Mercurial > hg > nginx-vendor-current
comparison src/http/modules/ngx_http_fastcgi_module.c @ 430:dac47e9ef0d5 NGINX_0_7_27
nginx 0.7.27
*) Feature: the "try_files" directive.
*) Feature: variables support in the "fastcgi_pass" directive.
*) Feature: now the $geo variable may get an address from a
variable.
Thanks to Andrei Nigmatulin.
*) Feature: now a location's modifier may be used without space before
name.
*) Feature: the $upstream_response_length variable.
*) Bugfix: now a "add_header" directive does not add an empty value.
*) Bugfix: if zero length static file was requested, then nginx just
closed connection; the bug had appeared in 0.7.25.
*) Bugfix: a MOVE method could not move file in non-existent directory.
*) Bugfix: a segmentation fault occurred in worker process, if no one
named location was defined in server, but some one was used in an
error_page directive.
Thanks to Sergey Bochenkov.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 15 Dec 2008 00:00:00 +0300 |
parents | b246022ef454 |
children | 49a0eb7ce20c |
comparison
equal
deleted
inserted
replaced
429:3b8e9d1bc9bb | 430:dac47e9ef0d5 |
---|---|
17 ngx_array_t *flushes; | 17 ngx_array_t *flushes; |
18 ngx_array_t *params_len; | 18 ngx_array_t *params_len; |
19 ngx_array_t *params; | 19 ngx_array_t *params; |
20 ngx_array_t *params_source; | 20 ngx_array_t *params_source; |
21 ngx_array_t *catch_stderr; | 21 ngx_array_t *catch_stderr; |
22 | |
23 ngx_array_t *fastcgi_lengths; | |
24 ngx_array_t *fastcgi_values; | |
22 } ngx_http_fastcgi_loc_conf_t; | 25 } ngx_http_fastcgi_loc_conf_t; |
23 | 26 |
24 | 27 |
25 typedef enum { | 28 typedef enum { |
26 ngx_http_fastcgi_st_version = 0, | 29 ngx_http_fastcgi_st_version = 0, |
101 ngx_http_fastcgi_begin_request_t br; | 104 ngx_http_fastcgi_begin_request_t br; |
102 ngx_http_fastcgi_header_small_t h1; | 105 ngx_http_fastcgi_header_small_t h1; |
103 } ngx_http_fastcgi_request_start_t; | 106 } ngx_http_fastcgi_request_start_t; |
104 | 107 |
105 | 108 |
109 static ngx_int_t ngx_http_fastcgi_eval(ngx_http_request_t *r, | |
110 ngx_http_fastcgi_loc_conf_t *flcf); | |
106 static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r); | 111 static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r); |
107 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); | 112 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r); |
108 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); | 113 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r); |
109 static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, | 114 static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, |
110 ngx_buf_t *buf); | 115 ngx_buf_t *buf); |
412 "ngx_http_fastcgi_module does not support " | 417 "ngx_http_fastcgi_module does not support " |
413 "subrequest in memory"); | 418 "subrequest in memory"); |
414 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 419 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
415 } | 420 } |
416 | 421 |
417 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); | 422 ngx_http_set_ctx(r, NULL, ngx_http_fastcgi_module); |
418 | 423 |
419 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); | 424 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); |
420 if (u == NULL) { | 425 if (u == NULL) { |
421 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 426 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
422 } | 427 } |
423 | 428 |
424 u->schema = flcf->upstream.schema; | 429 r->upstream = u; |
430 | |
431 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); | |
432 | |
433 if (flcf->fastcgi_lengths) { | |
434 if (ngx_http_fastcgi_eval(r, flcf) != NGX_OK) { | |
435 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
436 } | |
437 } | |
438 | |
439 u->schema.len = sizeof("fastcgi://") - 1; | |
440 u->schema.data = (u_char *) "fastcgi://"; | |
425 | 441 |
426 u->peer.log = r->connection->log; | 442 u->peer.log = r->connection->log; |
427 u->peer.log_error = NGX_ERROR_ERR; | 443 u->peer.log_error = NGX_ERROR_ERR; |
428 #if (NGX_THREADS) | 444 #if (NGX_THREADS) |
429 u->peer.lock = &r->connection->lock; | 445 u->peer.lock = &r->connection->lock; |
447 } | 463 } |
448 | 464 |
449 u->pipe->input_filter = ngx_http_fastcgi_input_filter; | 465 u->pipe->input_filter = ngx_http_fastcgi_input_filter; |
450 u->pipe->input_ctx = r; | 466 u->pipe->input_ctx = r; |
451 | 467 |
452 r->upstream = u; | |
453 | |
454 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); | 468 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); |
455 | 469 |
456 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 470 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
457 return rc; | 471 return rc; |
458 } | 472 } |
459 | 473 |
460 return NGX_DONE; | 474 return NGX_DONE; |
475 } | |
476 | |
477 | |
478 static ngx_int_t | |
479 ngx_http_fastcgi_eval(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf) | |
480 { | |
481 ngx_url_t u; | |
482 | |
483 ngx_memzero(&u, sizeof(ngx_url_t)); | |
484 | |
485 if (ngx_http_script_run(r, &u.url, flcf->fastcgi_lengths->elts, 0, | |
486 flcf->fastcgi_values->elts) | |
487 == NULL) | |
488 { | |
489 return NGX_ERROR; | |
490 } | |
491 | |
492 u.no_resolve = 1; | |
493 | |
494 if (ngx_parse_url(r->pool, &u) != NGX_OK) { | |
495 if (u.err) { | |
496 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
497 "%s in upstream \"%V\"", u.err, &u.url); | |
498 } | |
499 | |
500 return NGX_ERROR; | |
501 } | |
502 | |
503 if (u.no_port) { | |
504 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
505 "no port in upstream \"%V\"", &u.url); | |
506 return NGX_ERROR; | |
507 } | |
508 | |
509 r->upstream->resolved = ngx_pcalloc(r->pool, | |
510 sizeof(ngx_http_upstream_resolved_t)); | |
511 if (r->upstream->resolved == NULL) { | |
512 return NGX_ERROR; | |
513 } | |
514 | |
515 r->upstream->resolved->host = u.host; | |
516 r->upstream->resolved->port = u.port; | |
517 | |
518 return NGX_OK; | |
461 } | 519 } |
462 | 520 |
463 | 521 |
464 static ngx_int_t | 522 static ngx_int_t |
465 ngx_http_fastcgi_create_request(ngx_http_request_t *r) | 523 ngx_http_fastcgi_create_request(ngx_http_request_t *r) |
1629 * | 1687 * |
1630 * conf->upstream.bufs.num = 0; | 1688 * conf->upstream.bufs.num = 0; |
1631 * conf->upstream.next_upstream = 0; | 1689 * conf->upstream.next_upstream = 0; |
1632 * conf->upstream.temp_path = NULL; | 1690 * conf->upstream.temp_path = NULL; |
1633 * conf->upstream.hide_headers_hash = { NULL, 0 }; | 1691 * conf->upstream.hide_headers_hash = { NULL, 0 }; |
1634 * conf->upstream.schema = { 0, NULL }; | |
1635 * conf->upstream.uri = { 0, NULL }; | 1692 * conf->upstream.uri = { 0, NULL }; |
1636 * conf->upstream.location = NULL; | 1693 * conf->upstream.location = NULL; |
1637 * conf->upstream.store_lengths = NULL; | 1694 * conf->upstream.store_lengths = NULL; |
1638 * conf->upstream.store_values = NULL; | 1695 * conf->upstream.store_values = NULL; |
1639 * | 1696 * |
1859 return NGX_CONF_ERROR; | 1916 return NGX_CONF_ERROR; |
1860 } | 1917 } |
1861 | 1918 |
1862 if (conf->upstream.upstream == NULL) { | 1919 if (conf->upstream.upstream == NULL) { |
1863 conf->upstream.upstream = prev->upstream.upstream; | 1920 conf->upstream.upstream = prev->upstream.upstream; |
1864 conf->upstream.schema = prev->upstream.schema; | 1921 } |
1922 | |
1923 if (conf->fastcgi_lengths == NULL) { | |
1924 conf->fastcgi_lengths = prev->fastcgi_lengths; | |
1925 conf->fastcgi_values = prev->fastcgi_values; | |
1865 } | 1926 } |
1866 | 1927 |
1867 if (conf->params_source == NULL) { | 1928 if (conf->params_source == NULL) { |
1868 conf->flushes = prev->flushes; | 1929 conf->flushes = prev->flushes; |
1869 conf->params_len = prev->params_len; | 1930 conf->params_len = prev->params_len; |
2042 | 2103 |
2043 | 2104 |
2044 static char * | 2105 static char * |
2045 ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 2106 ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
2046 { | 2107 { |
2047 ngx_http_fastcgi_loc_conf_t *lcf = conf; | 2108 ngx_http_fastcgi_loc_conf_t *flcf = conf; |
2048 | 2109 |
2049 ngx_url_t u; | 2110 ngx_url_t u; |
2050 ngx_str_t *value; | 2111 ngx_str_t *value, *url; |
2051 ngx_http_core_loc_conf_t *clcf; | 2112 ngx_uint_t n; |
2052 | 2113 ngx_http_core_loc_conf_t *clcf; |
2053 if (lcf->upstream.schema.len) { | 2114 ngx_http_script_compile_t sc; |
2115 | |
2116 if (flcf->upstream.upstream || flcf->fastcgi_lengths) { | |
2054 return "is duplicate"; | 2117 return "is duplicate"; |
2055 } | 2118 } |
2056 | 2119 |
2120 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
2121 clcf->handler = ngx_http_fastcgi_handler; | |
2122 | |
2057 value = cf->args->elts; | 2123 value = cf->args->elts; |
2124 | |
2125 url = &value[1]; | |
2126 | |
2127 n = ngx_http_script_variables_count(url); | |
2128 | |
2129 if (n) { | |
2130 | |
2131 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
2132 | |
2133 sc.cf = cf; | |
2134 sc.source = url; | |
2135 sc.lengths = &flcf->fastcgi_lengths; | |
2136 sc.values = &flcf->fastcgi_values; | |
2137 sc.variables = n; | |
2138 sc.complete_lengths = 1; | |
2139 sc.complete_values = 1; | |
2140 | |
2141 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
2142 return NGX_CONF_ERROR; | |
2143 } | |
2144 | |
2145 return NGX_CONF_OK; | |
2146 } | |
2058 | 2147 |
2059 ngx_memzero(&u, sizeof(ngx_url_t)); | 2148 ngx_memzero(&u, sizeof(ngx_url_t)); |
2060 | 2149 |
2061 u.url = value[1]; | 2150 u.url = value[1]; |
2062 u.no_resolve = 1; | 2151 u.no_resolve = 1; |
2063 | 2152 |
2064 lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); | 2153 flcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); |
2065 if (lcf->upstream.upstream == NULL) { | 2154 if (flcf->upstream.upstream == NULL) { |
2066 return NGX_CONF_ERROR; | 2155 return NGX_CONF_ERROR; |
2067 } | 2156 } |
2068 | |
2069 lcf->upstream.schema.len = sizeof("fastcgi://") - 1; | |
2070 lcf->upstream.schema.data = (u_char *) "fastcgi://"; | |
2071 | |
2072 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
2073 | |
2074 clcf->handler = ngx_http_fastcgi_handler; | |
2075 | 2157 |
2076 if (clcf->name.data[clcf->name.len - 1] == '/') { | 2158 if (clcf->name.data[clcf->name.len - 1] == '/') { |
2077 clcf->auto_redirect = 1; | 2159 clcf->auto_redirect = 1; |
2078 } | 2160 } |
2079 | 2161 |