# HG changeset patch # User Igor Sysoev # Date 1274644800 -14400 # Node ID ff463db0be31226ba236423b24e3d6d58cc78d7e # Parent 5b59e716792b09ac4435e9b02b4e7b505d7b1a92 nginx 0.8.38 *) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives. *) Feature: now the "rewrite" directive does a redirect automatically if the $scheme variable is used. Thanks to Piotr Sikora. *) Bugfix: now "limit_req" delay directive conforms to the described algorithm. Thanks to Maxim Dounin. *) Bugfix: the $uid_got variable might not be used in the SSI and perl modules. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,20 @@ +Changes with nginx 0.8.38 24 May 2010 + + *) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives. + + *) Feature: now the "rewrite" directive does a redirect automatically + if the $scheme variable is used. + Thanks to Piotr Sikora. + + *) Bugfix: now "limit_req" delay directive conforms to the described + algorithm. + Thanks to Maxim Dounin. + + *) Bugfix: the $uid_got variable might not be used in the SSI and perl + modules. + + Changes with nginx 0.8.37 17 May 2010 *) Feature: the ngx_http_split_clients_module. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,20 @@ +Изменения в nginx 0.8.38 24.05.2010 + + *) Добавление: директивы proxy_no_cache и fastcgi_no_cache. + + *) Добавление: теперь при использовании переменной $scheme в директиве + rewrite автоматически делается редирект. + Спасибо Piotr Sikora. + + *) Исправление: теперь задержки в директиве limit_req соответствует + описанному алгоритму. + Спасибо Максиму Дунину. + + *) Исправление: переменную $uid_got нельзя было использовать в SSI и + перловом модулях. + + Изменения в nginx 0.8.37 17.05.2010 *) Добавление: модуль ngx_http_split_clients_module. @@ -406,7 +422,7 @@ *) Добавление: директивы limit_req_log_level и limit_conn_log_level. - *) Исправление: Теперь директива limit_req соответствует алгоритму + *) Исправление: теперь директива limit_req соответствует алгоритму leaky bucket. Спасибо Максиму Дунину. 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 8037 -#define NGINX_VERSION "0.8.37" +#define nginx_version 8038 +#define NGINX_VERSION "0.8.38" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -160,10 +160,6 @@ ngx_http_autoindex_handler(ngx_http_requ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -146,10 +146,6 @@ ngx_http_dav_handler(ngx_http_request_t ngx_int_t rc; ngx_http_dav_loc_conf_t *dlcf; - if (r->zero_in_uri) { - return NGX_DECLINED; - } - dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); if (!(r->method & dlcf->methods)) { 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 @@ -162,11 +162,6 @@ static char *ngx_http_fastcgi_cache_key( static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data); -static char *ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); -static char *ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); - static ngx_conf_post_t ngx_http_fastcgi_lowat_post = { ngx_http_fastcgi_lowat_check }; @@ -341,6 +336,13 @@ static ngx_command_t ngx_http_fastcgi_c 0, &ngx_http_fastcgi_module }, + { ngx_string("fastcgi_no_cache"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_no_cache_set_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.no_cache), + NULL }, + { ngx_string("fastcgi_cache_valid"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_file_cache_valid_set_slot, @@ -399,20 +401,6 @@ static ngx_command_t ngx_http_fastcgi_c offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream), &ngx_http_fastcgi_next_upstream_masks }, - { ngx_string("fastcgi_upstream_max_fails"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_fastcgi_upstream_max_fails_unsupported, - 0, - 0, - NULL }, - - { ngx_string("fastcgi_upstream_fail_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_fastcgi_upstream_fail_timeout_unsupported, - 0, - 0, - NULL }, - { ngx_string("fastcgi_param"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, ngx_conf_set_keyval_slot, @@ -1942,6 +1930,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_con #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; #endif @@ -2163,6 +2152,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; + ngx_conf_merge_ptr_value(conf->upstream.no_cache, + prev->upstream.no_cache, NULL); + ngx_conf_merge_ptr_value(conf->upstream.cache_valid, prev->upstream.cache_valid, NULL); @@ -2749,29 +2741,3 @@ ngx_http_fastcgi_lowat_check(ngx_conf_t return NGX_CONF_OK; } - - -static char * -ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"fastcgi_upstream_max_fails\" is not supported, " - "use the \"max_fails\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"fastcgi_upstream_fail_timeout\" is not supported, " - "use the \"fail_timeout\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -80,10 +80,6 @@ ngx_http_flv_handler(ngx_http_request_t return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c --- a/src/http/modules/ngx_http_gzip_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -89,10 +89,6 @@ ngx_http_gzip_static_handler(ngx_http_re return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module); if (!gzcf->enable) { diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -116,10 +116,6 @@ ngx_http_index_handler(ngx_http_request_ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -229,7 +229,8 @@ ngx_http_limit_req_handler(ngx_http_requ r->read_event_handler = ngx_http_test_reading; r->write_event_handler = ngx_http_limit_req_delay; - ngx_add_timer(r->connection->write, (ngx_msec_t) excess); + ngx_add_timer(r->connection->write, + (ngx_msec_t) excess * 1000 / ctx->rate); return NGX_AGAIN; } diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -38,11 +38,6 @@ static char *ngx_http_memcached_merge_lo static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); -static char *ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); - static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = { { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, @@ -105,20 +100,6 @@ static ngx_command_t ngx_http_memcached offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream), &ngx_http_memcached_next_upstream_masks }, - { ngx_string("memcached_upstream_max_fails"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_memcached_upstream_max_fails_unsupported, - 0, - 0, - NULL }, - - { ngx_string("memcached_upstream_fail_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_memcached_upstream_fail_timeout_unsupported, - 0, - 0, - NULL }, - ngx_null_command }; @@ -640,29 +621,3 @@ ngx_http_memcached_pass(ngx_conf_t *cf, return NGX_CONF_OK; } - - -static char * -ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"memcached_upstream_max_fails\" is not supported, " - "use the \"max_fails\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"memcached_upstream_fail_timeout\" is not supported, " - "use the \"fail_timeout\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} 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 @@ -142,11 +142,6 @@ static char *ngx_http_proxy_cache_key(ng static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); -static char *ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); -static char *ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); - #if (NGX_HTTP_SSL) static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf); @@ -364,6 +359,13 @@ static ngx_command_t ngx_http_proxy_com 0, &ngx_http_proxy_module }, + { ngx_string("proxy_no_cache"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_no_cache_set_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache), + NULL }, + { ngx_string("proxy_cache_valid"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_file_cache_valid_set_slot, @@ -422,20 +424,6 @@ static ngx_command_t ngx_http_proxy_com offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream), &ngx_http_proxy_next_upstream_masks }, - { ngx_string("proxy_upstream_max_fails"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_proxy_upstream_max_fails_unsupported, - 0, - 0, - NULL }, - - { ngx_string("proxy_upstream_fail_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_proxy_upstream_fail_timeout_unsupported, - 0, - 0, - NULL }, - { ngx_string("proxy_pass_header"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_str_array_slot, @@ -1936,6 +1924,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; #endif @@ -2160,6 +2149,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t |NGX_HTTP_UPSTREAM_FT_OFF; } + ngx_conf_merge_ptr_value(conf->upstream.no_cache, + prev->upstream.no_cache, NULL); + ngx_conf_merge_ptr_value(conf->upstream.cache_valid, prev->upstream.cache_valid, NULL); @@ -2959,32 +2951,6 @@ ngx_http_proxy_lowat_check(ngx_conf_t *c } -static char * -ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_upstream_max_fails\" is not supported, " - "use the \"max_fails\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_upstream_fail_timeout\" is not supported, " - "use the \"fail_timeout\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} - - #if (NGX_HTTP_SSL) static ngx_int_t diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c --- a/src/http/modules/ngx_http_random_index_module.c +++ b/src/http/modules/ngx_http_random_index_module.c @@ -86,10 +86,6 @@ ngx_http_random_index_handler(ngx_http_r return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -341,13 +341,10 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_com last = 0; - if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { - regex->status = NGX_HTTP_MOVED_TEMPORARILY; - regex->redirect = 1; - last = 1; - } - - if (ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0) { + if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0 + || ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0 + || ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0) + { regex->status = NGX_HTTP_MOVED_TEMPORARILY; regex->redirect = 1; last = 1; diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -66,10 +66,6 @@ ngx_http_static_handler(ngx_http_request return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - log = r->connection->log; /* diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -543,7 +543,7 @@ ngx_http_userid_add_variables(ngx_conf_t { ngx_http_variable_t *var; - var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH); + var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0); if (var == NULL) { return NGX_ERROR; } 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 @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.8.37'; +our $VERSION = '0.8.38'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -168,10 +168,6 @@ ngx_http_perl_xs_init(pTHX) static ngx_int_t ngx_http_perl_handler(ngx_http_request_t *r) { - if (r->zero_in_uri) { - return NGX_HTTP_NOT_FOUND; - } - r->main->count++; ngx_http_perl_handle_request(r); diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -134,6 +134,11 @@ char *ngx_http_file_cache_set_slot(ngx_c char *ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +ngx_int_t ngx_http_cache(ngx_http_request_t *r, ngx_array_t *no_cache); +char *ngx_http_no_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + + extern ngx_str_t ngx_http_cache_status[]; 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 @@ -1341,7 +1341,7 @@ ngx_http_core_content_phase(ngx_http_req /* no content handler was found */ - if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) { + if (r->uri.data[r->uri.len - 1] == '/') { if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, @@ -2104,7 +2104,6 @@ ngx_http_subrequest(ngx_http_request_t * ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http subrequest \"%V?%V\"", uri, &sr->args); - sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0; sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0; sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0; 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 @@ -1692,3 +1692,69 @@ ngx_http_file_cache_valid_set_slot(ngx_c return NGX_CONF_OK; } + + +ngx_int_t +ngx_http_cache(ngx_http_request_t *r, ngx_array_t *no_cache) +{ + ngx_str_t val; + ngx_uint_t i; + ngx_http_complex_value_t *cv; + + cv = no_cache->elts; + + for (i = 0; i < no_cache->nelts; i++) { + if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) { + return NGX_ERROR; + } + + if (val.len && val.data[0] != '0') { + return NGX_DECLINED; + } + } + + return NGX_OK; +} + + +char * +ngx_http_no_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *p = conf; + + ngx_str_t *value; + ngx_uint_t i; + ngx_array_t **a; + ngx_http_complex_value_t *cv; + ngx_http_compile_complex_value_t ccv; + + a = (ngx_array_t **) (p + cmd->offset); + + if (*a == NGX_CONF_UNSET_PTR) { + *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t)); + if (*a == NULL) { + return NGX_CONF_ERROR; + } + } + + value = cf->args->elts; + + for (i = 1; i < cf->args->nelts; i++) { + cv = ngx_array_push(*a); + if (cv == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[i]; + ccv.complex_value = cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + + return NGX_CONF_OK; +} diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -438,8 +438,7 @@ ngx_http_parse_request_line(ngx_http_req r->plus_in_uri = 1; break; case '\0': - r->zero_in_uri = 1; - break; + return NGX_HTTP_PARSE_INVALID_REQUEST; default: state = sw_check_uri; break; @@ -496,8 +495,7 @@ ngx_http_parse_request_line(ngx_http_req r->plus_in_uri = 1; break; case '\0': - r->zero_in_uri = 1; - break; + return NGX_HTTP_PARSE_INVALID_REQUEST; } break; @@ -526,8 +524,7 @@ ngx_http_parse_request_line(ngx_http_req r->complex_uri = 1; break; case '\0': - r->zero_in_uri = 1; - break; + return NGX_HTTP_PARSE_INVALID_REQUEST; } break; @@ -1202,7 +1199,7 @@ ngx_http_parse_complex_uri(ngx_http_requ ch = *p++; } else if (ch == '\0') { - r->zero_in_uri = 1; + return NGX_HTTP_PARSE_INVALID_REQUEST; } state = quoted_state; @@ -1304,8 +1301,7 @@ ngx_http_parse_unsafe_uri(ngx_http_reque } if (ch == '\0') { - *flags |= NGX_HTTP_ZERO_IN_URI; - continue; + goto unsafe; } if (ngx_path_separator(ch) && len > 2) { @@ -1449,34 +1445,19 @@ ngx_http_arg(ngx_http_request_t *r, u_ch void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args) { - u_char ch, *p, *last; - - p = uri->data; - - last = p + uri->len; + u_char *p, *last; - args->len = 0; + last = uri->data + uri->len; - while (p < last) { - - ch = *p++; + p = ngx_strlchr(uri->data, last, '?'); - if (ch == '?') { - args->len = last - p; - args->data = p; - - uri->len = p - 1 - uri->data; + if (p) { + uri->len = p - uri->data; + p++; + args->len = last - p; + args->data = p; - if (ngx_strlchr(p, last, '\0') != NULL) { - r->zero_in_uri = 1; - } - - return; - } - - if (ch == '\0') { - r->zero_in_uri = 1; - continue; - } + } else { + args->len = 0; } } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -56,7 +56,7 @@ #define NGX_HTTP_PARSE_INVALID_HEADER 13 -#define NGX_HTTP_ZERO_IN_URI 1 +/* unused 1 */ #define NGX_HTTP_SUBREQUEST_IN_MEMORY 2 #define NGX_HTTP_SUBREQUEST_WAITED 4 #define NGX_HTTP_LOG_UNSAFE 8 @@ -435,9 +435,6 @@ struct ngx_http_request_s { /* URI with "+" */ unsigned plus_in_uri:1; - /* URI with "\0" or "%00" */ - unsigned zero_in_uri:1; - unsigned invalid_header:1; unsigned valid_location:1; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -517,8 +517,6 @@ ngx_http_send_error_page(ngx_http_reques r->err_status = overwrite; - r->zero_in_uri = 0; - if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) { return NGX_ERROR; } diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -621,6 +621,13 @@ ngx_http_upstream_cache(ngx_http_request if (c == NULL) { + if (u->conf->no_cache) { + rc = ngx_http_cache(r, u->conf->no_cache); + if (rc != NGX_OK) { + return rc; + } + } + if (!(r->method & u->conf->cache_methods)) { return NGX_DECLINED; } @@ -1808,10 +1815,6 @@ ngx_http_upstream_process_headers(ngx_ht return NGX_DONE; } - if (flags & NGX_HTTP_ZERO_IN_URI) { - r->zero_in_uri = 1; - } - if (r->method != NGX_HTTP_HEAD) { r->method = NGX_HTTP_GET; } diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -162,6 +162,7 @@ typedef struct { ngx_uint_t cache_methods; ngx_array_t *cache_valid; + ngx_array_t *no_cache; /* ngx_http_complex_value_t */ #endif ngx_array_t *store_lengths;