# HG changeset patch # User Igor Sysoev # Date 1280779200 -14400 # Node ID 09d5f308901fa05a6031c104b0ea8f8c19c1b2b1 # Parent 8b891ad58d6a62907596bfefde6ea3df0ca53437 nginx 0.8.48 *) Change: now the "server_name" directive default value is an empty name "". Thanks to Gena Makhomed. *) Change: now the "server_name_in_redirect" directive default value is "off". *) Feature: the $geoip_dma_code, $geoip_area_code, and $geoip_region_name variables. Thanks to Christine McGonagle. *) Bugfix: the "proxy_pass", "fastcgi_pass", "uwsgi_pass", and "scgi_pass" directives were not inherited inside "limit_except" blocks. *) Bugfix: the "proxy_cache_min_uses", "fastcgi_cache_min_uses" "uwsgi_cache_min_uses", and "scgi_cache_min_uses" directives did not work; the bug had appeared in 0.8.46. *) Bugfix: the "fastcgi_split_path_info" directive used incorrectly captures, if only parts of an URI were captured. Thanks to Yuriy Taraday and Frank Enderle. *) Bugfix: the "rewrite" directive did not escape a ";" character during copying from URI to query string. Thanks to Daisuke Murase. *) Bugfix: the ngx_http_image_filter_module closed a connection, if an image was larger than "image_filter_buffer" size. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,9 +1,42 @@ +Changes with nginx 0.8.48 03 Aug 2010 + + *) Change: now the "server_name" directive default value is an empty + name "". + Thanks to Gena Makhomed. + + *) Change: now the "server_name_in_redirect" directive default value is + "off". + + *) Feature: the $geoip_dma_code, $geoip_area_code, and + $geoip_region_name variables. + Thanks to Christine McGonagle. + + *) Bugfix: the "proxy_pass", "fastcgi_pass", "uwsgi_pass", and + "scgi_pass" directives were not inherited inside "limit_except" + blocks. + + *) Bugfix: the "proxy_cache_min_uses", "fastcgi_cache_min_uses" + "uwsgi_cache_min_uses", and "scgi_cache_min_uses" directives did not + work; the bug had appeared in 0.8.46. + + *) Bugfix: the "fastcgi_split_path_info" directive used incorrectly + captures, if only parts of an URI were captured. + Thanks to Yuriy Taraday and Frank Enderle. + + *) Bugfix: the "rewrite" directive did not escape a ";" character + during copying from URI to query string. + Thanks to Daisuke Murase. + + *) Bugfix: the ngx_http_image_filter_module closed a connection, if an + image was larger than "image_filter_buffer" size. + + Changes with nginx 0.8.47 28 Jul 2010 *) Bugfix: $request_time variable had invalid values for subrequests. - *) Bugfix: errors intercepted by error_page could be cached. + *) Bugfix: errors intercepted by error_page could not be cached. *) Bugfix: a cache manager process my got caught in an endless loop, if max_size parameter was used; the bug had appeared in 0.8.46. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,36 @@ +Изменения в nginx 0.8.48 03.08.2010 + + *) Изменение: теперь по умолчанию директива server_name имеет значение + пустое имя "". + Спасибо Геннадию Махомеду. + + *) Изменение: теперь по умолчанию директива server_name_in_redirect + имеет значение off. + + *) Добавление: переменные $geoip_dma_code, $geoip_area_code и + $geoip_region_name. + Спасибо Christine McGonagle. + + *) Исправление: директивы proxy_pass, fastcgi_pass, uwsgi_pass и + scgi_pass не наследовались в блоки limit_except. + + *) Исправление: директивы proxy_cache_min_uses, fastcgi_cache_min_uses + uwsgi_cache_min_uses и scgi_cache_min_uses не работали; ошибка + появилась в 0.8.46. + + *) Исправление: директива fastcgi_split_path_info неверно использовала + выделения, если в выделения попадала только часть URI. + Спасибо Юрию Тарадаю и Frank Enderle. + + *) Исправление: директива rewrite не экранировала символ ";" при + копировании из URI в аргументы. + Спасибо Daisuke Murase. + + *) Исправление: модуль ngx_http_image_filter_module закрывал + соединение, если изображение было больше размера image_filter_buffer. + + Изменения в nginx 0.8.47 28.07.2010 *) Исправление: переменная $request_time имела неверные значения для @@ -7,7 +39,7 @@ *) Исправление: ошибки, перехваченные error_page, не кэшировались. *) Исправление: если использовался параметр max_size, то cache manager - мог зациклиться. ошибка появилась в 0.8.46. + мог зациклиться; ошибка появилась в 0.8.46. Изменения в nginx 0.8.46 19.07.2010 @@ -1922,7 +1954,7 @@ *) Исправление: nginx неверно определял длину строки кэша на Pentium 4. - Спасибо Gena Makhomed. + Спасибо Геннадию Махомеду. *) Исправление: в проксированных подзапросах и подзапросах к FastCGI-серверу вместо метода GET использовался оригинальный метод diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 8047 -#define NGINX_VERSION "0.8.47" +#define nginx_version 8048 +#define NGINX_VERSION "0.8.48" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -1329,7 +1329,7 @@ ngx_escape_uri(u_char *dst, u_char *src, 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ - 0x80000869, /* 1000 0000 0000 0000 0000 1000 0110 1001 */ + 0x88000869, /* 1000 1000 0000 0000 0000 1000 0110 1001 */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1312,7 +1312,8 @@ ngx_ssl_connection_error(ngx_connection_ n = ERR_GET_REASON(ERR_peek_error()); /* handshake failures */ - if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ + if (n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */ + || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ || n == SSL_R_LENGTH_MISMATCH /* 159 */ || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -310,14 +310,14 @@ static ngx_command_t ngx_http_fastcgi_c #if (NGX_HTTP_CACHE) { ngx_string("fastcgi_cache"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_fastcgi_cache, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, { ngx_string("fastcgi_cache_key"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_fastcgi_cache_key, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -410,14 +410,14 @@ static ngx_command_t ngx_http_fastcgi_c NULL }, { ngx_string("fastcgi_pass_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_headers), NULL }, { ngx_string("fastcgi_hide_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers), @@ -2025,6 +2025,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf ngx_keyval_t *src; ngx_hash_key_t *hk; ngx_hash_init_t hash; + ngx_http_core_loc_conf_t *clcf; ngx_http_script_compile_t sc; ngx_http_script_copy_code_t *copy; @@ -2270,6 +2271,13 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf conf->fastcgi_values = prev->fastcgi_values; } + if (conf->upstream.upstream || conf->fastcgi_lengths) { + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + if (clcf->handler == NULL && clcf->lmt_excpt) { + clcf->handler = ngx_http_fastcgi_handler; + } + } + #if (NGX_PCRE) if (conf->split_regex == NULL) { conf->split_regex = prev->split_regex; @@ -2558,10 +2566,10 @@ ngx_http_fastcgi_split(ngx_http_request_ if (n >= 0) { /* match */ f->script_name.len = captures[3] - captures[2]; - f->script_name.data = r->uri.data; + f->script_name.data = r->uri.data + captures[2]; f->path_info.len = captures[5] - captures[4]; - f->path_info.data = r->uri.data + f->script_name.len; + f->path_info.data = r->uri.data + captures[4]; return f; } diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c --- a/src/http/modules/ngx_http_geoip_module.c +++ b/src/http/modules/ngx_http_geoip_module.c @@ -30,8 +30,12 @@ static ngx_int_t ngx_http_geoip_country_ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_geoip_region_name_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_geoip_city_int_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r); static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); @@ -128,6 +132,10 @@ static ngx_http_variable_t ngx_http_geo ngx_http_geoip_city_variable, offsetof(GeoIPRecord, region), 0, 0 }, + { ngx_string("geoip_region_name"), NULL, + ngx_http_geoip_region_name_variable, + 0, 0, 0 }, + { ngx_string("geoip_city"), NULL, ngx_http_geoip_city_variable, offsetof(GeoIPRecord, city), 0, 0 }, @@ -144,6 +152,14 @@ static ngx_http_variable_t ngx_http_geo ngx_http_geoip_city_float_variable, offsetof(GeoIPRecord, longitude), 0, 0 }, + { ngx_string("geoip_dma_code"), NULL, + ngx_http_geoip_city_int_variable, + offsetof(GeoIPRecord, dma_code), 0, 0 }, + + { ngx_string("geoip_area_code"), NULL, + ngx_http_geoip_city_int_variable, + offsetof(GeoIPRecord, area_code), 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -245,6 +261,48 @@ not_found: static ngx_int_t +ngx_http_geoip_region_name_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + size_t len; + const char *val; + GeoIPRecord *gr; + + gr = ngx_http_geoip_get_city_record(r); + if (gr == NULL) { + goto not_found; + } + + val = GeoIP_region_name_by_code(gr->country_code, gr->region); + + len = ngx_strlen(val); + v->data = ngx_pnalloc(r->pool, len); + + if (v->data == NULL) { + GeoIPRecord_delete(gr); + return NGX_ERROR; + } + + ngx_memcpy(v->data, val, len); + + v->len = len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + GeoIPRecord_delete(gr); + + return NGX_OK; + +not_found: + + v->not_found = 1; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -273,6 +331,35 @@ ngx_http_geoip_city_float_variable(ngx_h } +static ngx_int_t +ngx_http_geoip_city_int_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + int val; + GeoIPRecord *gr; + + gr = ngx_http_geoip_get_city_record(r); + if (gr == NULL) { + v->not_found = 1; + return NGX_OK; + } + + v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN); + if (v->data == NULL) { + GeoIPRecord_delete(gr); + return NGX_ERROR; + } + + val = *(int *) ((char *) gr + data); + + v->len = ngx_sprintf(v->data, "%d", val) - v->data; + + GeoIPRecord_delete(gr); + + return NGX_OK; +} + + static GeoIPRecord * ngx_http_geoip_get_city_record(ngx_http_request_t *r) { diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c --- a/src/http/modules/ngx_http_image_filter_module.c +++ b/src/http/modules/ngx_http_image_filter_module.c @@ -228,7 +228,7 @@ ngx_http_image_header_filter(ngx_http_re ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "image filter: too big response: %O", len); - return NGX_ERROR; + return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; } if (len == -1) { diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -319,14 +319,14 @@ static ngx_command_t ngx_http_proxy_com #if (NGX_HTTP_CACHE) { ngx_string("proxy_cache"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_proxy_cache, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, { ngx_string("proxy_cache_key"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_proxy_cache_key, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -412,14 +412,14 @@ static ngx_command_t ngx_http_proxy_com &ngx_http_proxy_next_upstream_masks }, { ngx_string("proxy_pass_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers), NULL }, { ngx_string("proxy_hide_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers), @@ -572,7 +572,7 @@ ngx_http_proxy_handler(ngx_http_request_ u = r->upstream; - if (plcf->proxy_lengths == 0) { + if (plcf->proxy_lengths == NULL) { ctx->vars = plcf->vars; u->schema = plcf->vars.schema; #if (NGX_HTTP_SSL) @@ -1720,6 +1720,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t size_t size; ngx_keyval_t *s; ngx_hash_init_t hash; + ngx_http_core_loc_conf_t *clcf; ngx_http_proxy_redirect_t *pr; ngx_http_script_compile_t sc; @@ -1985,12 +1986,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t } } - /* STUB */ - if (prev->proxy_lengths) { - conf->proxy_lengths = prev->proxy_lengths; - conf->proxy_values = prev->proxy_values; - } - #if (NGX_HTTP_SSL) if (conf->upstream.ssl == NULL) { conf->upstream.ssl = prev->upstream.ssl; @@ -2022,6 +2017,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t conf->vars = prev->vars; } + if (conf->proxy_lengths == NULL) { + conf->proxy_lengths = prev->proxy_lengths; + conf->proxy_values = prev->proxy_values; + } + + if (conf->upstream.upstream || conf->proxy_lengths) { + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + if (clcf->handler == NULL && clcf->lmt_excpt) { + clcf->handler = ngx_http_proxy_handler; + conf->location = prev->location; + } + } if (conf->body_source.data == NULL) { conf->body_source = prev->body_source; diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -176,14 +176,14 @@ static ngx_command_t ngx_http_scgi_comma #if (NGX_HTTP_CACHE) { ngx_string("scgi_cache"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_scgi_cache, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, { ngx_string("scgi_cache_key"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_scgi_cache_key, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -276,14 +276,14 @@ static ngx_command_t ngx_http_scgi_comma NULL }, { ngx_string("scgi_pass_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_scgi_loc_conf_t, upstream.pass_headers), NULL }, { ngx_string("scgi_hide_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_scgi_loc_conf_t, upstream.hide_headers), @@ -1053,6 +1053,7 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t ngx_keyval_t *src; ngx_hash_key_t *hk; ngx_hash_init_t hash; + ngx_http_core_loc_conf_t *clcf; ngx_http_script_compile_t sc; ngx_http_script_copy_code_t *copy; @@ -1285,6 +1286,13 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t conf->scgi_values = prev->scgi_values; } + if (conf->upstream.upstream || conf->scgi_lengths) { + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + if (clcf->handler == NULL && clcf->lmt_excpt) { + clcf->handler = ngx_http_scgi_handler; + } + } + if (conf->params_source == NULL) { conf->flushes = prev->flushes; conf->params_len = prev->params_len; diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -203,14 +203,14 @@ static ngx_command_t ngx_http_uwsgi_comm #if (NGX_HTTP_CACHE) { ngx_string("uwsgi_cache"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_uwsgi_cache, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, { ngx_string("uwsgi_cache_key"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_uwsgi_cache_key, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -310,14 +310,14 @@ static ngx_command_t ngx_http_uwsgi_comm NULL }, { ngx_string("uwsgi_pass_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_headers), NULL }, { ngx_string("uwsgi_hide_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_uwsgi_loc_conf_t, upstream.hide_headers), @@ -1106,6 +1106,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t ngx_keyval_t *src; ngx_hash_key_t *hk; ngx_hash_init_t hash; + ngx_http_core_loc_conf_t *clcf; ngx_http_script_compile_t sc; ngx_http_script_copy_code_t *copy; @@ -1340,6 +1341,13 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t conf->uwsgi_values = prev->uwsgi_values; } + if (conf->upstream.upstream || conf->uwsgi_lengths) { + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + if (clcf->handler == NULL && clcf->lmt_excpt) { + clcf->handler = ngx_http_uwsgi_handler; + } + } + ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0); ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0); diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -48,7 +48,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.8.47'; +our $VERSION = '0.8.48'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -26,6 +26,9 @@ static ngx_int_t ngx_http_add_address(ng static ngx_int_t ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr); +static char *ngx_http_merge_servers(ngx_conf_t *cf, + ngx_http_core_main_conf_t *cmcf, ngx_http_module_t *module, + ngx_uint_t ctx_index); static char *ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index); @@ -263,39 +266,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma } } - for (s = 0; s < cmcf->servers.nelts; s++) { - - /* merge the server{}s' srv_conf's */ - - if (module->merge_srv_conf) { - rv = module->merge_srv_conf(cf, ctx->srv_conf[mi], - cscfp[s]->ctx->srv_conf[mi]); - if (rv != NGX_CONF_OK) { - goto failed; - } - } - - if (module->merge_loc_conf) { - - /* merge the server{}'s loc_conf */ - - rv = module->merge_loc_conf(cf, ctx->loc_conf[mi], - cscfp[s]->ctx->loc_conf[mi]); - if (rv != NGX_CONF_OK) { - goto failed; - } - - /* merge the locations{}' loc_conf's */ - - clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index]; - - rv = ngx_http_merge_locations(cf, clcf->locations, - cscfp[s]->ctx->loc_conf, - module, mi); - if (rv != NGX_CONF_OK) { - goto failed; - } - } + rv = ngx_http_merge_servers(cf, cmcf, module, mi); + if (rv != NGX_CONF_OK) { + goto failed; } } @@ -586,11 +559,74 @@ ngx_http_init_phase_handlers(ngx_conf_t static char * +ngx_http_merge_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, + ngx_http_module_t *module, ngx_uint_t ctx_index) +{ + char *rv; + ngx_uint_t s; + ngx_http_conf_ctx_t *ctx, saved; + ngx_http_core_loc_conf_t *clcf; + ngx_http_core_srv_conf_t **cscfp; + + cscfp = cmcf->servers.elts; + ctx = (ngx_http_conf_ctx_t *) cf->ctx; + saved = *ctx; + rv = NGX_CONF_OK; + + for (s = 0; s < cmcf->servers.nelts; s++) { + + /* merge the server{}s' srv_conf's */ + + ctx->srv_conf = cscfp[s]->ctx->srv_conf; + + if (module->merge_srv_conf) { + rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index], + cscfp[s]->ctx->srv_conf[ctx_index]); + if (rv != NGX_CONF_OK) { + goto failed; + } + } + + if (module->merge_loc_conf) { + + /* merge the server{}'s loc_conf */ + + ctx->loc_conf = cscfp[s]->ctx->loc_conf; + + rv = module->merge_loc_conf(cf, saved.loc_conf[ctx_index], + cscfp[s]->ctx->loc_conf[ctx_index]); + if (rv != NGX_CONF_OK) { + goto failed; + } + + /* merge the locations{}' loc_conf's */ + + clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index]; + + rv = ngx_http_merge_locations(cf, clcf->locations, + cscfp[s]->ctx->loc_conf, + module, ctx_index); + if (rv != NGX_CONF_OK) { + goto failed; + } + } + } + +failed: + + *ctx = saved; + + return rv; +} + + +static char * ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index) { char *rv; ngx_queue_t *q; + ngx_http_conf_ctx_t *ctx, saved; ngx_http_core_loc_conf_t *clcf; ngx_http_location_queue_t *lq; @@ -598,6 +634,9 @@ ngx_http_merge_locations(ngx_conf_t *cf, return NGX_CONF_OK; } + ctx = (ngx_http_conf_ctx_t *) cf->ctx; + saved = *ctx; + for (q = ngx_queue_head(locations); q != ngx_queue_sentinel(locations); q = ngx_queue_next(q)) @@ -605,6 +644,7 @@ ngx_http_merge_locations(ngx_conf_t *cf, lq = (ngx_http_location_queue_t *) q; clcf = lq->exact ? lq->exact : lq->inclusive; + ctx->loc_conf = clcf->loc_conf; rv = module->merge_loc_conf(cf, loc_conf[ctx_index], clcf->loc_conf[ctx_index]); @@ -619,6 +659,8 @@ ngx_http_merge_locations(ngx_conf_t *cf, } } + *ctx = saved; + return NGX_CONF_OK; } diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -56,10 +56,6 @@ typedef struct { #define ngx_http_get_module_srv_conf(r, module) (r)->srv_conf[module.ctx_index] #define ngx_http_get_module_loc_conf(r, module) (r)->loc_conf[module.ctx_index] -/* - * ngx_http_conf_get_module_srv_conf() and ngx_http_conf_get_module_loc_conf() - * must not be used at the merge phase because cf->ctx points to http{}'s ctx - */ #define ngx_http_conf_get_module_main_conf(cf, module) \ ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index] diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -3011,7 +3011,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t } if (conf->server_name.data == NULL) { - conf->server_name = cf->cycle->hostname; + ngx_str_set(&conf->server_name, ""); sn = ngx_array_push(&conf->server_names); if (sn == NULL) { @@ -3022,8 +3022,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t sn->regex = NULL; #endif sn->server = conf; - sn->name.len = conf->server_name.len; - sn->name.data = conf->server_name.data; + ngx_str_set(&sn->name, ""); } return NGX_CONF_OK; @@ -3331,7 +3330,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->reset_timedout_connection, prev->reset_timedout_connection, 0); ngx_conf_merge_value(conf->server_name_in_redirect, - prev->server_name_in_redirect, 1); + prev->server_name_in_redirect, 0); ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1); ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1); ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0); @@ -3609,23 +3608,16 @@ ngx_http_core_server_name(ngx_conf_t *cf ch = value[1].data[0]; if (cscf->server_name.data == NULL) { - if (value[1].len) { - name = value[1]; - - if (ch == '.') { - name.len--; - name.data++; - } - - cscf->server_name.len = name.len; - cscf->server_name.data = ngx_pstrdup(cf->pool, &name); - if (cscf->server_name.data == NULL) { - return NGX_CONF_ERROR; - } - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the first server name must not be empty"); + name = value[1]; + + if (ch == '.') { + name.len--; + name.data++; + } + + cscf->server_name.len = name.len; + cscf->server_name.data = ngx_pstrdup(cf->pool, &name); + if (cscf->server_name.data == NULL) { return NGX_CONF_ERROR; } } @@ -3916,6 +3908,7 @@ ngx_http_core_limit_except(ngx_conf_t *c clcf->loc_conf = ctx->loc_conf; clcf->name = pclcf->name; clcf->noname = 1; + clcf->lmt_excpt = 1; if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) { return NGX_CONF_ERROR; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -286,6 +286,7 @@ struct ngx_http_core_loc_conf_s { #endif unsigned noname:1; /* "if () {}" block or limit_except */ + unsigned lmt_excpt:1; unsigned named:1; unsigned exact_match:1; diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -368,8 +368,6 @@ ngx_http_file_cache_read(ngx_http_reques ngx_http_file_cache_t *cache; ngx_http_file_cache_header_t *h; - c = r->cache; - n = ngx_http_file_cache_aio_read(r, c); if (n < 0) { @@ -519,6 +517,9 @@ ngx_http_file_cache_exists(ngx_http_file if (fcn) { ngx_queue_remove(&fcn->queue); + fcn->uses++; + fcn->count++; + if (fcn->error) { if (fcn->valid_sec < ngx_time()) { @@ -530,9 +531,6 @@ ngx_http_file_cache_exists(ngx_http_file goto done; } - fcn->uses++; - fcn->count++; - if (fcn->exists) { c->exists = fcn->exists; @@ -581,12 +579,13 @@ ngx_http_file_cache_exists(ngx_http_file ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); + fcn->uses = 1; + fcn->count = 1; + renew: rc = NGX_DECLINED; - fcn->uses = 1; - fcn->count = 1; fcn->valid_msec = 0; fcn->error = 0; fcn->exists = 0; @@ -932,7 +931,7 @@ ngx_http_file_cache_free(ngx_http_cache_ fcn->valid_msec = c->valid_msec; fcn->error = c->error; - } else if (!fcn->exists && fcn->count == 0) { + } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1) { ngx_queue_remove(&fcn->queue); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); @@ -1006,7 +1005,7 @@ ngx_http_file_cache_forced_expire(ngx_ht ngx_memcpy(name, path->name.data, path->name.len); wait = 10; - tries = 0; + tries = 20; ngx_shmtx_lock(&cache->shpool->mutex); @@ -1021,28 +1020,17 @@ ngx_http_file_cache_forced_expire(ngx_ht fcn->count, fcn->exists, fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]); - if (fcn->count) { + if (fcn->count == 0) { + ngx_http_file_cache_delete(cache, q, name); - if (tries++ < 20) { + } else { + if (--tries) { continue; } wait = 1; - - break; } - if (!fcn->exists) { - - ngx_queue_remove(q); - ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); - ngx_slab_free_locked(cache->shpool, fcn); - - break; - } - - ngx_http_file_cache_delete(cache, q, name); - break; } @@ -1105,41 +1093,29 @@ ngx_http_file_cache_expire(ngx_http_file fcn->count, fcn->exists, fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]); - if (fcn->count) { - - p = ngx_hex_dump(key, (u_char *) &fcn->node.key, - sizeof(ngx_rbtree_key_t)); - - len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); - (void) ngx_hex_dump(p, fcn->key, len); - - /* - * abnormally exited workers may leave locked cache entries, - * and although it may be safe to remove them completely, - * we prefer to remove them from inactive queue and rbtree - * only, and to allow other leaks - */ - - ngx_queue_remove(q); - ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); - - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, - "ignore long locked inactive cache entry %*s, count:%d", - 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); - + if (fcn->count == 0) { + ngx_http_file_cache_delete(cache, q, name); continue; } - if (!fcn->exists) { + p = ngx_hex_dump(key, (u_char *) &fcn->node.key, + sizeof(ngx_rbtree_key_t)); + len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); + (void) ngx_hex_dump(p, fcn->key, len); - ngx_queue_remove(q); - ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); - ngx_slab_free_locked(cache->shpool, fcn); + /* + * abnormally exited workers may leave locked cache entries, + * and although it may be safe to remove them completely, + * we prefer to remove them from inactive queue and rbtree + * only, and to allow other leaks + */ - continue; - } + ngx_queue_remove(q); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); - ngx_http_file_cache_delete(cache, q, name); + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "ignore long locked inactive cache entry %*s, count:%d", + 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); } ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1161,37 +1137,40 @@ ngx_http_file_cache_delete(ngx_http_file fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); - cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize; - - path = cache->path; - - p = name + path->name.len + 1 + path->len; + if (fcn->exists) { + cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize; - p = ngx_hex_dump(p, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); + path = cache->path; + p = name + path->name.len + 1 + path->len; + p = ngx_hex_dump(p, (u_char *) &fcn->node.key, + sizeof(ngx_rbtree_key_t)); + len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); + p = ngx_hex_dump(p, fcn->key, len); + *p = '\0'; - len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); - p = ngx_hex_dump(p, fcn->key, len); - *p = '\0'; + fcn->count++; + ngx_shmtx_unlock(&cache->shpool->mutex); - ngx_queue_remove(q); - ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); - ngx_slab_free_locked(cache->shpool, fcn); + len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; + ngx_create_hashed_filename(path, name, len); - ngx_shmtx_unlock(&cache->shpool->mutex); - - len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "http file cache expire: \"%s\"", name); - ngx_create_hashed_filename(path, name, len); + if (ngx_delete_file(name) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", name); + } - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "http file cache expire: \"%s\"", name); - - if (ngx_delete_file(name) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, - ngx_delete_file_n " \"%s\" failed", name); + ngx_shmtx_lock(&cache->shpool->mutex); + fcn->count--; } - ngx_shmtx_lock(&cache->shpool->mutex); + if (fcn->count == 0) { + ngx_queue_remove(q); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); + ngx_slab_free_locked(cache->shpool, fcn); + } }