changeset 566:be4f34123024 NGINX_0_8_35

nginx 0.8.35 *) Change: now the charset filter runs before the SSI filter. *) Feature: the "chunked_transfer_encoding" directive. *) Bugfix: an "&" character was not escaped when it was copied in arguments part in a rewrite rule. *) Bugfix: nginx might be terminated abnormally while a signal processing or if the directive "timer_resolution" was used on platforms which do not support kqueue or eventport notification methods. Thanks to George Xie and Maxim Dounin. *) Bugfix: if temporary files and permanent storage area resided at different file systems, then permanent file modification times were incorrect. Thanks to Maxim Dounin. *) Bugfix: ngx_http_memcached_module might issue the error message "memcached sent invalid trailer". Thanks to Maxim Dounin. *) Bugfix: nginx could not built zlib-1.2.4 library using the library sources. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault occurred in a worker process, if there was large stderr output before FastCGI response; the bug had appeared in 0.8.34. Thanks to Maxim Dounin.
author Igor Sysoev <http://sysoev.ru>
date Mon, 29 Mar 2010 00:00:00 +0400
parents dd7104f21940
children a49f5d0aff01
files CHANGES CHANGES.ru auto/lib/openssl/conf auto/lib/openssl/makefile.bcc auto/lib/openssl/makefile.msvc auto/lib/zlib/make auto/modules auto/unix src/core/nginx.c src/core/nginx.h src/core/ngx_cycle.c src/core/ngx_file.c src/core/ngx_string.c src/core/ngx_times.c src/core/ngx_times.h src/event/modules/ngx_devpoll_module.c src/event/modules/ngx_epoll_module.c src/event/modules/ngx_eventport_module.c src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_poll_module.c src/event/modules/ngx_rtsig_module.c src/event/modules/ngx_select_module.c src/event/modules/ngx_win32_select_module.c src/event/ngx_event.c src/event/ngx_event_openssl.c src/http/modules/ngx_http_chunked_filter_module.c src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_memcached_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_file_cache.c src/http/ngx_http_header_filter_module.c src/misc/ngx_google_perftools_module.c src/os/unix/ngx_errno.h src/os/unix/ngx_process.c src/os/unix/ngx_process_cycle.c src/os/unix/ngx_sunpro_amd64.il
diffstat 39 files changed, 285 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,38 @@
 
+Changes with nginx 0.8.35                                        29 Mar 2010
+
+    *) Change: now the charset filter runs before the SSI filter.
+
+    *) Feature: the "chunked_transfer_encoding" directive.
+
+    *) Bugfix: an "&" character was not escaped when it was copied in 
+       arguments part in a rewrite rule.
+
+    *) Bugfix: nginx might be terminated abnormally while a signal 
+       processing or if the directive "timer_resolution" was used on 
+       platforms which do not support kqueue or eventport notification 
+       methods.
+       Thanks to George Xie and Maxim Dounin.
+
+    *) Bugfix: if temporary files and permanent storage area resided at 
+       different file systems, then permanent file modification times were 
+       incorrect.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: ngx_http_memcached_module might issue the error message 
+       "memcached sent invalid trailer".
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: nginx could not built zlib-1.2.4 library using the library 
+       sources.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: a segmentation fault occurred in a worker process, if there 
+       was large stderr output before FastCGI response; the bug had 
+       appeared in 0.8.34.
+       Thanks to Maxim Dounin.
+
+
 Changes with nginx 0.8.34                                        03 Mar 2010
 
     *) Bugfix: nginx did not support all ciphers and digests used in client 
@@ -11,7 +45,7 @@ Changes with nginx 0.8.34               
     *) Bugfix: nginx did not support HTTPS referrers.
 
     *) Bugfix: nginx/Windows might not find file if path in configuration 
-       was given in other character case; the bug had appeared in 0.8.34.
+       was given in other character case; the bug had appeared in 0.8.33.
 
     *) Bugfix: the $date_local variable has an incorrect value, if the "%s" 
        format was used.
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,37 @@
 
+Изменения в nginx 0.8.35                                          29.03.2010
+
+    *) Изменение: теперь charset-фильтр работает до SSI-фильтра.
+
+    *) Добавление: директива chunked_transfer_encoding.
+
+    *) Исправление: символ "&" при копировании в аргументы в правилах 
+       rewrite не экранировался.
+
+    *) Исправление: nginx мог завершаться аварийно во время обработки 
+       сигнала или при использовании директивы timer_resolution на 
+       платформах, не поддерживающих методы kqueue или eventport.
+       Спасибо George Xie и Максиму Дунину.
+
+    *) Исправление: если временные файлы и постоянное место хранения 
+       располагались на разных файловых системах, то у постоянных файлов 
+       время изменения было неверным.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: модуль ngx_http_memcached_module мог выдавать ошибку 
+       "memcached sent invalid trailer".
+       Спасибо Максиму Дунину.
+
+    *) Исправление: nginx не мог собрать библиотеку zlib-1.2.4 из исходных 
+       текстов.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: в рабочем процессе происходил segmentation fault, если 
+       перед ответом FastCGI-сервера было много вывода в stderr; ошибка 
+       появилась в 0.8.34.
+       Спасибо Максиму Дунину.
+
+
 Изменения в nginx 0.8.34                                          03.03.2010
 
     *) Исправление: nginx не поддерживал все шифры, используемые в 
@@ -11,7 +44,7 @@
     *) Исправление: nginx не поддерживал HTTPS-рефереры.
 
     *) Исправление: nginx/Windows мог не находить файлы, если путь в 
-       конфигурации был задан в другом регистре; ошибка появилась в 0.8.34.
+       конфигурации был задан в другом регистре; ошибка появилась в 0.8.33.
 
     *) Исправление: переменная $date_local выдавала неверное время, если 
        использовался формат "%s".
@@ -1962,7 +1995,7 @@
        Спасибо Андрею Нигматулину.
 
     *) Исправление: ngx_http_memcached_module не устанавливал 
-       upstream_response_time.
+       $upstream_response_time.
        Спасибо Максиму Дунину.
 
     *) Исправление: рабочий процесс мог зациклиться при использовании 
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -19,6 +19,8 @@ if [ $OPENSSL != NONE ]; then
 
             # libeay32.lib requires gdi32.lib
             CORE_LIBS="$CORE_LIBS gdi32.lib"
+            # OpenSSL 1.0.0 requires crypt32.lib
+            CORE_LIBS="$CORE_LIBS crypt32.lib"
         ;;
 
         *)
--- a/auto/lib/openssl/makefile.bcc
+++ b/auto/lib/openssl/makefile.bcc
@@ -5,8 +5,7 @@
 all:
 	cd $(OPENSSL)
 
-	perl Configure BC-32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \
-		$(OPENSSL_OPT)
+	perl Configure BC-32 no-shared --prefix=openssl $(OPENSSL_OPT)
 
 	ms\do_nasm
 
--- a/auto/lib/openssl/makefile.msvc
+++ b/auto/lib/openssl/makefile.msvc
@@ -5,8 +5,7 @@
 all:
 	cd $(OPENSSL)
 
-	perl Configure VC-WIN32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \
-		$(OPENSSL_OPT)
+	perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT)
 
 	ms\do_ms
 
--- a/auto/lib/zlib/make
+++ b/auto/lib/zlib/make
@@ -53,7 +53,7 @@ END
 
 $ZLIB/libz.a:	$NGX_MAKEFILE
 	cd $ZLIB \\
-	&& \$(MAKE) clean \\
+	&& \$(MAKE) distclean \\
 	&& cp contrib/asm586/match.S . \\
 	&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
 		./configure \\
@@ -70,7 +70,7 @@ END
 
 $ZLIB/libz.a:	$NGX_MAKEFILE
 	cd $ZLIB \\
-	&& \$(MAKE) clean \\
+	&& \$(MAKE) distclean \\
 	&& cp contrib/asm686/match.S . \\
 	&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
 		./configure \\
@@ -103,7 +103,7 @@ if [ $done = NO ]; then
 
 $ZLIB/libz.a:	$NGX_MAKEFILE
 	cd $ZLIB \\
-	&& \$(MAKE) clean \\
+	&& \$(MAKE) distclean \\
 	&& CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
 		./configure \\
 	&& \$(MAKE) libz.a
--- a/auto/modules
+++ b/auto/modules
@@ -102,10 +102,10 @@ fi
 #     ngx_http_range_header_filter
 #     ngx_http_gzip_filter
 #     ngx_http_postpone_filter
+#     ngx_http_ssi_filter
 #     ngx_http_charset_filter
-#     ngx_http_ssi_filter
 #         ngx_http_xslt_filter
-#         ngx_http_image_filter_filter
+#         ngx_http_image_filter
 #         ngx_http_sub_filter
 #         ngx_http_addition_filter
 #         ngx_http_userid_filter
@@ -131,12 +131,6 @@ if [ $HTTP_POSTPONE = YES ]; then
     HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS"
 fi
 
-if [ $HTTP_CHARSET = YES ]; then
-    have=NGX_HTTP_CHARSET . auto/have
-    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
-    HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
-fi
-
 if [ $HTTP_SSI = YES ]; then
     have=NGX_HTTP_SSI . auto/have
     HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE"
@@ -144,6 +138,12 @@ if [ $HTTP_SSI = YES ]; then
     HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS"
 fi
 
+if [ $HTTP_CHARSET = YES ]; then
+    have=NGX_HTTP_CHARSET . auto/have
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
+fi
+
 if [ $HTTP_XSLT = YES ]; then
     USE_LIBXSLT=YES
     HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE"
--- a/auto/unix
+++ b/auto/unix
@@ -133,6 +133,16 @@ ngx_feature_test="char buf[1024]; long n
 . auto/feature
 
 
+ngx_feature="sys_errlist[]"
+ngx_feature_name="NGX_HAVE_SYS_ERRLIST"
+ngx_feature_run=yes
+ngx_feature_incs="#include <stdio.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];"
+. auto/feature
+
+
 ngx_feature="localtime_r()"
 ngx_feature_name="NGX_HAVE_LOCALTIME_R"
 ngx_feature_run=no
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -919,7 +919,7 @@ ngx_core_module_create_conf(ngx_cycle_t 
     }
 
     /*
-     * set by pcalloc()
+     * set by ngx_pcalloc()
      *
      *     ccf->pid = NULL;
      *     ccf->oldpid = NULL;
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version         8034
-#define NGINX_VERSION      "0.8.34"
+#define nginx_version         8035
+#define NGINX_VERSION      "0.8.35"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -63,7 +63,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
     tp = ngx_timeofday();
     tp->sec = 0;
 
-    ngx_time_update(0, 0);
+    ngx_time_update();
 
 
     log = old_cycle->log;
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -762,10 +762,12 @@ ngx_copy_file(u_char *from, u_char *to, 
         size -= n;
     }
 
-    if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
-        ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
-                      ngx_set_file_time_n " \"%s\" failed", to);
-        goto failed;
+    if (cf->time != -1) {
+        if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
+            ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+                          ngx_set_file_time_n " \"%s\" failed", to);
+            goto failed;
+        }
     }
 
     rc = NGX_OK;
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1278,13 +1278,13 @@ ngx_escape_uri(u_char *dst, u_char *src,
         0xffffffff  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
-                    /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
+                    /* " ", "#", "%", "&", "+", "?", %00-%1F, %7F-%FF */
 
     static uint32_t   args[] = {
         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                     /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-        0x80000829, /* 1000 0000 0000 0000  0000 1000 0010 1001 */
+        0x80000869, /* 1000 0000 0000 0000  0000 1000 0110 1001 */
 
                     /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
         0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -28,6 +28,17 @@ volatile ngx_str_t       ngx_cached_err_
 volatile ngx_str_t       ngx_cached_http_time;
 volatile ngx_str_t       ngx_cached_http_log_time;
 
+#if !(NGX_WIN32)
+
+/*
+ * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
+ * they must not be called by a signal handler, so we use the cached
+ * GMT offset value. Fortunately the value is changed only two times a year.
+ */
+
+static ngx_int_t         cached_gmtoff;
+#endif
+
 static ngx_time_t        cached_time[NGX_TIME_SLOTS];
 static u_char            cached_err_log_time[NGX_TIME_SLOTS]
                                     [sizeof("1970/09/28 12:00:00")];
@@ -50,15 +61,17 @@ ngx_time_init(void)
 
     ngx_cached_time = &cached_time[0];
 
-    ngx_time_update(0, 0);
+    ngx_time_update();
 }
 
 
 void
-ngx_time_update(time_t sec, ngx_uint_t msec)
+ngx_time_update(void)
 {
     u_char          *p0, *p1, *p2;
     ngx_tm_t         tm, gmt;
+    time_t           sec;
+    ngx_uint_t       msec;
     ngx_time_t      *tp;
     struct timeval   tv;
 
@@ -66,12 +79,10 @@ ngx_time_update(time_t sec, ngx_uint_t m
         return;
     }
 
-    if (sec == 0) {
-        ngx_gettimeofday(&tv);
+    ngx_gettimeofday(&tv);
 
-        sec = tv.tv_sec;
-        msec = tv.tv_usec / 1000;
-    }
+    sec = tv.tv_sec;
+    msec = tv.tv_usec / 1000;
 
     ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
 
@@ -112,12 +123,14 @@ ngx_time_update(time_t sec, ngx_uint_t m
 #elif (NGX_HAVE_GMTOFF)
 
     ngx_localtime(sec, &tm);
-    tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+    cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+    tp->gmtoff = cached_gmtoff;
 
 #else
 
     ngx_localtime(sec, &tm);
-    tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+    cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+    tp->gmtoff = cached_gmtoff;
 
 #endif
 
@@ -151,6 +164,59 @@ ngx_time_update(time_t sec, ngx_uint_t m
 }
 
 
+#if !(NGX_WIN32)
+
+void
+ngx_time_sigsafe_update(void)
+{
+    u_char          *p;
+    ngx_tm_t         tm;
+    time_t           sec;
+    ngx_uint_t       msec;
+    ngx_time_t      *tp;
+    struct timeval   tv;
+
+    if (!ngx_trylock(&ngx_time_lock)) {
+        return;
+    }
+
+    ngx_gettimeofday(&tv);
+
+    sec = tv.tv_sec;
+    msec = tv.tv_usec / 1000;
+
+    tp = &cached_time[slot];
+
+    if (tp->sec == sec) {
+        ngx_unlock(&ngx_time_lock);
+        return;
+    }
+
+    if (slot == NGX_TIME_SLOTS - 1) {
+        slot = 0;
+    } else {
+        slot++;
+    }
+
+    ngx_gmtime(sec + cached_gmtoff * 60, &tm);
+
+    p = &cached_err_log_time[slot][0];
+
+    (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
+                       tm.ngx_tm_year, tm.ngx_tm_mon,
+                       tm.ngx_tm_mday, tm.ngx_tm_hour,
+                       tm.ngx_tm_min, tm.ngx_tm_sec);
+
+    ngx_memory_barrier();
+
+    ngx_cached_err_log_time.data = p;
+
+    ngx_unlock(&ngx_time_lock);
+}
+
+#endif
+
+
 u_char *
 ngx_http_time(u_char *buf, time_t t)
 {
--- a/src/core/ngx_times.h
+++ b/src/core/ngx_times.h
@@ -20,7 +20,8 @@ typedef struct {
 
 
 void ngx_time_init(void);
-void ngx_time_update(time_t sec, ngx_uint_t msec);
+void ngx_time_update(void);
+void ngx_time_sigsafe_update(void);
 u_char *ngx_http_time(u_char *buf, time_t t);
 u_char *ngx_http_cookie_time(u_char *buf, time_t t);
 void ngx_gmtime(time_t t, ngx_tm_t *tp);
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -371,8 +371,8 @@ ngx_devpoll_process_events(ngx_cycle_t *
 
     err = (events == -1) ? ngx_errno : 0;
 
-    if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+        ngx_time_update();
     }
 
     if (err) {
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -531,8 +531,8 @@ ngx_epoll_process_events(ngx_cycle_t *cy
 
     err = (events == -1) ? ngx_errno : 0;
 
-    if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+        ngx_time_update();
     }
 
     if (err) {
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -405,7 +405,7 @@ ngx_eventport_process_events(ngx_cycle_t
     err = ngx_errno;
 
     if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+        ngx_time_update();
     }
 
     if (n == -1) {
@@ -439,7 +439,7 @@ ngx_eventport_process_events(ngx_cycle_t
     for (i = 0; i < events; i++) {
 
         if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
-            ngx_time_update(0, 0);
+            ngx_time_update();
             continue;
         }
 
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -537,8 +537,8 @@ ngx_kqueue_process_events(ngx_cycle_t *c
 
     err = (events == -1) ? ngx_errno : 0;
 
-    if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+        ngx_time_update();
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@@ -589,7 +589,7 @@ ngx_kqueue_process_events(ngx_cycle_t *c
 #if (NGX_HAVE_TIMER_EVENT)
 
         if (event_list[i].filter == EVFILT_TIMER) {
-            ngx_time_update(0, 0);
+            ngx_time_update();
             continue;
         }
 
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -262,8 +262,8 @@ ngx_poll_process_events(ngx_cycle_t *cyc
 
     err = (ready == -1) ? ngx_errno : 0;
 
-    if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+        ngx_time_update();
     }
 
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -323,7 +323,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
                        "rtsig signo:%d", signo);
 
         if (flags & NGX_UPDATE_TIME) {
-            ngx_time_update(0, 0);
+            ngx_time_update();
         }
 
         if (err == NGX_EAGAIN) {
@@ -349,7 +349,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
                    signo, si.si_fd, si.si_band);
 
     if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+        ngx_time_update();
     }
 
     rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
@@ -419,7 +419,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
 
     } else if (signo == SIGALRM) {
 
-        ngx_time_update(0, 0);
+        ngx_time_update();
 
         return NGX_OK;
 
@@ -671,7 +671,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *
     }
 
     if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+        ngx_time_update();
     }
 
     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -262,8 +262,8 @@ ngx_select_process_events(ngx_cycle_t *c
 
     err = (ready == -1) ? ngx_errno : 0;
 
-    if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+        ngx_time_update();
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
--- a/src/event/modules/ngx_win32_select_module.c
+++ b/src/event/modules/ngx_win32_select_module.c
@@ -269,7 +269,7 @@ ngx_select_process_events(ngx_cycle_t *c
     err = (ready == -1) ? ngx_socket_errno : 0;
 
     if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
+        ngx_time_update();
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -562,8 +562,6 @@ ngx_timer_signal_handler(int signo)
 {
     ngx_event_timer_alarm = 1;
 
-    ngx_time_update(0, 0);
-
 #if 1
     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
 #endif
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -561,6 +561,9 @@ ngx_ssl_handshake(ngx_connection_t *c)
 #if (NGX_DEBUG)
         {
         char         buf[129], *s, *d;
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+        const
+#endif
         SSL_CIPHER  *cipher;
 
         cipher = SSL_get_current_cipher(c->ssl->connection);
--- a/src/http/modules/ngx_http_chunked_filter_module.c
+++ b/src/http/modules/ngx_http_chunked_filter_module.c
@@ -50,6 +50,8 @@ static ngx_http_output_body_filter_pt   
 static ngx_int_t
 ngx_http_chunked_header_filter(ngx_http_request_t *r)
 {
+    ngx_http_core_loc_conf_t  *clcf;
+
     if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
         || r->headers_out.status == NGX_HTTP_NO_CONTENT
         || r != r->main
@@ -63,7 +65,14 @@ ngx_http_chunked_header_filter(ngx_http_
             r->keepalive = 0;
 
         } else {
-            r->chunked = 1;
+            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+            if (clcf->chunked_transfer_encoding) {
+                r->chunked = 1;
+
+            } else {
+                r->keepalive = 0;
+            }
         }
     }
 
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -1254,7 +1254,7 @@ ngx_http_fastcgi_process_header(ngx_http
 
 #if (NGX_HTTP_CACHE)
 
-        if (f->large_stderr) {
+        if (f->large_stderr && r->cache) {
             u_char   *start;
             ssize_t   len;
 
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -432,15 +432,20 @@ ngx_http_memcached_filter(void *data, ss
 
         if (ngx_strncmp(b->last,
                    ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
-                   ctx->rest)
+                   bytes)
             != 0)
         {
             ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
                           "memcached sent invalid trailer");
+
+            u->length = 0;
+            ctx->rest = 0;
+
+            return NGX_OK;
         }
 
-        u->length = 0;
-        ctx->rest = 0;
+        u->length -= bytes;
+        ctx->rest -= bytes;
 
         return NGX_OK;
     }
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -637,6 +637,7 @@ ngx_http_proxy_handler(ngx_http_request_
     u->process_header = ngx_http_proxy_process_status_line;
     u->abort_request = ngx_http_proxy_abort_request;
     u->finalize_request = ngx_http_proxy_finalize_request;
+    r->state = 0;
 
     if (plcf->redirects) {
         u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
@@ -1198,6 +1199,7 @@ ngx_http_proxy_reinit_request(ngx_http_r
     ctx->status_end = NULL;
 
     r->upstream->process_header = ngx_http_proxy_process_status_line;
+    r->state = 0;
 
     return NGX_OK;
 }
@@ -1913,7 +1915,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
      *     conf->body_set_len = NULL;
      *     conf->body_set = NULL;
      *     conf->body_source = { 0, NULL };
-     *     conf->rewrite_locations = NULL;
+     *     conf->redirects = NULL;
      */
 
     conf->upstream.store = NGX_CONF_UNSET;
@@ -2754,9 +2756,16 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, 
     }
 
     if (ngx_strcmp(value[1].data, "default") == 0) {
+        if (plcf->proxy_lengths) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "\"proxy_redirect default\" may not be used "
+                               "with \"proxy_pass\" directive with variables");
+            return NGX_CONF_ERROR;
+        }
+
         if (plcf->url.data == NULL) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "\"proxy_rewrite_location default\" must go "
+                               "\"proxy_redirect default\" must go "
                                "after the \"proxy_pass\" directive");
             return NGX_CONF_ERROR;
         }
--- 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.34';
+our $VERSION = '0.8.35';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -599,6 +599,13 @@ static ngx_command_t  ngx_http_core_comm
       offsetof(ngx_http_core_loc_conf_t, if_modified_since),
       &ngx_http_core_if_modified_since },
 
+    { ngx_string("chunked_transfer_encoding"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
+      NULL },
+
     { ngx_string("error_page"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                         |NGX_CONF_2MORE,
@@ -2972,6 +2979,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t
     clcf->log_subrequest = NGX_CONF_UNSET;
     clcf->recursive_error_pages = NGX_CONF_UNSET;
     clcf->server_tokens = NGX_CONF_UNSET;
+    clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
     clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
     clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
 
@@ -3215,6 +3223,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
     ngx_conf_merge_value(conf->recursive_error_pages,
                               prev->recursive_error_pages, 0);
     ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
+    ngx_conf_merge_value(conf->chunked_transfer_encoding,
+                              prev->chunked_transfer_encoding, 1);
 
     ngx_conf_merge_ptr_value(conf->open_file_cache,
                               prev->open_file_cache, NULL);
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -363,6 +363,7 @@ struct ngx_http_core_loc_conf_s {
     ngx_flag_t    log_subrequest;          /* log_subrequest */
     ngx_flag_t    recursive_error_pages;   /* recursive_error_pages */
     ngx_flag_t    server_tokens;           /* server_tokens */
+    ngx_flag_t    chunked_transfer_encoding; /* chunked_transfer_encoding */
 
 #if (NGX_HTTP_GZIP)
     ngx_flag_t    gzip_vary;               /* gzip_vary */
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -1216,7 +1216,7 @@ ngx_http_file_cache_manager_sleep(ngx_ht
 
     if (cache->files++ > 100) {
 
-        ngx_time_update(0, 0);
+        ngx_time_update();
 
         elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
 
@@ -1233,7 +1233,7 @@ ngx_http_file_cache_manager_sleep(ngx_ht
 
             ngx_msleep(200);
 
-            ngx_time_update(0, 0);
+            ngx_time_update();
         }
 
         cache->last = ngx_current_msec;
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -338,6 +338,11 @@ ngx_http_header_filter(ngx_http_request_
             port = ntohs(sin6->sin6_port);
             break;
 #endif
+#if (NGX_HAVE_UNIX_DOMAIN)
+        case AF_UNIX:
+            port = 0;
+            break;
+#endif
         default: /* AF_INET */
             sin = (struct sockaddr_in *) c->local_sockaddr;
             port = ntohs(sin->sin_port);
--- a/src/misc/ngx_google_perftools_module.c
+++ b/src/misc/ngx_google_perftools_module.c
@@ -8,7 +8,7 @@
 #include <ngx_core.h>
 
 /*
- * declare Profiler here interface because
+ * declare Profiler interface here because
  * <google/profiler.h> is C++ header file
  */
 
@@ -73,7 +73,7 @@ ngx_google_perftools_create_conf(ngx_cyc
     }
 
     /*
-     * set by pcalloc()
+     * set by ngx_pcalloc()
      *
      *     gptcf->profiles = { 0, NULL };
      */
@@ -101,7 +101,6 @@ ngx_google_perftools_worker(ngx_cycle_t 
     }
 
     if (getenv("CPUPROFILE")) {
-
         /* disable inherited Profiler enabled in master process */
         ProfilerStop();
     }
@@ -109,7 +108,6 @@ ngx_google_perftools_worker(ngx_cycle_t 
     ngx_sprintf(profile, "%V.%d%Z", &gptcf->profiles, ngx_pid);
 
     if (ProfilerStart(profile)) {
-
         /* start ITIMER_PROF timer */
         ProfilerRegisterThread();
 
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -64,10 +64,22 @@ u_char *ngx_strerror_r(int err, u_char *
 
 /* Solaris and Tru64 UNIX have thread-safe strerror() */
 
-#define ngx_strerror_r(err, errstr, size)  \
+#define ngx_strerror_r(err, errstr, size)                                    \
     ngx_cpystrn(errstr, (u_char *) strerror(err), size)
 
 #endif
 
 
+#if (NGX_HAVE_SYS_ERRLIST)
+
+#define ngx_sigsafe_strerror(err)                                            \
+    (err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error"
+
+#else
+
+#define ngx_sigsafe_strerror(err)  ""
+
+#endif
+
+
 #endif /* _NGX_ERRNO_H_INCLUDED_ */
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -317,7 +317,7 @@ ngx_signal_handler(int signo)
         }
     }
 
-    ngx_time_update(0, 0);
+    ngx_time_sigsafe_update();
 
     action = "";
 
@@ -479,16 +479,17 @@ ngx_process_get_status(void)
              */
 
             if (err == NGX_ECHILD) {
-                ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno,
-                              "waitpid() failed");
+                ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+                              "waitpid() failed (%d: %s)",
+                              err, ngx_sigsafe_strerror(err));
                 return;
             }
 
 #endif
 
-            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno,
-                          "waitpid() failed");
-
+            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+                          "waitpid() failed (%d: %s)",
+                          err, ngx_sigsafe_strerror(err));
             return;
         }
 
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -168,7 +168,7 @@ ngx_master_process_cycle(ngx_cycle_t *cy
 
         sigsuspend(&set);
 
-        ngx_time_update(0, 0);
+        ngx_time_update();
 
         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                        "wake up, sigio %i", sigio);
@@ -1342,7 +1342,7 @@ ngx_cache_manager_process_handler(ngx_ev
 
             next = (n <= next) ? n : next;
 
-            ngx_time_update(0, 0);
+            ngx_time_update();
         }
     }
 
@@ -1372,7 +1372,7 @@ ngx_cache_loader_process_handler(ngx_eve
 
         if (path[i]->loader) {
             path[i]->loader(path[i]->data);
-            ngx_time_update(0, 0);
+            ngx_time_update();
         }
     }
 
--- a/src/os/unix/ngx_sunpro_amd64.il
+++ b/src/os/unix/ngx_sunpro_amd64.il
@@ -31,7 +31,12 @@
 
 
 / ngx_cpu_pause()
+/
+/ the "rep; nop" is used instead of "pause" to avoid the "[ PAUSE ]" hardware
+/ capability added by linker because Solaris/amd64 does not know about it:
+/
+/ ld.so.1: nginx: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
 
        .inline ngx_cpu_pause,0
-       pause
+       rep; nop
        .end