Mercurial > hg > nginx-vendor-current
diff src/http/ngx_http_core_module.c @ 664:f5b859b2f097 NGINX_1_1_16
nginx 1.1.16
*) Change: the simultaneous subrequest limit has been raised to 200.
*) Feature: the "from" parameter of the "disable_symlinks" directive.
*) Feature: the "return" and "error_page" directives can be used to
return 307 redirections.
*) Bugfix: a segmentation fault might occur in a worker process if the
"resolver" directive was used and there was no "error_log" directive
specified at global level.
Thanks to Roman Arutyunyan.
*) Bugfix: a segmentation fault might occur in a worker process if the
"proxy_http_version 1.1" or "fastcgi_keep_conn on" directives were
used.
*) Bugfix: memory leaks.
Thanks to Lanshun Zhou.
*) Bugfix: in the "disable_symlinks" directive.
*) Bugfix: on ZFS filesystem disk cache size might be calculated
incorrectly; the bug had appeared in 1.0.1.
*) Bugfix: nginx could not be built by the icc 12.1 compiler.
*) Bugfix: nginx could not be built by gcc on Solaris; the bug had
appeared in 1.1.15.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 29 Feb 2012 00:00:00 +0400 |
parents | e5fa0a4a7d27 |
children | bf8b55a5ac89 |
line wrap: on
line diff
--- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -76,6 +76,10 @@ static ngx_uint_t ngx_http_gzip_quantity static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); #endif +#if (NGX_HAVE_OPENAT) +static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +#endif static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data); @@ -187,18 +191,6 @@ static ngx_str_t ngx_http_gzip_private #endif -#if (NGX_HAVE_OPENAT) - -static ngx_conf_enum_t ngx_http_core_disable_symlinks[] = { - { ngx_string("off"), NGX_DISABLE_SYMLINKS_OFF }, - { ngx_string("if_not_owner"), NGX_DISABLE_SYMLINKS_NOTOWNER }, - { ngx_string("on"), NGX_DISABLE_SYMLINKS_ON }, - { ngx_null_string, 0 } -}; - -#endif - - static ngx_command_t ngx_http_core_commands[] = { { ngx_string("variables_hash_max_size"), @@ -779,11 +771,11 @@ static ngx_command_t ngx_http_core_comm #if (NGX_HAVE_OPENAT) { ngx_string("disable_symlinks"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, + ngx_http_disable_symlinks, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, disable_symlinks), - &ngx_http_core_disable_symlinks }, + 0, + NULL }, #endif @@ -1320,9 +1312,11 @@ ngx_http_core_try_files_phase(ngx_http_r of.test_only = 1; of.errors = clcf->open_file_cache_errors; of.events = clcf->open_file_cache_events; -#if (NGX_HAVE_OPENAT) - of.disable_symlinks = clcf->disable_symlinks; -#endif + + if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; + } if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) @@ -1824,8 +1818,11 @@ ngx_http_send_response(ngx_http_request_ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (status >= NGX_HTTP_MOVED_PERMANENTLY && status <= NGX_HTTP_SEE_OTHER) { - + if (status == NGX_HTTP_MOVED_PERMANENTLY + || status == NGX_HTTP_MOVED_TEMPORARILY + || status == NGX_HTTP_SEE_OTHER + || status == NGX_HTTP_TEMPORARY_REDIRECT) + { ngx_http_clear_location(r); r->headers_out.location = ngx_list_push(&r->headers_out.headers); @@ -2642,6 +2639,56 @@ ngx_http_cleanup_add(ngx_http_request_t } +ngx_int_t +ngx_http_set_disable_symlinks(ngx_http_request_t *r, + ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of) +{ +#if (NGX_HAVE_OPENAT) + u_char *p; + ngx_str_t from; + + of->disable_symlinks = clcf->disable_symlinks; + + if (clcf->disable_symlinks_from == NULL) { + return NGX_OK; + } + + if (ngx_http_complex_value(r, clcf->disable_symlinks_from, &from) + != NGX_OK) + { + return NGX_ERROR; + } + + if (from.len == 0 + || from.len > path->len + || ngx_memcmp(path->data, from.data, from.len) != 0) + { + return NGX_OK; + } + + if (from.len == path->len) { + of->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF; + return NGX_OK; + } + + p = path->data + from.len; + + if (*p == '/') { + of->disable_symlinks_from = from.len; + return NGX_OK; + } + + p--; + + if (*p == '/') { + of->disable_symlinks_from = from.len - 1; + } +#endif + + return NGX_OK; +} + + static char * ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { @@ -3372,6 +3419,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t #if (NGX_HAVE_OPENAT) clcf->disable_symlinks = NGX_CONF_UNSET_UINT; + clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR; #endif return clcf; @@ -3656,6 +3704,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t #if (NGX_HAVE_OPENAT) ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks, NGX_DISABLE_SYMLINKS_OFF); + ngx_conf_merge_ptr_value(conf->disable_symlinks_from, + prev->disable_symlinks_from, NULL); #endif return NGX_CONF_OK; @@ -4791,6 +4841,100 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ng #endif +#if (NGX_HAVE_OPENAT) + +static char * +ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_core_loc_conf_t *clcf = conf; + + ngx_str_t *value; + ngx_uint_t i; + ngx_http_compile_complex_value_t ccv; + + if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) { + return "is duplicate"; + } + + value = cf->args->elts; + + for (i = 1; i < cf->args->nelts; i++) { + + if (ngx_strcmp(value[i].data, "off") == 0) { + clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF; + continue; + } + + if (ngx_strcmp(value[i].data, "if_not_owner") == 0) { + clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER; + continue; + } + + if (ngx_strcmp(value[i].data, "on") == 0) { + clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON; + continue; + } + + if (ngx_strncmp(value[i].data, "from=", 5) == 0) { + value[i].len -= 5; + value[i].data += 5; + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[i]; + ccv.complex_value = ngx_palloc(cf->pool, + sizeof(ngx_http_complex_value_t)); + if (ccv.complex_value == NULL) { + return NGX_CONF_ERROR; + } + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + clcf->disable_symlinks_from = ccv.complex_value; + + continue; + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"%V\" must have \"off\", \"on\" " + "or \"if_not_owner\" parameter", + &cmd->name); + return NGX_CONF_ERROR; + } + + if (cf->args->nelts == 2) { + clcf->disable_symlinks_from = NULL; + return NGX_CONF_OK; + } + + if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate parameters \"%V %V\"", + &value[1], &value[2]); + return NGX_CONF_ERROR; + } + + if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"from=\" cannot be used with \"off\" parameter"); + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + +#endif + + static char * ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data) {