changeset 646:09a689c5e494 NGINX_1_0_13

nginx 1.0.13 *) Feature: the "return" and "error_page" directives can now 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: memory leaks. Thanks to Lanshun Zhou. *) Bugfix: nginx might log incorrect error "upstream prematurely closed connection" instead of correct "upstream sent too big header" one. Thanks to Feibo Li. *) Bugfix: on ZFS filesystem disk cache size might be calculated incorrectly; the bug had appeared in 1.0.1. *) Bugfix: the number of internal redirects to named locations was not limited. *) Bugfix: temporary files might be not removed if the "proxy_store" directive was used with SSI includes. *) Bugfix: in some cases non-cacheable variables (such as the $args variable) returned old empty cached value. *) Bugfix: the "proxy_redirect" directives might be inherited incorrectly. *) Bugfix: nginx could not be built with the ngx_http_perl_module if the --with-openssl option was used. *) Bugfix: nginx could not be built by the icc 12.1 compiler.
author Igor Sysoev <http://sysoev.ru>
date Mon, 05 Mar 2012 00:00:00 +0400
parents 60344e6faa47
children db509e2f8037
files CHANGES CHANGES.ru auto/cc/name auto/lib/perl/make auto/unix src/core/nginx.h src/core/ngx_open_file_cache.c src/core/ngx_resolver.c src/core/ngx_times.c src/event/ngx_event.h src/event/ngx_event_openssl.c src/event/ngx_event_pipe.c src/http/modules/ngx_http_autoindex_module.c src/http/modules/ngx_http_headers_filter_module.c src/http/modules/ngx_http_index_module.c src/http/modules/ngx_http_limit_req_module.c src/http/modules/ngx_http_limit_zone_module.c src/http/modules/ngx_http_log_module.c src/http/modules/ngx_http_memcached_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_random_index_module.c src/http/modules/ngx_http_range_filter_module.c src/http/modules/ngx_http_rewrite_module.c src/http/modules/ngx_http_userid_filter_module.c src/http/modules/perl/Makefile.PL src/http/modules/perl/nginx.pm src/http/ngx_http_core_module.c src/http/ngx_http_file_cache.c src/http/ngx_http_header_filter_module.c src/http/ngx_http_parse_time.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_special_response.c src/http/ngx_http_upstream.c src/http/ngx_http_variables.c src/mail/ngx_mail_pop3_handler.c src/os/unix/ngx_darwin_sendfile_chain.c src/os/unix/ngx_files.h src/os/unix/ngx_freebsd_sendfile_chain.c src/os/unix/ngx_posix_init.c src/os/unix/ngx_user.c
diffstat 41 files changed, 350 insertions(+), 270 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,42 @@
 
+Changes with nginx 1.0.13                                        05 Mar 2012
+
+    *) Feature: the "return" and "error_page" directives can now 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: memory leaks.
+       Thanks to Lanshun Zhou.
+
+    *) Bugfix: nginx might log incorrect error "upstream prematurely closed
+       connection" instead of correct "upstream sent too big header" one.
+       Thanks to Feibo Li.
+
+    *) Bugfix: on ZFS filesystem disk cache size might be calculated
+       incorrectly; the bug had appeared in 1.0.1.
+
+    *) Bugfix: the number of internal redirects to named locations was not
+       limited.
+
+    *) Bugfix: temporary files might be not removed if the "proxy_store"
+       directive was used with SSI includes.
+
+    *) Bugfix: in some cases non-cacheable variables (such as the $args
+       variable) returned old empty cached value.
+
+    *) Bugfix: the "proxy_redirect" directives might be inherited
+       incorrectly.
+
+    *) Bugfix: nginx could not be built with the ngx_http_perl_module if the
+       --with-openssl option was used.
+
+    *) Bugfix: nginx could not be built by the icc 12.1 compiler.
+
+
 Changes with nginx 1.0.12                                        06 Feb 2012
 
     *) Feature: the "TLSv1.1" and "TLSv1.2" parameters of the
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,42 @@
 
+Изменения в nginx 1.0.13                                          05.03.2012
+
+    *) Добавление: директивы return и error_page теперь могут использоваться
+       для возврата перенаправлений с кодом 307.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовалась директива resolver и на глобальном уровне не была
+       задана директива error_log.
+       Спасибо Роману Арутюняну.
+
+    *) Исправление: утечек памяти.
+       Спасибо Lanshun Zhou.
+
+    *) Исправление: nginx мог некорректно сообщать об ошибке "upstream
+       prematurely closed connection" вместо "upstream sent too big header".
+       Спасибо Feibo Li.
+
+    *) Исправление: при использовании ZFS размер кэша на диске мог считаться
+       некорректно; ошибка появилась в 1.0.1.
+
+    *) Исправление: количество внутренних перенаправлений в именованные
+       location'ы не ограничивалось.
+
+    *) Исправление: при использовании директивы proxy_store с
+       SSI-подзапросами временные файлы могли не удаляться.
+
+    *) Исправление: в некоторых случаях некэшируемые переменные (такие, как
+       $args) возвращали старое пустое закэшированное значение.
+
+    *) Исправление: директивы proxy_redirect могли наследоваться
+       некорректно.
+
+    *) Исправление: nginx не собирался с модулем ngx_http_perl_module, если
+       использовался параметр --with-openssl.
+
+    *) Исправление: nginx не собирался компилятором icc 12.1.
+
+
 Изменения в nginx 1.0.12                                          06.02.2012
 
     *) Добавление: параметры TLSv1.1 и TLSv1.2 в директиве ssl_protocols.
--- a/auto/cc/name
+++ b/auto/cc/name
@@ -64,16 +64,16 @@ if [ "$CC" = bcc32 ]; then
     echo " + using Borland C++ compiler"
 
 else
+if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
+    NGX_CC_NAME=icc
+    echo " + using Intel C++ compiler"
+
+else
 if `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
     NGX_CC_NAME=gcc
     echo " + using GNU C compiler"
 
 else
-if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
-    NGX_CC_NAME=icc
-    echo " + using Intel C++ compiler"
-
-else
 if `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
     NGX_CC_NAME=sunc
     echo " + using Sun C compiler"
--- a/auto/lib/perl/make
+++ b/auto/lib/perl/make
@@ -28,6 +28,7 @@ cat << END                              
 		&& NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT"	\
 			NGX_PCRE=$PCRE					\
 			NGX_OBJS=$NGX_OBJS				\
+			NGX_OPENSSL=$OPENSSL				\
 		$NGX_PERL Makefile.PL					\
 			LIB=$NGX_PERL_MODULES				\
 			INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
--- a/auto/unix
+++ b/auto/unix
@@ -707,3 +707,13 @@ ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="struct dirent  dir; dir.d_type = DT_REG"
 . auto/feature
+
+
+ngx_feature="sysconf(_SC_NPROCESSORS_ONLN)"
+ngx_feature_name="NGX_HAVE_SC_NPROCESSORS_ONLN"
+ngx_feature_run=no
+ngx_feature_incs=
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="sysconf(_SC_NPROCESSORS_ONLN)"
+. auto/feature
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1000012
-#define NGINX_VERSION      "1.0.12"
+#define nginx_version      1000013
+#define NGINX_VERSION      "1.0.13"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -837,20 +837,15 @@ ngx_open_file_lookup(ngx_open_file_cache
 
         /* hash == node->key */
 
-        do {
-            file = (ngx_cached_open_file_t *) node;
+        file = (ngx_cached_open_file_t *) node;
 
-            rc = ngx_strcmp(name->data, file->name);
+        rc = ngx_strcmp(name->data, file->name);
 
-            if (rc == 0) {
-                return file;
-            }
+        if (rc == 0) {
+            return file;
+        }
 
-            node = (rc < 0) ? node->left : node->right;
-
-        } while (node != sentinel && hash == node->key);
-
-        break;
+        node = (rc < 0) ? node->left : node->right;
     }
 
     return NULL;
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -152,11 +152,6 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_
         uc->sockaddr = addr->sockaddr;
         uc->socklen = addr->socklen;
         uc->server = addr->name;
-
-        uc->log = cf->cycle->new_log;
-        uc->log.handler = ngx_resolver_log_error;
-        uc->log.data = uc;
-        uc->log.action = "resolving";
     }
 
     return r;
@@ -830,6 +825,12 @@ ngx_resolver_send_query(ngx_resolver_t *
     uc = r->udp_connection;
 
     if (uc->connection == NULL) {
+
+        uc->log = *r->log;
+        uc->log.handler = ngx_resolver_log_error;
+        uc->log.data = uc;
+        uc->log.action = "resolving";
+
         if (ngx_udp_connect(uc) != NGX_OK) {
             return NGX_ERROR;
         }
@@ -1625,20 +1626,15 @@ ngx_resolver_lookup_name(ngx_resolver_t 
 
         /* hash == node->key */
 
-        do {
-            rn = (ngx_resolver_node_t *) node;
-
-            rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
-
-            if (rc == 0) {
-                return rn;
-            }
-
-            node = (rc < 0) ? node->left : node->right;
-
-        } while (node != sentinel && hash == node->key);
-
-        break;
+        rn = (ngx_resolver_node_t *) node;
+
+        rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
+
+        if (rc == 0) {
+            return rn;
+        }
+
+        node = (rc < 0) ? node->left : node->right;
     }
 
     /* not found */
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -287,7 +287,7 @@ ngx_gmtime(time_t t, ngx_tm_t *tp)
 
     days = n / 86400;
 
-    /* Jaunary 1, 1970 was Thursday */
+    /* January 1, 1970 was Thursday */
 
     wday = (4 + days) % 7;
 
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -83,7 +83,7 @@ struct ngx_event_s {
 #endif
 
 #if (NGX_WIN32)
-    /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was succesfull */
+    /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
     unsigned         accept_context_updated:1;
 #endif
 
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -842,7 +842,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char
         case NGX_ERROR:
             c->read->error = 1;
 
-            /* fall thruogh */
+            /* fall through */
 
         case NGX_AGAIN:
             return c->ssl->last;
@@ -1801,44 +1801,39 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_
 
         /* hash == node->key */
 
-        do {
-            sess_id = (ngx_ssl_sess_id_t *) node;
-
-            rc = ngx_memn2cmp(id, sess_id->id,
-                              (size_t) len, (size_t) node->data);
-            if (rc == 0) {
-
-                if (sess_id->expire > ngx_time()) {
-                    ngx_memcpy(buf, sess_id->session, sess_id->len);
-
-                    ngx_shmtx_unlock(&shpool->mutex);
-
-                    p = buf;
-                    sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
-
-                    return sess;
-                }
-
-                ngx_queue_remove(&sess_id->queue);
-
-                ngx_rbtree_delete(&cache->session_rbtree, node);
-
-                ngx_slab_free_locked(shpool, sess_id->session);
+        sess_id = (ngx_ssl_sess_id_t *) node;
+
+        rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
+
+        if (rc == 0) {
+
+            if (sess_id->expire > ngx_time()) {
+                ngx_memcpy(buf, sess_id->session, sess_id->len);
+
+                ngx_shmtx_unlock(&shpool->mutex);
+
+                p = buf;
+                sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
+
+                return sess;
+            }
+
+            ngx_queue_remove(&sess_id->queue);
+
+            ngx_rbtree_delete(&cache->session_rbtree, node);
+
+            ngx_slab_free_locked(shpool, sess_id->session);
 #if (NGX_PTR_SIZE == 4)
-                ngx_slab_free_locked(shpool, sess_id->id);
+            ngx_slab_free_locked(shpool, sess_id->id);
 #endif
-                ngx_slab_free_locked(shpool, sess_id);
-
-                sess = NULL;
-
-                goto done;
-            }
-
-            node = (rc < 0) ? node->left : node->right;
-
-        } while (node != sentinel && hash == node->key);
-
-        break;
+            ngx_slab_free_locked(shpool, sess_id);
+
+            sess = NULL;
+
+            goto done;
+        }
+
+        node = (rc < 0) ? node->left : node->right;
     }
 
 done:
@@ -1908,31 +1903,26 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx
 
         /* hash == node->key */
 
-        do {
-            sess_id = (ngx_ssl_sess_id_t *) node;
-
-            rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
-
-            if (rc == 0) {
-
-                ngx_queue_remove(&sess_id->queue);
-
-                ngx_rbtree_delete(&cache->session_rbtree, node);
-
-                ngx_slab_free_locked(shpool, sess_id->session);
+        sess_id = (ngx_ssl_sess_id_t *) node;
+
+        rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
+
+        if (rc == 0) {
+
+            ngx_queue_remove(&sess_id->queue);
+
+            ngx_rbtree_delete(&cache->session_rbtree, node);
+
+            ngx_slab_free_locked(shpool, sess_id->session);
 #if (NGX_PTR_SIZE == 4)
-                ngx_slab_free_locked(shpool, sess_id->id);
+            ngx_slab_free_locked(shpool, sess_id->id);
 #endif
-                ngx_slab_free_locked(shpool, sess_id);
-
-                goto done;
-            }
-
-            node = (rc < 0) ? node->left : node->right;
-
-        } while (node != sentinel && hash == node->key);
-
-        break;
+            ngx_slab_free_locked(shpool, sess_id);
+
+            goto done;
+        }
+
+        node = (rc < 0) ? node->left : node->right;
     }
 
 done:
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -946,7 +946,7 @@ ngx_event_pipe_add_free_buf(ngx_event_pi
         return NGX_OK;
     }
 
-    /* the first free buf is partialy filled, thus add the free buf after it */
+    /* the first free buf is partially filled, thus add the free buf after it */
 
     cl->next = p->free_raw_bufs->next;
     p->free_raw_bufs->next = cl;
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -95,8 +95,8 @@ static ngx_http_module_t  ngx_http_autoi
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_autoindex_create_loc_conf,    /* create location configration */
-    ngx_http_autoindex_merge_loc_conf      /* merge location configration */
+    ngx_http_autoindex_create_loc_conf,    /* create location configuration */
+    ngx_http_autoindex_merge_loc_conf      /* merge location configuration */
 };
 
 
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -149,7 +149,9 @@ ngx_http_headers_filter(ngx_http_request
             && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
             && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
             && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY
-            && r->headers_out.status != NGX_HTTP_NOT_MODIFIED))
+            && r->headers_out.status != NGX_HTTP_SEE_OTHER
+            && r->headers_out.status != NGX_HTTP_NOT_MODIFIED
+            && r->headers_out.status != NGX_HTTP_TEMPORARY_REDIRECT))
     {
         return ngx_http_next_header_filter(r);
     }
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -62,8 +62,8 @@ static ngx_http_module_t  ngx_http_index
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_index_create_loc_conf,        /* create location configration */
-    ngx_http_index_merge_loc_conf          /* merge location configration */
+    ngx_http_index_create_loc_conf,        /* create location configuration */
+    ngx_http_index_merge_loc_conf          /* merge location configuration */
 };
 
 
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -112,8 +112,8 @@ static ngx_http_module_t  ngx_http_limit
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_limit_req_create_conf,        /* create location configration */
-    ngx_http_limit_req_merge_conf          /* merge location configration */
+    ngx_http_limit_req_create_conf,        /* create location configuration */
+    ngx_http_limit_req_merge_conf          /* merge location configuration */
 };
 
 
@@ -372,47 +372,42 @@ ngx_http_limit_req_lookup(ngx_http_limit
 
         /* hash == node->key */
 
-        do {
-            lr = (ngx_http_limit_req_node_t *) &node->color;
+        lr = (ngx_http_limit_req_node_t *) &node->color;
 
-            rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
+        rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
 
-            if (rc == 0) {
-                ngx_queue_remove(&lr->queue);
-                ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
-
-                tp = ngx_timeofday();
-
-                now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
-                ms = (ngx_msec_int_t) (now - lr->last);
-
-                excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
+        if (rc == 0) {
+            ngx_queue_remove(&lr->queue);
+            ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
 
-                if (excess < 0) {
-                    excess = 0;
-                }
+            tp = ngx_timeofday();
 
-                *ep = excess;
+            now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
+            ms = (ngx_msec_int_t) (now - lr->last);
 
-                if ((ngx_uint_t) excess > lrcf->burst) {
-                    return NGX_BUSY;
-                }
+            excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
 
-                lr->excess = excess;
-                lr->last = now;
-
-                if (excess) {
-                    return NGX_AGAIN;
-                }
-
-                return NGX_OK;
+            if (excess < 0) {
+                excess = 0;
             }
 
-            node = (rc < 0) ? node->left : node->right;
+            *ep = excess;
+
+            if ((ngx_uint_t) excess > lrcf->burst) {
+                return NGX_BUSY;
+            }
+
+            lr->excess = excess;
+            lr->last = now;
 
-        } while (node != sentinel && hash == node->key);
+            if (excess) {
+                return NGX_AGAIN;
+            }
 
-        break;
+            return NGX_OK;
+        }
+
+        node = (rc < 0) ? node->left : node->right;
     }
 
     *ep = 0;
--- a/src/http/modules/ngx_http_limit_zone_module.c
+++ b/src/http/modules/ngx_http_limit_zone_module.c
@@ -96,8 +96,8 @@ static ngx_http_module_t  ngx_http_limit
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_limit_zone_create_conf,       /* create location configration */
-    ngx_http_limit_zone_merge_conf         /* merge location configration */
+    ngx_http_limit_zone_create_conf,       /* create location configuration */
+    ngx_http_limit_zone_merge_conf         /* merge location configuration */
 };
 
 
@@ -194,31 +194,26 @@ ngx_http_limit_zone_handler(ngx_http_req
 
         /* hash == node->key */
 
-        do {
-            lz = (ngx_http_limit_zone_node_t *) &node->color;
+        lz = (ngx_http_limit_zone_node_t *) &node->color;
 
-            rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len);
+        rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len);
 
-            if (rc == 0) {
-                if ((ngx_uint_t) lz->conn < lzcf->conn) {
-                    lz->conn++;
-                    goto done;
-                }
-
-                ngx_shmtx_unlock(&shpool->mutex);
-
-                ngx_log_error(lzcf->log_level, r->connection->log, 0,
-                              "limiting connections by zone \"%V\"",
-                              &lzcf->shm_zone->shm.name);
-
-                return NGX_HTTP_SERVICE_UNAVAILABLE;
+        if (rc == 0) {
+            if ((ngx_uint_t) lz->conn < lzcf->conn) {
+                lz->conn++;
+                goto done;
             }
 
-            node = (rc < 0) ? node->left : node->right;
+            ngx_shmtx_unlock(&shpool->mutex);
 
-        } while (node != sentinel && hash == node->key);
+            ngx_log_error(lzcf->log_level, r->connection->log, 0,
+                          "limiting connections by zone \"%V\"",
+                          &lzcf->shm_zone->shm.name);
 
-        break;
+            return NGX_HTTP_SERVICE_UNAVAILABLE;
+        }
+
+        node = (rc < 0) ? node->left : node->right;
     }
 
     n = offsetof(ngx_rbtree_node_t, color)
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -161,8 +161,8 @@ static ngx_http_module_t  ngx_http_log_m
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_log_create_loc_conf,          /* create location configration */
-    ngx_http_log_merge_loc_conf            /* merge location configration */
+    ngx_http_log_create_loc_conf,          /* create location configuration */
+    ngx_http_log_merge_loc_conf            /* merge location configuration */
 };
 
 
@@ -375,10 +375,10 @@ ngx_http_log_script_write(ngx_http_reque
 
     if (!r->root_tested) {
 
-        /* test root directory existance */
+        /* test root directory existence */
 
         if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
-            /* simulate successfull logging */
+            /* simulate successful logging */
             return len;
         }
 
@@ -399,14 +399,14 @@ ngx_http_log_script_write(ngx_http_reque
             != NGX_OK)
         {
             if (of.err == 0) {
-                /* simulate successfull logging */
+                /* simulate successful logging */
                 return len;
             }
 
             ngx_log_error(NGX_LOG_ERR, r->connection->log, of.err,
                           "testing \"%s\" existence failed", path.data);
 
-            /* simulate successfull logging */
+            /* simulate successful logging */
             return len;
         }
 
@@ -414,7 +414,7 @@ ngx_http_log_script_write(ngx_http_reque
             ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ENOTDIR,
                           "testing \"%s\" existence failed", path.data);
 
-            /* simulate successfull logging */
+            /* simulate successful logging */
             return len;
         }
     }
@@ -423,7 +423,7 @@ ngx_http_log_script_write(ngx_http_reque
                             script->values->elts)
         == NULL)
     {
-        /* simulate successfull logging */
+        /* simulate successful logging */
         return len;
     }
 
@@ -447,7 +447,7 @@ ngx_http_log_script_write(ngx_http_reque
     {
         ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                       "%s \"%s\" failed", of.failed, log.data);
-        /* simulate successfull logging */
+        /* simulate successful logging */
         return len;
     }
 
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -115,8 +115,8 @@ static ngx_http_module_t  ngx_http_memca
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_memcached_create_loc_conf,    /* create location configration */
-    ngx_http_memcached_merge_loc_conf      /* merge location configration */
+    ngx_http_memcached_create_loc_conf,    /* create location configuration */
+    ngx_http_memcached_merge_loc_conf      /* merge location configuration */
 };
 
 
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -458,8 +458,8 @@ static ngx_http_module_t  ngx_http_proxy
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_proxy_create_loc_conf,        /* create location configration */
-    ngx_http_proxy_merge_loc_conf          /* merge location configration */
+    ngx_http_proxy_create_loc_conf,        /* create location configuration */
+    ngx_http_proxy_merge_loc_conf          /* merge location configuration */
 };
 
 
@@ -2496,6 +2496,8 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, 
         return NGX_CONF_OK;
     }
 
+    plcf->redirect = 1;
+
     value = cf->args->elts;
 
     if (cf->args->nelts == 2) {
--- a/src/http/modules/ngx_http_random_index_module.c
+++ b/src/http/modules/ngx_http_random_index_module.c
@@ -49,8 +49,8 @@ static ngx_http_module_t  ngx_http_rando
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_random_index_create_loc_conf, /* create location configration */
-    ngx_http_random_index_merge_loc_conf   /* merge location configration */
+    ngx_http_random_index_create_loc_conf, /* create location configuration */
+    ngx_http_random_index_merge_loc_conf   /* merge location configuration */
 };
 
 
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -595,15 +595,8 @@ ngx_http_range_test_overlapped(ngx_http_
     buf = in->buf;
 
     if (!buf->last_buf) {
-
-        if (buf->in_file) {
-            start = buf->file_pos + ctx->offset;
-            last = buf->file_last + ctx->offset;
-
-        } else {
-            start = buf->pos - buf->start + ctx->offset;
-            last = buf->last - buf->start + ctx->offset;
-        }
+        start = ctx->offset;
+        last = ctx->offset + ngx_buf_size(buf);
 
         range = ctx->ranges.elts;
         for (i = 0; i < ctx->ranges.nelts; i++) {
@@ -716,7 +709,6 @@ static ngx_int_t
 ngx_http_range_multipart_body(ngx_http_request_t *r,
     ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
 {
-    off_t              body_start;
     ngx_buf_t         *b, *buf;
     ngx_uint_t         i;
     ngx_chain_t       *out, *hcl, *rcl, *dcl, **ll;
@@ -726,12 +718,6 @@ ngx_http_range_multipart_body(ngx_http_r
     buf = in->buf;
     range = ctx->ranges.elts;
 
-#if (NGX_HTTP_CACHE)
-    body_start = r->cached ? r->cache->body_start : 0;
-#else
-    body_start = 0;
-#endif
-
     for (i = 0; i < ctx->ranges.nelts; i++) {
 
         /*
@@ -792,13 +778,13 @@ ngx_http_range_multipart_body(ngx_http_r
         b->file = buf->file;
 
         if (buf->in_file) {
-            b->file_pos = body_start + range[i].start;
-            b->file_last = body_start + range[i].end;
+            b->file_pos = buf->file_pos + range[i].start;
+            b->file_last = buf->file_pos + range[i].end;
         }
 
         if (ngx_buf_in_memory(buf)) {
-            b->pos = buf->start + (size_t) range[i].start;
-            b->last = buf->start + (size_t) range[i].end;
+            b->pos = buf->pos + (size_t) range[i].start;
+            b->last = buf->pos + (size_t) range[i].end;
         }
 
         dcl = ngx_alloc_chain_link(r->pool);
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -112,8 +112,8 @@ static ngx_http_module_t  ngx_http_rewri
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_rewrite_create_loc_conf,      /* create location configration */
-    ngx_http_rewrite_merge_loc_conf        /* merge location configration */
+    ngx_http_rewrite_create_loc_conf,      /* create location configuration */
+    ngx_http_rewrite_merge_loc_conf        /* merge location configuration */
 };
 
 
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -166,8 +166,8 @@ static ngx_http_module_t  ngx_http_useri
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_userid_create_conf,           /* create location configration */
-    ngx_http_userid_merge_conf             /* merge location configration */
+    ngx_http_userid_create_conf,           /* create location configuration */
+    ngx_http_userid_merge_conf             /* merge location configuration */
 };
 
 
--- a/src/http/modules/perl/Makefile.PL
+++ b/src/http/modules/perl/Makefile.PL
@@ -25,7 +25,11 @@ WriteMakefile(
                          "-I ../../../../../$ENV{NGX_OBJS} " .
                          ($ENV{NGX_PCRE} =~ /^(YES|NO)/ ? "" :
                              ($ENV{NGX_PCRE} =~ m#^/# ? "-I $ENV{NGX_PCRE} " :
-                                  "-I ../../../../../$ENV{NGX_PCRE} ")),
+                                  "-I ../../../../../$ENV{NGX_PCRE} ")) .
+                         ($ENV{NGX_OPENSSL} =~ /^(YES|NO)/ ? "" :
+                             ($ENV{NGX_OPENSSL} =~ m#^/# ?
+                                  "-I $ENV{NGX_OPENSSL}/.openssl/include " :
+                      "-I ../../../../../$ENV{NGX_OPENSSL}/.openssl/include ")),
 
     depend => {
         'nginx.c'     =>
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -21,7 +21,9 @@ our @EXPORT = qw(
     HTTP_MOVED_PERMANENTLY
     HTTP_MOVED_TEMPORARILY
     HTTP_REDIRECT
+    HTTP_SEE_OTHER
     HTTP_NOT_MODIFIED
+    HTTP_TEMPORARY_REDIRECT
 
     HTTP_BAD_REQUEST
     HTTP_UNAUTHORIZED
@@ -48,7 +50,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '1.0.12';
+our $VERSION = '1.0.13';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
@@ -67,7 +69,9 @@ use constant HTTP_PARTIAL_CONTENT       
 use constant HTTP_MOVED_PERMANENTLY         => 301;
 use constant HTTP_MOVED_TEMPORARILY         => 302;
 use constant HTTP_REDIRECT                  => 302;
+use constant HTTP_SEE_OTHER                 => 303;
 use constant HTTP_NOT_MODIFIED              => 304;
+use constant HTTP_TEMPORARY_REDIRECT        => 307;
 
 use constant HTTP_BAD_REQUEST               => 400;
 use constant HTTP_UNAUTHORIZED              => 401;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1798,8 +1798,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);
@@ -2524,6 +2527,16 @@ ngx_http_named_location(ngx_http_request
     ngx_http_core_main_conf_t   *cmcf;
 
     r->main->count++;
+    r->uri_changes--;
+
+    if (r->uri_changes == 0) {
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                      "rewrite or internal redirection cycle "
+                      "while redirect to named location \"%V\"", name);
+
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_DONE;
+    }
 
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -673,21 +673,16 @@ ngx_http_file_cache_lookup(ngx_http_file
 
         /* node_key == node->key */
 
-        do {
-            fcn = (ngx_http_file_cache_node_t *) node;
+        fcn = (ngx_http_file_cache_node_t *) node;
 
-            rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
-                            NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
+        rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
+                        NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
 
-            if (rc == 0) {
-                return fcn;
-            }
+        if (rc == 0) {
+            return fcn;
+        }
 
-            node = (rc < 0) ? node->left : node->right;
-
-        } while (node != sentinel && node_key == node->key);
-
-        break;
+        node = (rc < 0) ? node->left : node->right;
     }
 
     /* not found */
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -71,12 +71,11 @@ static ngx_str_t ngx_http_status_lines[]
     ngx_string("302 Moved Temporarily"),
     ngx_string("303 See Other"),
     ngx_string("304 Not Modified"),
+    ngx_null_string,  /* "305 Use Proxy" */
+    ngx_null_string,  /* "306 unused" */
+    ngx_string("307 Temporary Redirect"),
 
-    /* ngx_null_string, */  /* "305 Use Proxy" */
-    /* ngx_null_string, */  /* "306 unused" */
-    /* ngx_null_string, */  /* "307 Temporary Redirect" */
-
-#define NGX_HTTP_LAST_3XX  305
+#define NGX_HTTP_LAST_3XX  308
 #define NGX_HTTP_OFF_4XX   (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
 
     ngx_string("400 Bad Request"),
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -242,7 +242,7 @@ ngx_http_parse_time(u_char *value, size_
         year -= 1;
     }
 
-    /* Gauss' formula for Grigorian days since March 1, 1 BC */
+    /* Gauss' formula for Gregorian days since March 1, 1 BC */
 
     time = (uint64_t) (
             /* days in years including leap years since March 1, 1 BC */
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2898,6 +2898,10 @@ ngx_http_post_action(ngx_http_request_t 
         return NGX_DECLINED;
     }
 
+    if (r->post_action && r->uri_changes == 0) {
+        return NGX_DECLINED;
+    }
+
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "post action: \"%V\"", &clcf->post_action);
 
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -75,6 +75,7 @@
 #define NGX_HTTP_MOVED_TEMPORARILY         302
 #define NGX_HTTP_SEE_OTHER                 303
 #define NGX_HTTP_NOT_MODIFIED              304
+#define NGX_HTTP_TEMPORARY_REDIRECT        307
 
 #define NGX_HTTP_BAD_REQUEST               400
 #define NGX_HTTP_UNAUTHORIZED              401
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -74,6 +74,14 @@ static char ngx_http_error_303_page[] =
 ;
 
 
+static char ngx_http_error_307_page[] =
+"<html>" CRLF
+"<head><title>307 Temporary Redirect</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>307 Temporary Redirect</h1></center>" CRLF
+;
+
+
 static char ngx_http_error_400_page[] =
 "<html>" CRLF
 "<head><title>400 Bad Request</title></head>" CRLF
@@ -294,16 +302,20 @@ static ngx_str_t ngx_http_error_pages[] 
 
     ngx_null_string,                     /* 201, 204 */
 
-#define NGX_HTTP_LAST_LEVEL_200  202
-#define NGX_HTTP_LEVEL_200       (NGX_HTTP_LAST_LEVEL_200 - 201)
+#define NGX_HTTP_LAST_2XX  202
+#define NGX_HTTP_OFF_3XX   (NGX_HTTP_LAST_2XX - 201)
 
     /* ngx_null_string, */               /* 300 */
     ngx_string(ngx_http_error_301_page),
     ngx_string(ngx_http_error_302_page),
     ngx_string(ngx_http_error_303_page),
+    ngx_null_string,                     /* 304 */
+    ngx_null_string,                     /* 305 */
+    ngx_null_string,                     /* 306 */
+    ngx_string(ngx_http_error_307_page),
 
-#define NGX_HTTP_LAST_LEVEL_300  304
-#define NGX_HTTP_LEVEL_300       (NGX_HTTP_LAST_LEVEL_300 - 301)
+#define NGX_HTTP_LAST_3XX  308
+#define NGX_HTTP_OFF_4XX   (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
 
     ngx_string(ngx_http_error_400_page),
     ngx_string(ngx_http_error_401_page),
@@ -323,8 +335,8 @@ static ngx_str_t ngx_http_error_pages[] 
     ngx_string(ngx_http_error_415_page),
     ngx_string(ngx_http_error_416_page),
 
-#define NGX_HTTP_LAST_LEVEL_400  417
-#define NGX_HTTP_LEVEL_400       (NGX_HTTP_LAST_LEVEL_400 - 400)
+#define NGX_HTTP_LAST_4XX  417
+#define NGX_HTTP_OFF_5XX   (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
 
     ngx_string(ngx_http_error_494_page), /* 494, request header too large */
     ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
@@ -342,7 +354,7 @@ static ngx_str_t ngx_http_error_pages[] 
     ngx_null_string,                     /* 506 */
     ngx_string(ngx_http_error_507_page)
 
-#define NGX_HTTP_LAST_LEVEL_500  508
+#define NGX_HTTP_LAST_5XX  508
 
 };
 
@@ -428,25 +440,22 @@ ngx_http_special_response_handler(ngx_ht
         err = 0;
 
     } else if (error >= NGX_HTTP_MOVED_PERMANENTLY
-               && error < NGX_HTTP_LAST_LEVEL_300)
+               && error < NGX_HTTP_LAST_3XX)
     {
         /* 3XX */
-        err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200;
+        err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_OFF_3XX;
 
     } else if (error >= NGX_HTTP_BAD_REQUEST
-               && error < NGX_HTTP_LAST_LEVEL_400)
+               && error < NGX_HTTP_LAST_4XX)
     {
         /* 4XX */
-        err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200
-                                           + NGX_HTTP_LEVEL_300;
+        err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_OFF_4XX;
 
     } else if (error >= NGX_HTTP_NGINX_CODES
-               && error < NGX_HTTP_LAST_LEVEL_500)
+               && error < NGX_HTTP_LAST_5XX)
     {
         /* 49X, 5XX */
-        err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_LEVEL_200
-                                           + NGX_HTTP_LEVEL_300
-                                           + NGX_HTTP_LEVEL_400;
+        err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_OFF_5XX;
         switch (error) {
             case NGX_HTTP_TO_HTTPS:
             case NGX_HTTPS_CERT_ERROR:
@@ -570,12 +579,11 @@ ngx_http_send_error_page(ngx_http_reques
         return NGX_ERROR;
     }
 
-    if (overwrite >= NGX_HTTP_MOVED_PERMANENTLY
-        && overwrite <= NGX_HTTP_SEE_OTHER)
+    if (overwrite != NGX_HTTP_MOVED_PERMANENTLY
+        && overwrite != NGX_HTTP_MOVED_TEMPORARILY
+        && overwrite != NGX_HTTP_SEE_OTHER
+        && overwrite != NGX_HTTP_TEMPORARY_REDIRECT)
     {
-        r->err_status = overwrite;
-
-    } else {
         r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
     }
 
@@ -595,7 +603,7 @@ ngx_http_send_error_page(ngx_http_reques
 
     return ngx_http_send_special_response(r, clcf, r->err_status
                                                    - NGX_HTTP_MOVED_PERMANENTLY
-                                                   + NGX_HTTP_LEVEL_200);
+                                                   + NGX_HTTP_OFF_3XX);
 }
 
 
@@ -626,7 +634,7 @@ ngx_http_send_special_response(ngx_http_
         if (clcf->msie_padding
             && (r->headers_in.msie || r->headers_in.chrome)
             && r->http_version >= NGX_HTTP_VERSION_10
-            && err >= NGX_HTTP_LEVEL_300)
+            && err >= NGX_HTTP_OFF_4XX)
         {
             r->headers_out.content_length_n +=
                                          sizeof(ngx_http_msie_padding) - 1;
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1561,7 +1561,7 @@ ngx_http_upstream_process_header(ngx_htt
 
         if (rc == NGX_AGAIN) {
 
-            if (u->buffer.pos == u->buffer.end) {
+            if (u->buffer.last == u->buffer.end) {
                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
                               "upstream sent too big header");
 
@@ -2263,7 +2263,7 @@ ngx_http_upstream_send_response(ngx_http
     }
 
     if (ngx_event_flags & NGX_USE_AIO_EVENT) {
-        /* the posted aio operation may currupt a shadow buffer */
+        /* the posted aio operation may corrupt a shadow buffer */
         p->single_buf = 1;
     }
 
@@ -2616,7 +2616,6 @@ ngx_http_upstream_process_upstream(ngx_h
 static void
 ngx_http_upstream_process_request(ngx_http_request_t *r)
 {
-    ngx_uint_t            del;
     ngx_temp_file_t      *tf;
     ngx_event_pipe_t     *p;
     ngx_http_upstream_t  *u;
@@ -2628,30 +2627,16 @@ ngx_http_upstream_process_request(ngx_ht
 
         if (u->store) {
 
-            del = p->upstream_error;
-
-            tf = u->pipe->temp_file;
-
             if (p->upstream_eof || p->upstream_done) {
 
+                tf = u->pipe->temp_file;
+
                 if (u->headers_in.status_n == NGX_HTTP_OK
                     && (u->headers_in.content_length_n == -1
                         || (u->headers_in.content_length_n == tf->offset)))
                 {
                     ngx_http_upstream_store(r, u);
-
-                } else {
-                    del = 1;
-                }
-            }
-
-            if (del && tf->file.fd != NGX_INVALID_FILE) {
-
-                if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
-
-                    ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
-                                  ngx_delete_file_n " \"%s\" failed",
-                                  u->pipe->temp_file->file.name.data);
+                    u->store = 0;
                 }
             }
         }
@@ -2994,6 +2979,18 @@ ngx_http_upstream_finalize_request(ngx_h
                        u->pipe->temp_file->file.fd);
     }
 
+    if (u->store && u->pipe && u->pipe->temp_file
+        && u->pipe->temp_file->file.fd != NGX_INVALID_FILE)
+    {
+        if (ngx_delete_file(u->pipe->temp_file->file.name.data)
+            == NGX_FILE_ERROR)
+        {
+            ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
+                          ngx_delete_file_n " \"%s\" failed",
+                          u->pipe->temp_file->file.name.data);
+        }
+    }
+
 #if (NGX_HTTP_CACHE)
 
     if (r->cache) {
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -428,7 +428,7 @@ ngx_http_get_flushed_variable(ngx_http_r
 
     v = &r->variables[index];
 
-    if (v->valid) {
+    if (v->valid || v->not_found) {
         if (!v->no_cacheable) {
             return v;
         }
--- a/src/mail/ngx_mail_pop3_handler.c
+++ b/src/mail/ngx_mail_pop3_handler.c
@@ -218,7 +218,7 @@ ngx_mail_pop3_auth_state(ngx_event_t *re
 
             break;
 
-        /* suppress warinings */
+        /* suppress warnings */
         case ngx_pop3_passwd:
             break;
 
--- a/src/os/unix/ngx_darwin_sendfile_chain.c
+++ b/src/os/unix/ngx_darwin_sendfile_chain.c
@@ -173,7 +173,7 @@ ngx_darwin_sendfile_chain(ngx_connection
 
         if (file && header.nelts == 0) {
 
-            /* create the tailer iovec and coalesce the neighbouring bufs */
+            /* create the trailer iovec and coalesce the neighbouring bufs */
 
             prev = NULL;
             iov = NULL;
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -159,7 +159,7 @@ ngx_int_t ngx_set_file_time(u_char *name
 #define ngx_is_exec(sb)          (((sb)->st_mode & S_IXUSR) == S_IXUSR)
 #define ngx_file_access(sb)      ((sb)->st_mode & 0777)
 #define ngx_file_size(sb)        (sb)->st_size
-#define ngx_file_fs_size(sb)     ((sb)->st_blocks * 512)
+#define ngx_file_fs_size(sb)     ngx_max((sb)->st_size, (sb)->st_blocks * 512)
 #define ngx_file_mtime(sb)       (sb)->st_mtime
 #define ngx_file_uniq(sb)        (sb)->st_ino
 
@@ -255,7 +255,8 @@ ngx_de_info(u_char *name, ngx_dir_t *dir
 
 #define ngx_de_access(dir)       (((dir)->info.st_mode) & 0777)
 #define ngx_de_size(dir)         (dir)->info.st_size
-#define ngx_de_fs_size(dir)      ((dir)->info.st_blocks * 512)
+#define ngx_de_fs_size(dir)                                                  \
+    ngx_max((dir)->info.st_size, (dir)->info.st_blocks * 512)
 #define ngx_de_mtime(dir)        (dir)->info.st_mtime
 
 
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -178,7 +178,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio
 
         if (file) {
 
-            /* create the tailer iovec and coalesce the neighbouring bufs */
+            /* create the trailer iovec and coalesce the neighbouring bufs */
 
             prev = NULL;
             iov = NULL;
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -47,7 +47,13 @@ ngx_os_init(ngx_log_t *log)
 
     for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
 
+#if (NGX_HAVE_SC_NPROCESSORS_ONLN)
     if (ngx_ncpu == 0) {
+        ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);
+    }
+#endif
+
+    if (ngx_ncpu < 1) {
         ngx_ncpu = 1;
     }
 
--- a/src/os/unix/ngx_user.c
+++ b/src/os/unix/ngx_user.c
@@ -67,7 +67,7 @@ ngx_libc_crypt(ngx_pool_t *pool, u_char 
 
 #if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
 
-    /* crypt() is a time consuming funtion, so we only try to lock */
+    /* crypt() is a time consuming function, so we only try to lock */
 
     if (ngx_mutex_trylock(ngx_crypt_mutex) != NGX_OK) {
         return NGX_AGAIN;