changeset 634:23ef0645ea57 NGINX_1_1_1

nginx 1.1.1 *) Change: now cache loader processes either as many files as specified by "loader_files" parameter or works no more than time specified by "loader_threshold" parameter during each iteration. *) Change: now SIGWINCH signal works only in deamon mode. *) Feature: now shared zones and caches use POSIX semaphores on Solaris. Thanks to Den Ivanov. *) Feature: accept filters are now supported on NetBSD. *) Bugfix: nginx could not be build on Linux 3.0. *) Bugfix: nginx did not use gzipping in some cases; the bug had appeared in 1.1.0. *) Bugfix: request body might be incorrectly processed if client used pipelining. *) Bugfix: in the "request_body_in_single_buf" directive. *) Bugfix: in "proxy_set_body" and "proxy_pass_request_body" directives if SSL connection to backend was used. *) Bugfix: nginx hogged CPU if all servers in an upstream were marked as "down". *) Bugfix: a segmentation fault might occur during reconfiguration if ssl_session_cache was defined but not used in a previous configuration. *) Bugfix: a segmentation fault might occur in a worker process if many backup servers were used in an upstream. *) Bugfix: a segmentation fault might occur in a worker process if "fastcgi/scgi/uwsgi_param" directives were used with values starting with "HTTP_"; the bug had appeared in 0.8.40.
author Igor Sysoev <http://sysoev.ru>
date Mon, 22 Aug 2011 00:00:00 +0400
parents 561a37709f6d
children 5d94f8b3e01d
files CHANGES CHANGES.ru auto/cc/sunc auto/install auto/os/linux auto/unix html/http/ngx_http_core_module.html man/nginx.8 src/core/nginx.h src/core/ngx_connection.c src/core/ngx_cycle.c src/core/ngx_log.c src/event/ngx_event_openssl.c src/event/ngx_event_openssl.h src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_log_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_referer_module.c src/http/modules/ngx_http_scgi_module.c src/http/modules/ngx_http_ssl_module.c src/http/modules/ngx_http_uwsgi_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_core_module.c src/http/ngx_http_file_cache.c src/http/ngx_http_request_body.c src/http/ngx_http_upstream_round_robin.c src/mail/ngx_mail_ssl_module.c src/os/unix/ngx_freebsd_config.h src/os/unix/ngx_linux_config.h src/os/unix/ngx_process.c
diffstat 30 files changed, 304 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,46 @@
 
+Changes with nginx 1.1.1                                         22 Aug 2011
+
+    *) Change: now cache loader processes either as many files as specified 
+       by "loader_files" parameter or works no more than time specified by 
+       "loader_threshold" parameter during each iteration.
+
+    *) Change: now SIGWINCH signal works only in deamon mode.
+
+    *) Feature: now shared zones and caches use POSIX semaphores on 
+       Solaris.
+       Thanks to Den Ivanov.
+
+    *) Feature: accept filters are now supported on NetBSD.
+
+    *) Bugfix: nginx could not be build on Linux 3.0.
+
+    *) Bugfix: nginx did not use gzipping in some cases; the bug had 
+       appeared in 1.1.0.
+
+    *) Bugfix: request body might be incorrectly processed if client used 
+       pipelining.
+
+    *) Bugfix: in the "request_body_in_single_buf" directive.
+
+    *) Bugfix: in "proxy_set_body" and "proxy_pass_request_body" directives 
+       if SSL connection to backend was used.
+
+    *) Bugfix: nginx hogged CPU if all servers in an upstream were marked 
+       as "down".
+
+    *) Bugfix: a segmentation fault might occur during reconfiguration if 
+       ssl_session_cache was defined but not used in a previous 
+       configuration.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if many 
+       backup servers were used in an upstream.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if 
+       "fastcgi/scgi/uwsgi_param" directives were used with values starting 
+       with "HTTP_"; the bug had appeared in 0.8.40.
+
+
 Changes with nginx 1.1.0                                         01 Aug 2011
 
     *) Feature: cache loader run time decrease.
@@ -1867,7 +1909,7 @@ Changes with nginx 0.7.15               
 Changes with nginx 0.7.14                                        01 Sep 2008
 
     *) Change: now the ssl_certificate and ssl_certificate_key directives 
-       have not default values.
+       have no default values.
 
     *) Feature: the "listen" directive supports the "ssl" parameter.
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,46 @@
 
+Изменения в nginx 1.1.1                                           22.08.2011
+
+    *) Изменение: теперь загрузчик кэша за каждую итерацию обрабатывает 
+       число файлов, указанное в параметре load_files, или же работает не 
+       больше времени, указанное в параметре loader_threshold.
+
+    *) Изменение: SIGWINCH сигнал теперь работает только в режиме демона.
+
+    *) Добавление: теперь разделяемые зоны и кэши используют семафоры POSIX 
+       на Solaris.
+       Спасибо Денису Иванову.
+
+    *) Добавление: поддержка accept фильтров на NetBSD.
+
+    *) Исправление: nginx не собирался на Linux 3.0.
+
+    *) Исправление: в некоторых случаях nginx не использовал сжатие; ошибка 
+       появилась в 1.1.0.
+
+    *) Исправление: обработка тела запроса могло быть неверной, если клиент 
+       использовал pipelining.
+
+    *) Исправление: в директиве request_body_in_single_buf.
+
+    *) Исправление: в директивах proxy_set_body и proxy_pass_request_body 
+       при использовании SSL соединения с бэкендом.
+
+    *) Исправление: nginx нагружал процессор, если все сервера в upstream'е 
+       были отмечены флагом down.
+
+    *) Исправление: при переконфигурации мог произойти segmentation fault, 
+       если ssl_session_cache был определён, но не использовался в 
+       предыдущей конфигурации.
+
+    *) Исправление: при использовании большого количества backup-серверов в 
+       рабочем процессе мог произойти segmentation fault.
+
+    *) Исправление: при использовании директив fastcgi/scgi/uwsgi_param со 
+       значением, начинающимся со строки "HTTP_", в рабочем процессе мог 
+       произойти segmentation fault; ошибка появилась в 0.8.40.
+
+
 Изменения в nginx 1.1.0                                           01.08.2011
 
     *) Добавление: уменьшение времени работы загрузчика кэша.
--- a/auto/cc/sunc
+++ b/auto/cc/sunc
@@ -6,6 +6,8 @@
 # Sun C 5.8 2005/10/13                    Sun Studio 11
 # Sun C 5.9 SunOS_i386 2007/05/03         Sun Studio 12
 # Sun C 5.9 SunOS_sparc 2007/05/03
+# Sun C 5.10 SunOS_i386 2009/06/03        Sun Studio 12.1
+# Sun C 5.11 SunOS_i386 2010/08/13        Sun Studio 12.2
 
 NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
                           | sed -e 's/^.* Sun C \(.*\)/\1/'`
@@ -57,9 +59,19 @@ esac
 
 # optimizations
 
+# 20736 == 0x5100, Sun Studio 12.1
+
+if [ "$ngx_sunc_ver" -ge 20736 ]; then
+    ngx_fast="-fast"
+
+else
+    # older versions had problems with bit-fields
+    ngx_fast="-fast -xalias_level=any"
+fi
+
 IPO=-xipo
-CFLAGS="$CFLAGS -fast $IPO"
-CORE_LINK="$CORE_LINK -fast $IPO"
+CFLAGS="$CFLAGS $ngx_fast $IPO"
+CORE_LINK="$CORE_LINK $ngx_fast $IPO"
 
 
 case $CPU in
@@ -126,15 +138,15 @@ CFLAGS="$CFLAGS $CPU_OPT"
 
 
 if [ ".$PCRE_OPT" = "." ]; then
-    PCRE_OPT="-fast $IPO $CPU_OPT"
+    PCRE_OPT="$ngx_fast $IPO $CPU_OPT"
 fi
 
 if [ ".$MD5_OPT" = "." ]; then
-    MD5_OPT="-fast $IPO $CPU_OPT"
+    MD5_OPT="$ngx_fast $IPO $CPU_OPT"
 fi
 
 if [ ".$ZLIB_OPT" = "." ]; then
-    ZLIB_OPT="-fast $IPO $CPU_OPT"
+    ZLIB_OPT="$ngx_fast $IPO $CPU_OPT"
 fi
 
 
--- a/auto/install
+++ b/auto/install
@@ -74,7 +74,9 @@ esac
 
 cat << END                                                    >> $NGX_MAKEFILE
 
-manpage:
+manpage:	$NGX_OBJS/nginx.8
+
+$NGX_OBJS/nginx.8:	man/nginx.8 $NGX_AUTO_CONFIG_H
 	sed -e "s|%%PREFIX%%|$NGX_PREFIX|" \\
 		-e "s|%%PID_PATH%%|$NGX_PID_PATH|" \\
 		-e "s|%%CONF_PATH%%|$NGX_CONF_PATH|" \\
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -18,7 +18,9 @@ CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURC
 # Linux kernel version
 
 version=$((`uname -r \
-       | sed 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1*256*256+\2*256+\3/'`))
+    | sed -n -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/ \
+                                                 \1*256*256+\2*256+\3/p' \
+             -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1*256*256+\2*256/p'`))
 
 version=${version:-0}
 
--- a/auto/unix
+++ b/auto/unix
@@ -295,6 +295,7 @@ if [ $ngx_found != yes ]; then
     fi
 fi
 
+
 ngx_feature="SO_SETFIB"
 ngx_feature_name="NGX_HAVE_SETFIB"
 ngx_feature_run=no
@@ -305,6 +306,28 @@ ngx_feature_test="setsockopt(0, SOL_SOCK
 . auto/feature
 
 
+ngx_feature="SO_ACCEPTFILTER"
+ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)"
+. auto/feature
+
+
+ngx_feature="TCP_DEFER_ACCEPT"
+ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <netinet/in.h>
+                  #include <netinet/tcp.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_DEFER_ACCEPT, NULL, 0)"
+. auto/feature
+
+
 ngx_feature="accept4()"
 ngx_feature_name="NGX_HAVE_ACCEPT4"
 ngx_feature_run=no
@@ -620,6 +643,19 @@ if [ $ngx_found = no ]; then
 fi
 
 
+if [ $ngx_found = no ]; then
+
+    # Solaris has POSIX semaphores in librt
+    ngx_feature="POSIX semaphores in librt"
+    ngx_feature_libs=-lrt
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS -lrt"
+    fi
+fi
+
+
 ngx_feature="struct msghdr.msg_control"
 ngx_feature_name="NGX_HAVE_MSGHDR_MSG_CONTROL"
 ngx_feature_run=no
new file mode 100644
--- /dev/null
+++ b/html/http/ngx_http_core_module.html
@@ -0,0 +1,10 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>ngx_http_core_module</title></head><body><center><h4>Directives</h4></center><a name="client_body_buffer_size"></a><center><h4>client_body_buffer_size</h4></center>syntax: client_body_buffer_size <i>size</i><br>default: client_body_buffer_size 8k/16k<br>context: http, server, location<br><p>
+Directive sets client request body buffer size.
+If the request body is larger than the buffer,
+then the whole body or some its part is written to temporary file.
+By default buffer size is equal to 2 memory page sizes.
+This is 8K on x86, other 32-bit platforms, and x86-64.
+It is usually 16K on other 64-bit platforms.
+</p><a name="sendfile"></a><center><h4>sendfile</h4></center>syntax: sendfile <i>[on|off]</i><br>default: sendfile off<br>context: http, server, location<br><p>
+Directive enables or disables sendfile() usage.
+</p></body></html>
--- a/man/nginx.8
+++ b/man/nginx.8
@@ -24,7 +24,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"
-.Dd November 14, 2010
+.Dd August 10, 2011
 .Dt NGINX 8
 .Os
 .Sh NAME
@@ -177,25 +177,25 @@ Test configuration file
 .Pa ~/mynginx.conf
 with global directives for PID and quantity of worker processes.
 .Sh SEE ALSO
-.Xr nginx.conf 5
+.\"Xr nginx.conf 5
+.\"Pp
+Documentation at
+.Pa http://nginx.org/
+and
+.Pa http://sysoev.ru/nginx/ .
+.Pp
+For questions and technical support, please refer to
+.Pa http://nginx.org/en/support.html .
 .Sh HISTORY
 Development of
 .Nm
 started in 2002, with the first public release on October 4, 2004.
 .Sh AUTHORS
+.An -nosplit
 .An Igor Sysoev Aq igor@sysoev.ru
 .Pp
-Documentation available on
-.Pa http://nginx.org/
-and
-.Pa http://sysoev.ru/nginx/ .
-.Pp
 This manual page was written by
 .An Sergey A. Osokin Aq osa@FreeBSD.org.ru
 as a result of compilation of many
 .Nm
 documents all over the world.
-.Sh BUGS
-Report to mailing list
-.Aq Li nginx@nginx.org
-if you found one.
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1001000
-#define NGINX_VERSION      "1.1.0"
+#define nginx_version      1001001
+#define NGINX_VERSION      "1.1.1"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -580,7 +580,7 @@ ngx_configure_listening_sockets(ngx_cycl
             {
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
-                              " for %V failed, ignored",
+                              "for %V failed, ignored",
                               ls[i].accept_filter, &ls[i].addr_text);
                 continue;
             }
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -418,11 +418,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
             goto failed;
         }
 
-        if (shm_zone[i].init == NULL) {
-            /* unused shared zone */
-            continue;
-        }
-
         shm_zone[i].shm.log = cycle->log;
 
         opart = &old_cycle->shared_memory.part;
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -369,12 +369,13 @@ ngx_log_create(ngx_cycle_t *cycle, ngx_s
 char *
 ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
 {
-    ngx_uint_t   i, n, d;
+    ngx_uint_t   i, n, d, found;
     ngx_str_t   *value;
 
     value = cf->args->elts;
 
     for (i = 2; i < cf->args->nelts; i++) {
+        found = 0;
 
         for (n = 1; n <= NGX_LOG_DEBUG; n++) {
             if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
@@ -387,7 +388,8 @@ ngx_log_set_levels(ngx_conf_t *cf, ngx_l
                 }
 
                 log->log_level = n;
-                continue;
+                found = 1;
+                break;
             }
         }
 
@@ -401,11 +403,13 @@ ngx_log_set_levels(ngx_conf_t *cf, ngx_l
                 }
 
                 log->log_level |= d;
+                found = 1;
+                break;
             }
         }
 
 
-        if (log->log_level == 0) {
+        if (!found) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "invalid log level \"%V\"", &value[i]);
             return NGX_CONF_ERROR;
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -26,8 +26,7 @@ static void ngx_ssl_connection_error(ngx
     ngx_err_t err, char *text);
 static void ngx_ssl_clear_error(ngx_log_t *log);
 
-static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
-    void *data);
+ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
 static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
     ngx_ssl_session_t *sess);
 static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
@@ -1505,8 +1504,6 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ng
     SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
 
     if (shm_zone) {
-        shm_zone->init = ngx_ssl_session_cache_init;
-
         SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
         SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
         SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);
@@ -1524,7 +1521,7 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ng
 }
 
 
-static ngx_int_t
+ngx_int_t
 ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
 {
     size_t                    len;
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -104,6 +104,7 @@ ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf
 ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
     ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout);
+ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
 ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
     ngx_uint_t flags);
 
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -737,7 +737,15 @@ ngx_http_fastcgi_create_request(ngx_http
         lowcase_key = NULL;
 
         if (flcf->header_params) {
-            ignored = ngx_palloc(r->pool, flcf->header_params * sizeof(void *));
+            n = 0;
+            part = &r->headers_in.headers.part;
+
+            while (part) {
+                n += part->nelts;
+                part = part->next;
+            }
+
+            ignored = ngx_palloc(r->pool, n * sizeof(void *));
             if (ignored == NULL) {
                 return NGX_ERROR;
             }
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -1055,25 +1055,6 @@ ngx_http_log_compile_format(ngx_conf_t *
 
     for ( /* void */ ; s < args->nelts; s++) {
 
-        for (i = 0; i < value[s].len; i++) {
-            if (value[s].data[i] != '%') {
-                continue;
-            }
-
-            ch = value[s].data[i + 1];
-
-            if ((ch >= 'A' && ch <= 'Z')
-                 || (ch >= 'a' && ch <= 'z')
-                 || ch == '{')
-            {
-                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                     "the parameters in the \"%%name\" form are not supported, "
-                     "use the \"$variable\" instead");
-
-                return NGX_CONF_ERROR;
-            }
-        }
-
         i = 0;
 
         while (i < value[s].len) {
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1132,12 +1132,11 @@ ngx_http_proxy_create_request(ngx_http_r
             body = body->next;
         }
 
-        b->flush = 1;
-
     } else {
         u->request_bufs = cl;
     }
 
+    b->flush = 1;
     cl->next = NULL;
 
     return NGX_OK;
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -309,7 +309,7 @@ ngx_http_referer_merge_conf(ngx_conf_t *
     hash.key = ngx_hash_key_lc;
     hash.max_size = conf->referer_hash_max_size;
     hash.bucket_size = conf->referer_hash_bucket_size;
-    hash.name = "referers_hash";
+    hash.name = "referer_hash";
     hash.pool = cf->pool;
 
     if (conf->keys->keys.nelts) {
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -561,7 +561,15 @@ ngx_http_scgi_create_request(ngx_http_re
         lowcase_key = NULL;
 
         if (scf->header_params) {
-            ignored = ngx_palloc(r->pool, scf->header_params * sizeof(void *));
+            n = 0;
+            part = &r->headers_in.headers.part;
+
+            while (part) {
+                n += part->nelts;
+                part = part->next;
+            }
+
+            ignored = ngx_palloc(r->pool, n * sizeof(void *));
             if (ignored == NULL) {
                 return NGX_ERROR;
             }
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -626,6 +626,8 @@ ngx_http_ssl_session_cache(ngx_conf_t *c
         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
     }
 
+    sscf->shm_zone->init = ngx_ssl_session_cache_init;
+
     return NGX_CONF_OK;
 
 invalid:
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -589,7 +589,15 @@ ngx_http_uwsgi_create_request(ngx_http_r
         lowcase_key = NULL;
 
         if (uwcf->header_params) {
-            ignored = ngx_palloc(r->pool, uwcf->header_params * sizeof(void *));
+            n = 0;
+            part = &r->headers_in.headers.part;
+
+            while (part) {
+                n += part->nelts;
+                part = part->next;
+            }
+
+            ignored = ngx_palloc(r->pool, n * sizeof(void *));
             if (ignored == NULL) {
                 return NGX_ERROR;
             }
--- 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 = '1.1.0';
+our $VERSION = '1.1.1';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -71,6 +71,7 @@ static char *ngx_http_core_resolver(ngx_
     void *conf);
 #if (NGX_HTTP_GZIP)
 static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
+static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 #endif
@@ -2189,7 +2190,7 @@ ok:
 
 /*
  * gzip is enabled for the following quantities:
- *     "gzip; q=0.001" ... "gzip; q=0.999", "gzip; q=1"
+ *     "gzip; q=0.001" ... "gzip; q=1.000"
  * gzip is disabled for the following quantities:
  *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
  */
@@ -2197,8 +2198,7 @@ ok:
 static ngx_int_t
 ngx_http_gzip_accept_encoding(ngx_str_t *ae)
 {
-    u_char      c, *p, *start, *last;
-    ngx_uint_t  n, q;
+    u_char  *p, *start, *last;
 
     start = ae->data;
     last = start + ae->len;
@@ -2255,56 +2255,65 @@ equal:
         return NGX_DECLINED;
     }
 
-    c = *p++;
-
-    if (c == '1') {
-        if (p == last || *p == ',' || *p == ' ') {
-            return NGX_OK;
-        }
+    if (ngx_http_gzip_quantity(p, last) == 0) {
         return NGX_DECLINED;
     }
 
-    if (c != '0') {
-        return NGX_DECLINED;
+    return NGX_OK;
+}
+
+
+ngx_uint_t
+ngx_http_gzip_quantity(u_char *p, u_char *last)
+{
+    u_char      c;
+    ngx_uint_t  n, q;
+
+    c = *p++;
+
+    if (c != '0' && c != '1') {
+        return 0;
     }
 
+    q = (c - '0') * 100;
+
     if (p == last) {
-        return NGX_DECLINED;
+        return q;
     }
 
-    if (*p++ != '.') {
-        return NGX_DECLINED;
+    c = *p++;
+
+    if (c == ',' || c == ' ') {
+        return q;
+    }
+
+    if (c != '.') {
+        return 0;
     }
 
     n = 0;
-    q = 0;
 
     while (p < last) {
         c = *p++;
 
-        if (c == ',') {
+        if (c == ',' || c == ' ') {
             break;
         }
 
-        if (c >= '1' && c <= '9') {
-            n++;
-            q++;
-            continue;
-        }
-
-        if (c == '0') {
+        if (c >= '0' && c <= '9') {
+            q += c - '0';
             n++;
             continue;
         }
 
-        return NGX_DECLINED;
+        return 0;
     }
 
-    if (n < 4 && q != 0) {
-        return NGX_OK;
+    if (q > 100 || n > 3) {
+        return 0;
     }
 
-    return NGX_DECLINED;
+    return q;
 }
 
 #endif
@@ -3482,7 +3491,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
                               prev->keepalive_header, 0);
     ngx_conf_merge_uint_value(conf->keepalive_requests,
                               prev->keepalive_requests, 100);
-    ngx_conf_merge_msec_value(conf->lingering_close,
+    ngx_conf_merge_uint_value(conf->lingering_close,
                               prev->lingering_close, NGX_HTTP_LINGERING_ON);
     ngx_conf_merge_msec_value(conf->lingering_time,
                               prev->lingering_time, 30000);
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -30,8 +30,7 @@ static time_t ngx_http_file_cache_forced
 static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
 static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache,
     ngx_queue_t *q, u_char *name);
-static ngx_int_t
-    ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache);
+static void ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache);
 static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx,
     ngx_str_t *path);
 static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx,
@@ -1261,48 +1260,6 @@ ngx_http_file_cache_loader(void *data)
 
 
 static ngx_int_t
-ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
-{
-    ngx_msec_t  elapsed;
-
-    if (++cache->files >= cache->loader_files) {
-
-        ngx_time_update();
-
-        elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
-                       "http file cache loader time elapsed: %M", elapsed);
-
-        if (elapsed >= cache->loader_threshold) {
-
-            if (cache->loader_files > 1) {
-                cache->loader_files /= 2;
-                ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
-                              "cache %V loader_files decreased to %ui",
-                              &cache->path->name, cache->loader_files);
-
-            } else {
-                cache->loader_sleep *= 2;
-                ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
-                              "cache %V loader_sleep increased to %Mms",
-                              &cache->path->name, cache->loader_sleep);
-            }
-        }
-
-        ngx_msleep(cache->loader_sleep);
-
-        ngx_time_update();
-
-        cache->last = ngx_current_msec;
-        cache->files = 0;
-    }
-
-    return (ngx_quit || ngx_terminate) ? NGX_ABORT : NGX_OK;
-}
-
-
-static ngx_int_t
 ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path)
 {
     return NGX_OK;
@@ -1312,6 +1269,7 @@ ngx_http_file_cache_noop(ngx_tree_ctx_t 
 static ngx_int_t
 ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
 {
+    ngx_msec_t              elapsed;
     ngx_http_file_cache_t  *cache;
 
     cache = ctx->data;
@@ -1320,7 +1278,35 @@ ngx_http_file_cache_manage_file(ngx_tree
         (void) ngx_http_file_cache_delete_file(ctx, path);
     }
 
-    return ngx_http_file_cache_loader_sleep(cache);
+    if (++cache->files >= cache->loader_files) {
+        ngx_http_file_cache_loader_sleep(cache);
+
+    } else {
+        ngx_time_update();
+
+        elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+                       "http file cache loader time elapsed: %M", elapsed);
+
+        if (elapsed >= cache->loader_threshold) {
+            ngx_http_file_cache_loader_sleep(cache);
+        }
+    }
+
+    return (ngx_quit || ngx_terminate) ? NGX_ABORT : NGX_OK;
+}
+
+
+static void
+ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
+{
+    ngx_msleep(cache->loader_sleep);
+
+    ngx_time_update();
+
+    cache->last = ngx_current_msec;
+    cache->files = 0;
 }
 
 
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -143,6 +143,7 @@ ngx_http_read_client_request_body(ngx_ht
 
             r->header_in->pos += (size_t) r->headers_in.content_length_n;
             r->request_length += r->headers_in.content_length_n;
+            b->last = r->header_in->pos;
 
             if (r->request_body_in_file_only) {
                 if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) {
@@ -371,7 +372,9 @@ ngx_http_do_read_client_request_body(ngx
         }
     }
 
-    if (r->request_body_in_file_only && rb->bufs->next) {
+    if (rb->bufs->next
+        && (r->request_body_in_file_only || r->request_body_in_single_buf))
+    {
         rb->bufs = rb->bufs->next;
     }
 
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -228,13 +228,18 @@ ngx_http_upstream_init_round_robin_peer(
     rrp->peers = us->peer.data;
     rrp->current = 0;
 
-    if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
+    n = rrp->peers->number;
+
+    if (rrp->peers->next && rrp->peers->next->number > n) {
+        n = rrp->peers->next->number;
+    }
+
+    if (n <= 8 * sizeof(uintptr_t)) {
         rrp->tried = &rrp->data;
         rrp->data = 0;
 
     } else {
-        n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
-                / (8 * sizeof(uintptr_t));
+        n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t));
 
         rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
         if (rrp->tried == NULL) {
@@ -585,7 +590,7 @@ failed:
 static ngx_uint_t
 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers)
 {
-    ngx_uint_t                    i, n;
+    ngx_uint_t                    i, n, reset = 0;
     ngx_http_upstream_rr_peer_t  *peer;
 
     peer = &peers->peer[0];
@@ -624,6 +629,10 @@ ngx_http_upstream_get_peer(ngx_http_upst
             return n;
         }
 
+        if (reset++) {
+            return 0;
+        }
+
         for (i = 0; i < peers->number; i++) {
             peer[i].current_weight = peer[i].weight;
         }
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -474,6 +474,8 @@ ngx_mail_ssl_session_cache(ngx_conf_t *c
         scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
     }
 
+    scf->shm_zone->init = ngx_ssl_session_cache_init;
+
     return NGX_CONF_OK;
 
 invalid:
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -92,11 +92,6 @@ typedef struct aiocb  ngx_aiocb_t;
 #define NGX_LISTEN_BACKLOG        -1
 
 
-#if (defined SO_ACCEPTFILTER && !defined NGX_HAVE_DEFERRED_ACCEPT)
-#define NGX_HAVE_DEFERRED_ACCEPT  1
-#endif
-
-
 #if (__FreeBSD_version < 430000 || __FreeBSD_version < 500012)
 
 pid_t rfork_thread(int flags, void *stack, int (*func)(void *arg), void *arg);
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -96,11 +96,6 @@ typedef struct iocb  ngx_aiocb_t;
 #define NGX_LISTEN_BACKLOG        511
 
 
-#if defined TCP_DEFER_ACCEPT && !defined NGX_HAVE_DEFERRED_ACCEPT
-#define NGX_HAVE_DEFERRED_ACCEPT  1
-#endif
-
-
 #ifndef NGX_HAVE_SO_SNDLOWAT
 /* setsockopt(SO_SNDLOWAT) returns ENOPROTOOPT */
 #define NGX_HAVE_SO_SNDLOWAT         0
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -339,8 +339,10 @@ ngx_signal_handler(int signo)
             break;
 
         case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
-            ngx_noaccept = 1;
-            action = ", stop accepting connections";
+            if (ngx_daemonized) {
+                ngx_noaccept = 1;
+                action = ", stop accepting connections";
+            }
             break;
 
         case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
@@ -392,6 +394,9 @@ ngx_signal_handler(int signo)
         switch (signo) {
 
         case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
+            if (!ngx_daemonized) {
+                break;
+            }
             ngx_debug_quit = 1;
         case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
             ngx_quit = 1;