# HG changeset patch # User Igor Sysoev # Date 1243195200 -14400 # Node ID 499474178a112350895b502f16a2d1abe1b5b532 # Parent d13d7ebf13704e94c4c7b8cabe1dd8f916b89a60 nginx 0.7.59 *) Feature: the "proxy_cache_methods" and "fastcgi_cache_methods" directives. *) Bugfix: socket leak; the bug had appeared in 0.7.25. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault occurred in worker process, if a request had no body and the $request_body variable was used; the bug had appeared in 0.7.58. *) Bugfix: the SSL modules might not built on Solaris and Linux; the bug had appeared in 0.7.58. *) Bugfix: ngx_http_xslt_filter_module responses were not handled by SSI, charset, and gzip filters. *) Bugfix: a "charset" directive did not set a charset to ngx_http_gzip_static_module responses. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,26 @@ +Changes with nginx 0.7.59 25 May 2009 + + *) Feature: the "proxy_cache_methods" and "fastcgi_cache_methods" + directives. + + *) Bugfix: socket leak; the bug had appeared in 0.7.25. + Thanks to Maxim Dounin. + + *) Bugfix: a segmentation fault occurred in worker process, + if a request had no body and the $request_body variable was used; + the bug had appeared in 0.7.58. + + *) Bugfix: the SSL modules might not built on Solaris and Linux; + the bug had appeared in 0.7.58. + + *) Bugfix: ngx_http_xslt_filter_module responses were not handled by + SSI, charset, and gzip filters. + + *) Bugfix: a "charset" directive did not set a charset to + ngx_http_gzip_static_module responses. + + Changes with nginx 0.7.58 18 May 2009 *) Feature: a "listen" directive of the mail proxy module supports IPv6. @@ -19,7 +41,7 @@ Changes with nginx 0.7.58 Changes with nginx 0.7.57 12 May 2009 - *) Bugfix: a segmentation fault occurred in worker process, if the + *) Bugfix: a floating-point fault occurred in worker process, if the ngx_http_image_filter_module errors were redirected to named location; the bug had appeared in 0.7.56. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,25 @@ +Изменения в nginx 0.7.59 25.05.2009 + + *) Добавление: директивы proxy_cache_methods и fastcgi_cache_methods. + + *) Исправление: утечки сокетов; ошибка появилась в 0.7.25. + Спасибо Максиму Дунину. + + *) Исправление: при использовании переменной $request_body в рабочем + процессе происходил segmentation fault, если в запросе не было тела; + ошибка появилась в 0.7.58. + + *) Исправление: SSL-модули могли не собираться на Solaris и Linux; + ошибка появилась в 0.7.56. + + *) Исправление: ответы модуля ngx_http_xslt_filter_module не + обрабатывались SSI-, charset- и gzip-фильтрами. + + *) Исправление: директива charset не ставила кодировку для ответов + модуля ngx_http_gzip_static_module. + + Изменения в nginx 0.7.58 18.05.2009 *) Добавление: директива listen почтового прокси-сервера поддерживает @@ -1381,7 +1402,7 @@ *) Добавление: директивы open_file_cache, open_file_cache_retest и open_file_cache_errors. - *) Исправление: утечка сокетов; ошибка появилась в 0.6.7. + *) Исправление: утечки сокетов; ошибка появилась в 0.6.7. *) Исправление: В строку заголовка ответа "Content-Type", указанную в методе $r->send_http_header(), не добавлялась кодировка, указанная в diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -25,19 +25,14 @@ if [ $OPENSSL != NONE ]; then have=NGX_OPENSSL . auto/have have=NGX_SSL . auto/have - CORE_INCS="$CORE_INCS $OPENSSL/include" - LINK_DEPS="$LINK_DEPS $OPENSSL/libssl.a $OPENSSL/libcrypto.a" - CORE_LIBS="$CORE_LIBS $OPENSSL/libssl.a $OPENSSL/libcrypto.a" - ;; - esac - - case "$NGX_SYSTEM" in - SunOS|Linux) + CORE_INCS="$CORE_INCS $OPENSSL/openssl/include" + CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h" + CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libssl.a" + CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libcrypto.a" CORE_LIBS="$CORE_LIBS $NGX_LIBDL" ;; esac - else case "$NGX_PLATFORM" in @@ -69,14 +64,8 @@ else if [ $ngx_found = yes ]; then have=NGX_SSL . auto/have - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL" OPENSSL=YES - - case "$NGX_SYSTEM" in - SunOS) - CORE_LIBS="$CORE_LIBS $NGX_LIBDL" - ;; - esac fi ;; diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make --- a/auto/lib/openssl/make +++ b/auto/lib/openssl/make @@ -2,15 +2,9 @@ # Copyright (C) Igor Sysoev -if test -n "$OPENSSL_OPT"; then - NGX_OPENSSL_CONFIG="./Configure $OPENSSL_OPT" -else - NGX_OPENSSL_CONFIG="./config" -fi - case $USE_THREADS in - NO) NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG no-threads" ;; - *) NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG threads" ;; + NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;; + *) OPENSSL_OPT="$OPENSSL_OPT threads" ;; esac case "$CC" in @@ -51,13 +45,26 @@ END ;; *) + case $OPENSSL in + + /*) + ngx_prefix="$OPENSSL/openssl" + ;; + + *) + ngx_prefix="$PWD/$OPENSSL/openssl" + ;; + + esac + cat << END >> $NGX_MAKEFILE -$OPENSSL/libssl.a: $NGX_MAKEFILE +$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE cd $OPENSSL \\ && \$(MAKE) clean \\ - && $NGX_OPENSSL_CONFIG no-shared \\ - && \$(MAKE) + && ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\ + && \$(MAKE) \\ + && \$(MAKE) install END diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -135,7 +135,7 @@ opt= for option do - opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`" + opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`" case "$option" in -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;; diff --git a/auto/os/features b/auto/os/features --- a/auto/os/features +++ b/auto/os/features @@ -230,3 +230,25 @@ ngx_feature_libs= ngx_feature_test="struct statvfs fs; statvfs(NULL, &fs);" . auto/feature + + +ngx_feature="dlopen()" +ngx_feature_name= +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="dlopen(NULL, 0)" +. auto/feature + + +if [ $ngx_found != yes ]; then + + ngx_feature="dlopen() in libdl" + ngx_feature_libs="-ldl" + . auto/feature + + if [ $ngx_found = yes ]; then + NGX_LIBDL="-ldl" + fi +fi diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -185,28 +185,6 @@ if [ $ngx_found != yes ]; then fi -ngx_feature="dlopen()" -ngx_feature_name= -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="dlopen(NULL, 0)" -. auto/feature - - -if [ $ngx_found != yes ]; then - - ngx_feature="dlopen() in libdl" - ngx_feature_libs="-ldl" - . auto/feature - - if [ $ngx_found = yes ]; then - NGX_LIBDL="-ldl" - fi -fi - - ngx_feature="mmap(MAP_ANON|MAP_SHARED)" ngx_feature_name="NGX_HAVE_MAP_ANON" ngx_feature_run=yes 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 7058 -#define NGINX_VERSION "0.7.58" +#define nginx_version 7059 +#define NGINX_VERSION "0.7.59" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c --- a/src/http/modules/ngx_http_charset_filter_module.c +++ b/src/http/modules/ngx_http_charset_filter_module.c @@ -224,7 +224,8 @@ ngx_http_charset_header_filter(ngx_http_ if (r == r->main) { - if (r->headers_out.content_encoding + if (!r->ignore_content_encoding + && r->headers_out.content_encoding && r->headers_out.content_encoding->value.len) { return ngx_http_next_header_filter(r); 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 @@ -353,6 +353,13 @@ static ngx_command_t ngx_http_fastcgi_c offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_use_stale), &ngx_http_fastcgi_next_upstream_masks }, + { ngx_string("fastcgi_cache_methods"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_conf_set_bitmask_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_methods), + &ngx_http_upstream_cache_method_mask }, + #endif { ngx_string("fastcgi_temp_path"), @@ -1835,7 +1842,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_con * conf->upstream.bufs.num = 0; * conf->upstream.ignore_headers = 0; * conf->upstream.next_upstream = 0; - * conf->upstream.use_stale_cache = 0; + * conf->upstream.cache_use_stale = 0; + * conf->upstream.cache_methods = 0; * conf->upstream.temp_path = NULL; * conf->upstream.hide_headers_hash = { NULL, 0 }; * conf->upstream.uri = { 0, NULL }; @@ -2083,6 +2091,12 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf |NGX_HTTP_UPSTREAM_FT_OFF; } + if (conf->upstream.cache_methods == 0) { + conf->upstream.cache_methods = prev->upstream.cache_methods; + } + + conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; + ngx_conf_merge_ptr_value(conf->upstream.cache_valid, prev->upstream.cache_valid, NULL); 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 @@ -205,6 +205,7 @@ ngx_http_gzip_static_handler(ngx_http_re h->value.data = (u_char *) "gzip"; r->headers_out.content_encoding = h; + r->ignore_content_encoding = 1; /* we need to allocate all before the header would be sent */ 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 @@ -282,6 +282,7 @@ ngx_http_image_body_filter(ngx_http_requ ct = &ngx_http_image_types[ctx->type - 1]; r->headers_out.content_type_len = ct->len; r->headers_out.content_type = *ct; + r->headers_out.content_type_lowcase = NULL; if (conf->filter == NGX_HTTP_IMAGE_TEST) { ctx->phase = NGX_HTTP_IMAGE_PASS; @@ -502,6 +503,7 @@ ngx_http_image_json(ngx_http_request_t * r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_type.len = sizeof("text/plain") - 1; r->headers_out.content_type.data = (u_char *) "text/plain"; + r->headers_out.content_type_lowcase = NULL; if (ctx == NULL) { b->pos = (u_char *) "{}" CRLF; 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 @@ -377,6 +377,13 @@ static ngx_command_t ngx_http_proxy_com offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_use_stale), &ngx_http_proxy_next_upstream_masks }, + { ngx_string("proxy_cache_methods"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_conf_set_bitmask_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_methods), + &ngx_http_upstream_cache_method_mask }, + #endif { ngx_string("proxy_temp_path"), @@ -1885,7 +1892,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ * conf->upstream.bufs.num = 0; * conf->upstream.ignore_headers = 0; * conf->upstream.next_upstream = 0; - * conf->upstream.use_stale_cache = 0; + * conf->upstream.cache_use_stale = 0; + * conf->upstream.cache_methods = 0; * conf->upstream.temp_path = NULL; * conf->upstream.hide_headers_hash = { NULL, 0 }; * conf->upstream.uri = { 0, NULL }; @@ -2139,6 +2147,12 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t (NGX_CONF_BITMASK_SET |NGX_HTTP_UPSTREAM_FT_OFF)); + if (conf->upstream.cache_methods == 0) { + conf->upstream.cache_methods = prev->upstream.cache_methods; + } + + conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; + if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) { conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET |NGX_HTTP_UPSTREAM_FT_OFF; diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -456,6 +456,8 @@ ngx_http_range_multipart_header(ngx_http return NGX_ERROR; } + r->headers_out.content_type_lowcase = NULL; + /* "Content-Type: multipart/byteranges; boundary=0123456789" */ r->headers_out.content_type.len = @@ -464,6 +466,7 @@ ngx_http_range_multipart_header(ngx_http boundary) - r->headers_out.content_type.data; + r->headers_out.content_type_len = r->headers_out.content_type.len; /* the size of the last boundary CRLF "--0123456789--" CRLF */ diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -837,6 +837,8 @@ ngx_http_xslt_apply_stylesheet(ngx_http_ r->headers_out.content_type.data = (u_char *) "text/html"; } + r->headers_out.content_type_lowcase = NULL; + return b; } 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.7.58'; +our $VERSION = '0.7.59'; require XSLoader; XSLoader::load('nginx', $VERSION); 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 @@ -1530,38 +1530,38 @@ ngx_http_core_find_static_location(ngx_h void * ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash) { - u_char c, *p; - ngx_uint_t i, hash; + u_char c, *lowcase; + size_t len; + ngx_uint_t i, hash; if (r->headers_out.content_type.len == 0) { return NULL; } + len = r->headers_out.content_type_len; + if (r->headers_out.content_type_lowcase == NULL) { - p = ngx_pnalloc(r->pool, r->headers_out.content_type_len); - - if (p == NULL) { + lowcase = ngx_pnalloc(r->pool, len); + if (lowcase == NULL) { return NULL; } - r->headers_out.content_type_lowcase = p; + r->headers_out.content_type_lowcase = lowcase; hash = 0; - for (i = 0; i < r->headers_out.content_type_len; i++) { + for (i = 0; i < len; i++) { c = ngx_tolower(r->headers_out.content_type.data[i]); hash = ngx_hash(hash, c); - *p++ = c; + lowcase[i] = c; } r->headers_out.content_type_hash = hash; } - return ngx_hash_find(types_hash, - r->headers_out.content_type_hash, - r->headers_out.content_type_lowcase, - r->headers_out.content_type_len); + return ngx_hash_find(types_hash, r->headers_out.content_type_hash, + r->headers_out.content_type_lowcase, len); } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2098,6 +2098,11 @@ ngx_http_writer(ngx_http_request_t *r) "http writer output filter: %d, \"%V?%V\"", rc, &r->uri, &r->args); + if (rc == NGX_ERROR) { + ngx_http_finalize_request(r, rc); + return; + } + if (r->buffered || r->postponed || (r == r->main && c->buffered)) { if (!wev->ready && !wev->delayed) { 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 @@ -478,6 +478,7 @@ struct ngx_http_request_s { unsigned discard_body:1; unsigned internal:1; unsigned error_page:1; + unsigned ignore_content_encoding:1; unsigned filter_finalize:1; unsigned post_action:1; unsigned request_complete: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 @@ -610,6 +610,7 @@ ngx_http_send_special_response(ngx_http_ r->headers_out.content_type_len = sizeof("text/html") - 1; r->headers_out.content_type.len = sizeof("text/html") - 1; r->headers_out.content_type.data = (u_char *) "text/html"; + r->headers_out.content_type_lowcase = NULL; } else { r->headers_out.content_length_n = -1; @@ -712,6 +713,7 @@ ngx_http_send_refresh(ngx_http_request_t r->headers_out.content_type_len = sizeof("text/html") - 1; r->headers_out.content_type.len = sizeof("text/html") - 1; r->headers_out.content_type.data = (u_char *) "text/html"; + r->headers_out.content_type_lowcase = NULL; r->headers_out.location->hash = 0; r->headers_out.location = NULL; 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 @@ -329,6 +329,15 @@ static ngx_http_upstream_next_t ngx_htt { 0, 0 } }; + +ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = { + { ngx_string("GET"), NGX_HTTP_GET}, + { ngx_string("HEAD"), NGX_HTTP_HEAD }, + { ngx_string("POST"), NGX_HTTP_POST }, + { ngx_null_string, 0 } +}; + + void ngx_http_upstream_init(ngx_http_request_t *r) { @@ -532,7 +541,7 @@ ngx_http_upstream_cache(ngx_http_request ngx_int_t rc; ngx_http_cache_t *c; - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { + if (!(r->method & u->conf->cache_methods)) { return NGX_DECLINED; } @@ -562,8 +571,8 @@ ngx_http_upstream_cache(ngx_http_request u->cacheable = 1; - c->min_uses = r->upstream->conf->cache_min_uses; - c->body_start = r->upstream->conf->buffer_size; + c->min_uses = u->conf->cache_min_uses; + c->body_start = u->conf->buffer_size; c->file_cache = u->conf->cache->data; rc = ngx_http_file_cache_open(r); @@ -3165,6 +3174,7 @@ ngx_http_upstream_copy_content_type(ngx_ r->headers_out.content_type_len = h->value.len; r->headers_out.content_type = h->value; + r->headers_out.content_type_lowcase = NULL; for (p = h->value.data; *p; p++) { 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 @@ -156,6 +156,7 @@ typedef struct { ngx_uint_t cache_min_uses; ngx_uint_t cache_use_stale; + ngx_uint_t cache_methods; ngx_array_t *cache_valid; #endif @@ -327,7 +328,9 @@ ngx_int_t ngx_http_upstream_hide_headers uscf->srv_conf[module.ctx_index] -extern ngx_module_t ngx_http_upstream_module; +extern ngx_module_t ngx_http_upstream_module; +extern ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[]; + #endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */ diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -1492,7 +1492,10 @@ ngx_http_variable_request_body(ngx_http_ ngx_buf_t *buf, *next; ngx_chain_t *cl; - if (r->request_body == NULL || r->request_body->temp_file) { + if (r->request_body == NULL + || r->request_body->bufs == NULL + || r->request_body->temp_file) + { v->not_found = 1; return NGX_OK;