summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNGINX team <nginx@nginx.org>2012-02-29 14:54:20 +0000
committerJon Kolb <jon@b0g.us>2012-02-29 14:54:20 +0000
commit55ebd600fb4c3d0842a9d7ed29c7b8d3e56f848d (patch)
tree04f2471b3a7967b1c5809f6e024da8335f52c024
parent616d163c4ad4900518e06187809dab9d0dd6e2c9 (diff)
downloadnginx-55ebd600fb4c3d0842a9d7ed29c7b8d3e56f848d.tar.gz
Changes with nginx 1.1.16 29 Feb 2012v1.1.16
*) Change: the simultaneous subrequest limit has been raised to 200. *) Feature: the "from" parameter of the "disable_symlinks" directive. *) Feature: the "return" and "error_page" directives can be used to return 307 redirections. *) Bugfix: a segmentation fault might occur in a worker process if the "resolver" directive was used and there was no "error_log" directive specified at global level. Thanks to Roman Arutyunyan. *) Bugfix: a segmentation fault might occur in a worker process if the "proxy_http_version 1.1" or "fastcgi_keep_conn on" directives were used. *) Bugfix: memory leaks. Thanks to Lanshun Zhou. *) Bugfix: in the "disable_symlinks" directive. *) Bugfix: on ZFS filesystem disk cache size might be calculated incorrectly; the bug had appeared in 1.0.1. *) Bugfix: nginx could not be built by the icc 12.1 compiler. *) Bugfix: nginx could not be built by gcc on Solaris; the bug had appeared in 1.1.15.
-rw-r--r--CHANGES32
-rw-r--r--CHANGES.ru33
-rw-r--r--auto/cc/name10
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_open_file_cache.c116
-rw-r--r--src/core/ngx_open_file_cache.h2
-rw-r--r--src/core/ngx_resolver.c28
-rw-r--r--src/core/ngx_times.c2
-rw-r--r--src/event/ngx_event.h2
-rw-r--r--src/event/ngx_event_openssl.c74
-rw-r--r--src/event/ngx_event_pipe.c5
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c4
-rw-r--r--src/http/modules/ngx_http_flv_module.c7
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c7
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c4
-rw-r--r--src/http/modules/ngx_http_index_module.c18
-rw-r--r--src/http/modules/ngx_http_limit_conn_module.c23
-rw-r--r--src/http/modules/ngx_http_limit_req_module.c57
-rw-r--r--src/http/modules/ngx_http_log_module.c34
-rw-r--r--src/http/modules/ngx_http_memcached_module.c4
-rw-r--r--src/http/modules/ngx_http_mp4_module.c7
-rw-r--r--src/http/modules/ngx_http_proxy_module.c4
-rw-r--r--src/http/modules/ngx_http_random_index_module.c4
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c4
-rw-r--r--src/http/modules/ngx_http_static_module.c7
-rw-r--r--src/http/modules/ngx_http_userid_filter_module.c4
-rw-r--r--src/http/modules/perl/nginx.pm6
-rw-r--r--src/http/modules/perl/nginx.xs7
-rw-r--r--src/http/ngx_http_core_module.c186
-rw-r--r--src/http/ngx_http_core_module.h5
-rw-r--r--src/http/ngx_http_file_cache.c19
-rw-r--r--src/http/ngx_http_header_filter_module.c9
-rw-r--r--src/http/ngx_http_parse_time.c2
-rw-r--r--src/http/ngx_http_request.h3
-rw-r--r--src/http/ngx_http_script.c9
-rw-r--r--src/http/ngx_http_special_response.c54
-rw-r--r--src/http/ngx_http_upstream.c2
-rw-r--r--src/mail/ngx_mail_pop3_handler.c2
-rw-r--r--src/os/unix/ngx_darwin_sendfile_chain.c2
-rw-r--r--src/os/unix/ngx_files.h24
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c2
-rw-r--r--src/os/unix/ngx_process_cycle.c4
-rw-r--r--src/os/unix/ngx_user.c2
43 files changed, 540 insertions, 294 deletions
diff --git a/CHANGES b/CHANGES
index e460866ec..0f856e8c5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,36 @@
+Changes with nginx 1.1.16 29 Feb 2012
+
+ *) Change: the simultaneous subrequest limit has been raised to 200.
+
+ *) Feature: the "from" parameter of the "disable_symlinks" directive.
+
+ *) Feature: the "return" and "error_page" directives can be used to
+ return 307 redirections.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if the
+ "resolver" directive was used and there was no "error_log" directive
+ specified at global level.
+ Thanks to Roman Arutyunyan.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if the
+ "proxy_http_version 1.1" or "fastcgi_keep_conn on" directives were
+ used.
+
+ *) Bugfix: memory leaks.
+ Thanks to Lanshun Zhou.
+
+ *) Bugfix: in the "disable_symlinks" directive.
+
+ *) Bugfix: on ZFS filesystem disk cache size might be calculated
+ incorrectly; the bug had appeared in 1.0.1.
+
+ *) Bugfix: nginx could not be built by the icc 12.1 compiler.
+
+ *) Bugfix: nginx could not be built by gcc on Solaris; the bug had
+ appeared in 1.1.15.
+
+
Changes with nginx 1.1.15 15 Feb 2012
*) Feature: the "disable_symlinks" directive.
diff --git a/CHANGES.ru b/CHANGES.ru
index 9f71304c1..0dc5fc934 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,37 @@
+Изменения в nginx 1.1.16 29.02.2012
+
+ *) Изменение: ограничение на количество одновременных подзапросов
+ поднято до 200.
+
+ *) Добавление: параметр from в директиве disable_symlinks.
+
+ *) Добавление: директивы return и error_page теперь могут использоваться
+ для возврата перенаправлений с кодом 307.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если использовалась директива resolver и на глобальном уровне не была
+ задана директива error_log.
+ Спасибо Роману Арутюняну.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если использовались директивы "proxy_http_version 1.1" или
+ "fastcgi_keep_conn on".
+
+ *) Исправление: утечек памяти.
+ Спасибо Lanshun Zhou.
+
+ *) Исправление: в директиве disable_symlinks.
+
+ *) Исправление: при использовании ZFS размер кэша на диске мог считаться
+ некорректно; ошибка появилась в 1.0.1.
+
+ *) Исправление: nginx не собирался компилятором icc 12.1.
+
+ *) Исправление: nginx не собирался gcc на Solaris; ошибка появилась в
+ 1.1.15.
+
+
Изменения в nginx 1.1.15 15.02.2012
*) Добавление: директива disable_symlinks.
diff --git a/auto/cc/name b/auto/cc/name
index 598f879a0..7860c69e2 100644
--- 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 '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 'gcc version' >/dev/null 2>&1`; then
+ NGX_CC_NAME=gcc
+ echo " + using GNU 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"
diff --git a/src/core/nginx.h b/src/core/nginx.h
index a22b37732..fab6ce688 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1001015
-#define NGINX_VERSION "1.1.15"
+#define nginx_version 1001016
+#define NGINX_VERSION "1.1.16"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index c871f74b1..c44ac96b8 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -229,6 +229,7 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
&& now - file->created < of->valid
#if (NGX_HAVE_OPENAT)
&& of->disable_symlinks == file->disable_symlinks
+ && of->disable_symlinks_from == file->disable_symlinks_from
#endif
))
{
@@ -395,6 +396,7 @@ update:
file->err = of->err;
#if (NGX_HAVE_OPENAT)
file->disable_symlinks = of->disable_symlinks;
+ file->disable_symlinks_from = of->disable_symlinks_from;
#endif
if (of->err == 0) {
@@ -504,8 +506,8 @@ ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
fd = ngx_openat_file(at_fd, name, mode, create, access);
- if (fd == NGX_FILE_ERROR) {
- return NGX_FILE_ERROR;
+ if (fd == NGX_INVALID_FILE) {
+ return NGX_INVALID_FILE;
}
if (ngx_file_at_info(at_fd, name, &atfi, AT_SYMLINK_NOFOLLOW)
@@ -565,7 +567,6 @@ ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
u_char *p, *cp, *end;
ngx_fd_t at_fd;
ngx_str_t at_name;
- ngx_file_info_t fi;
if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
fd = ngx_open_file(name->data, mode, create, access);
@@ -582,22 +583,45 @@ ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
p = name->data;
end = p + name->len;
- at_fd = AT_FDCWD;
at_name = *name;
- if (p[0] == '/') {
- at_fd = ngx_openat_file(at_fd, "/",
- NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
- NGX_FILE_OPEN, 0);
+ if (of->disable_symlinks_from) {
+
+ cp = p + of->disable_symlinks_from;
+
+ *cp = '\0';
- if (at_fd == NGX_FILE_ERROR) {
+ at_fd = ngx_open_file(p, NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
+ NGX_FILE_OPEN, 0);
+
+ *cp = '/';
+
+ if (at_fd == NGX_INVALID_FILE) {
+ of->err = ngx_errno;
+ of->failed = ngx_open_file_n;
+ return NGX_INVALID_FILE;
+ }
+
+ at_name.len = of->disable_symlinks_from;
+ p = cp + 1;
+
+ } else if (*p == '/') {
+
+ at_fd = ngx_open_file("/",
+ NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
+ NGX_FILE_OPEN, 0);
+
+ if (at_fd == NGX_INVALID_FILE) {
of->err = ngx_errno;
of->failed = ngx_openat_file_n;
- return NGX_FILE_ERROR;
+ return NGX_INVALID_FILE;
}
at_name.len = 1;
p++;
+
+ } else {
+ at_fd = NGX_AT_FDCWD;
}
for ( ;; ) {
@@ -615,12 +639,12 @@ ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
fd = ngx_openat_file_owner(at_fd, p,
- NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
+ NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
NGX_FILE_OPEN, 0, log);
} else {
fd = ngx_openat_file(at_fd, p,
- NGX_FILE_RDONLY|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW,
+ NGX_FILE_SEARCH|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW,
NGX_FILE_OPEN, 0);
}
@@ -632,9 +656,9 @@ ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
goto failed;
}
- if (at_fd != AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
+ if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", at_name);
+ ngx_close_file_n " \"%V\" failed", &at_name);
}
p = cp + 1;
@@ -642,47 +666,34 @@ ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
at_name.len = cp - at_name.data;
}
- if (p == end && at_fd != AT_FDCWD) {
+ if (p == end) {
/*
- * If pathname ends with a trailing slash, check if last path
- * component is a directory; if not, fail with ENOTDIR as per
- * POSIX.
- *
- * We use separate check instead of O_DIRECTORY in the loop above,
- * as O_DIRECTORY doesn't work on FreeBSD 8.
+ * If pathname ends with a trailing slash, assume the last path
+ * component is a directory and reopen it with requested flags;
+ * if not, fail with ENOTDIR as per POSIX.
*
- * Note this returns already opened file descriptor, with different
- * mode/create/access. This is believed to be safe as we don't
- * use this codepath to create directories.
+ * We cannot rely on O_DIRECTORY in the loop above to check
+ * that the last path component is a directory because
+ * O_DIRECTORY doesn't work on FreeBSD 8. Fortunately, by
+ * reopening a directory, we don't depend on it at all.
*/
- if (ngx_fd_info(at_fd, &fi) == NGX_FILE_ERROR) {
- of->err = ngx_errno;
- of->failed = ngx_fd_info_n;
- fd = NGX_INVALID_FILE;
-
- goto failed;
- }
-
- if (ngx_is_dir(&fi)) {
- return at_fd;
- }
-
- of->err = ENOTDIR;
- of->failed = ngx_openat_file_n;
- fd = NGX_INVALID_FILE;
-
- goto failed;
+ fd = ngx_openat_file(at_fd, ".", mode, create, access);
+ goto done;
}
- if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
+ if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER
+ && !(create & (NGX_FILE_CREATE_OR_OPEN|NGX_FILE_TRUNCATE)))
+ {
fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log);
} else {
fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access);
}
+done:
+
if (fd == NGX_INVALID_FILE) {
of->err = ngx_errno;
of->failed = ngx_openat_file_n;
@@ -690,9 +701,9 @@ ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
failed:
- if (at_fd != AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
+ if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", at_name);
+ ngx_close_file_n " \"%V\" failed", &at_name);
}
return fd;
@@ -1131,20 +1142,15 @@ ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
/* hash == node->key */
- do {
- file = (ngx_cached_open_file_t *) node;
-
- rc = ngx_strcmp(name->data, file->name);
+ file = (ngx_cached_open_file_t *) node;
- if (rc == 0) {
- return file;
- }
+ rc = ngx_strcmp(name->data, file->name);
- node = (rc < 0) ? node->left : node->right;
-
- } while (node != sentinel && hash == node->key);
+ if (rc == 0) {
+ return file;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
return NULL;
diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h
index 0ff345318..d119c1296 100644
--- a/src/core/ngx_open_file_cache.h
+++ b/src/core/ngx_open_file_cache.h
@@ -33,6 +33,7 @@ typedef struct {
ngx_uint_t min_uses;
#if (NGX_HAVE_OPENAT)
+ size_t disable_symlinks_from;
unsigned disable_symlinks:2;
#endif
@@ -69,6 +70,7 @@ struct ngx_cached_open_file_s {
uint32_t uses;
#if (NGX_HAVE_OPENAT)
+ size_t disable_symlinks_from;
unsigned disable_symlinks:2;
#endif
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 5a0ade729..2e3047135 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -189,11 +189,6 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
uc->sockaddr = u.addrs->sockaddr;
uc->socklen = u.addrs->socklen;
uc->server = u.addrs->name;
-
- uc->log = cf->cycle->new_log;
- uc->log.handler = ngx_resolver_log_error;
- uc->log.data = uc;
- uc->log.action = "resolving";
}
return r;
@@ -876,6 +871,12 @@ ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
}
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;
}
@@ -1688,20 +1689,15 @@ ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
/* hash == node->key */
- do {
- rn = (ngx_resolver_node_t *) node;
-
- rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
+ rn = (ngx_resolver_node_t *) node;
- if (rc == 0) {
- return rn;
- }
+ rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
- node = (rc < 0) ? node->left : node->right;
-
- } while (node != sentinel && hash == node->key);
+ if (rc == 0) {
+ return rn;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
/* not found */
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 745a4bd1b..6a5808fe2 100644
--- 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;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index aa2183a22..8cc87ebff 100644
--- 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
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index f393334ad..6b9dba16b 100644
--- 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 *buf, size_t size)
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_t *ssl_conn, u_char *id, int len,
/* hash == node->key */
- do {
- sess_id = (ngx_ssl_sess_id_t *) node;
+ 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) {
+ rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
- if (sess_id->expire > ngx_time()) {
- ngx_memcpy(buf, sess_id->session, sess_id->len);
+ if (rc == 0) {
- ngx_shmtx_unlock(&shpool->mutex);
+ if (sess_id->expire > ngx_time()) {
+ ngx_memcpy(buf, sess_id->session, sess_id->len);
- p = buf;
- sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
+ ngx_shmtx_unlock(&shpool->mutex);
- return sess;
- }
+ p = buf;
+ sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
+
+ return sess;
+ }
- ngx_queue_remove(&sess_id->queue);
+ ngx_queue_remove(&sess_id->queue);
- ngx_rbtree_delete(&cache->session_rbtree, node);
+ ngx_rbtree_delete(&cache->session_rbtree, node);
- ngx_slab_free_locked(shpool, sess_id->session);
+ 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;
- }
+ ngx_slab_free_locked(shpool, sess_id);
- node = (rc < 0) ? node->left : node->right;
+ sess = NULL;
- } while (node != sentinel && hash == node->key);
+ goto done;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
done:
@@ -1908,31 +1903,26 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
/* hash == node->key */
- do {
- sess_id = (ngx_ssl_sess_id_t *) node;
+ sess_id = (ngx_ssl_sess_id_t *) node;
- rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
+ rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
- if (rc == 0) {
+ if (rc == 0) {
- ngx_queue_remove(&sess_id->queue);
+ ngx_queue_remove(&sess_id->queue);
- ngx_rbtree_delete(&cache->session_rbtree, node);
+ ngx_rbtree_delete(&cache->session_rbtree, node);
- ngx_slab_free_locked(shpool, sess_id->session);
+ 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;
+ ngx_slab_free_locked(shpool, sess_id);
- } while (node != sentinel && hash == node->key);
+ goto done;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
done:
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 62358ead1..c2c79837f 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -401,13 +401,14 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
if (cl->buf->last - cl->buf->pos >= p->length) {
+ p->free_raw_bufs = cl->next;
+
/* STUB */ cl->buf->num = p->num++;
if (p->input_filter(p, cl->buf) == NGX_ERROR) {
return NGX_ABORT;
}
- p->free_raw_bufs = cl->next;
ngx_free_chain(p->pool, cl);
}
}
@@ -968,7 +969,7 @@ ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b)
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;
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index 9b54d0cf9..450a48e50 100644
--- 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_autoindex_module_ctx = {
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 */
};
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 292e37013..719a01124 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -109,9 +109,10 @@ ngx_http_flv_handler(ngx_http_request_t *r)
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index 2fad280e9..46ce8f3f3 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -129,9 +129,10 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index ff33f1f78..e6cf3f423 100644
--- 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_t *r)
&& 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);
}
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 7d99c18e5..cfe4ba6cc 100644
--- 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_module_ctx = {
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 */
};
@@ -209,9 +209,10 @@ ngx_http_index_handler(ngx_http_request_t *r)
of.test_only = 1;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
@@ -307,9 +308,10 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
of.test_only = 1;
of.valid = clcf->open_file_cache_valid;
of.errors = clcf->open_file_cache_errors;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &dir, &of) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &dir, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/modules/ngx_http_limit_conn_module.c b/src/http/modules/ngx_http_limit_conn_module.c
index 6322fd682..c23c046ed 100644
--- a/src/http/modules/ngx_http_limit_conn_module.c
+++ b/src/http/modules/ngx_http_limit_conn_module.c
@@ -118,8 +118,8 @@ static ngx_http_module_t ngx_http_limit_conn_module_ctx = {
NULL, /* create server configuration */
NULL, /* merge server configuration */
- ngx_http_limit_conn_create_conf, /* create location configration */
- ngx_http_limit_conn_merge_conf /* merge location configration */
+ ngx_http_limit_conn_create_conf, /* create location configuration */
+ ngx_http_limit_conn_merge_conf /* merge location configuration */
};
@@ -325,20 +325,15 @@ ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree, ngx_http_variable_value_t *vv,
/* hash == node->key */
- do {
- lcn = (ngx_http_limit_conn_node_t *) &node->color;
-
- rc = ngx_memn2cmp(vv->data, lcn->data,
- (size_t) vv->len, (size_t) lcn->len);
- if (rc == 0) {
- return node;
- }
+ lcn = (ngx_http_limit_conn_node_t *) &node->color;
- node = (rc < 0) ? node->left : node->right;
-
- } while (node != sentinel && hash == node->key);
+ rc = ngx_memn2cmp(vv->data, lcn->data,
+ (size_t) vv->len, (size_t) lcn->len);
+ if (rc == 0) {
+ return node;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
return NULL;
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index e4d90a98f..18db71549 100644
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -121,8 +121,8 @@ static ngx_http_module_t ngx_http_limit_req_module_ctx = {
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 */
};
@@ -385,47 +385,42 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash,
/* 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);
+ if (rc == 0) {
+ ngx_queue_remove(&lr->queue);
+ ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
- ms = (ngx_msec_int_t) (now - lr->last);
-
- excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
-
- if (excess < 0) {
- excess = 0;
- }
-
- *ep = excess;
+ ms = (ngx_msec_int_t) (now - lr->last);
- if ((ngx_uint_t) excess > limit->burst) {
- return NGX_BUSY;
- }
+ excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
- if (account) {
- lr->excess = excess;
- lr->last = now;
- return NGX_OK;
- }
+ if (excess < 0) {
+ excess = 0;
+ }
- lr->count++;
+ *ep = excess;
- ctx->node = lr;
+ if ((ngx_uint_t) excess > limit->burst) {
+ return NGX_BUSY;
+ }
- return NGX_AGAIN;
+ if (account) {
+ lr->excess = excess;
+ lr->last = now;
+ return NGX_OK;
}
- node = (rc < 0) ? node->left : node->right;
+ lr->count++;
- } while (node != sentinel && hash == node->key);
+ ctx->node = lr;
+
+ return NGX_AGAIN;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
*ep = 0;
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index da3b33c96..2452f23b3 100644
--- 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_module_ctx = {
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 */
};
@@ -377,10 +377,10 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
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;
}
@@ -394,22 +394,24 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
of.test_only = 1;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ /* simulate successful logging */
+ return len;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= 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;
}
@@ -417,7 +419,7 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
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;
}
}
@@ -426,7 +428,7 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
script->values->elts)
== NULL)
{
- /* simulate successfull logging */
+ /* simulate successful logging */
return len;
}
@@ -444,16 +446,18 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
of.valid = llcf->open_file_cache_valid;
of.min_uses = llcf->open_file_cache_min_uses;
of.directio = NGX_OPEN_FILE_DIRECTIO_OFF;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &log, &of) != NGX_OK) {
+ /* simulate successful logging */
+ return len;
+ }
if (ngx_open_cached_file(llcf->open_file_cache, &log, &of, r->pool)
!= NGX_OK)
{
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;
}
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index be45d4eeb..5077ded9a 100644
--- 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_memcached_module_ctx = {
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 */
};
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index f63b2bc56..384125a03 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -440,9 +440,10 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index f2bff3d3d..678c70e77 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -530,8 +530,8 @@ static ngx_http_module_t ngx_http_proxy_module_ctx = {
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 */
};
diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c
index 67f34f739..b0f0e0809 100644
--- 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_random_index_module_ctx = {
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 */
};
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 98da67f27..74d26e524 100644
--- 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_rewrite_module_ctx = {
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 */
};
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index f4904fc00..9d77e43b1 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -94,9 +94,10 @@ ngx_http_static_handler(ngx_http_request_t *r)
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index 8713dd629..1487c091e 100644
--- 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_userid_filter_module_ctx = {
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 */
};
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index b671c2dd0..b6fbdfd45 100644
--- 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.1.15';
+our $VERSION = '1.1.16';
require XSLoader;
XSLoader::load('nginx', $VERSION);
@@ -67,7 +69,9 @@ use constant HTTP_PARTIAL_CONTENT => 206;
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;
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 8def03eb1..ecd11ffbc 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -662,9 +662,10 @@ sendfile(r, filename, offset = -1, bytes = 0)
of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ XSRETURN_EMPTY;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 35b538b6e..0dbe8b01d 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -76,6 +76,10 @@ static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#endif
+#if (NGX_HAVE_OPENAT)
+static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+#endif
static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
@@ -187,18 +191,6 @@ static ngx_str_t ngx_http_gzip_private = ngx_string("private");
#endif
-#if (NGX_HAVE_OPENAT)
-
-static ngx_conf_enum_t ngx_http_core_disable_symlinks[] = {
- { ngx_string("off"), NGX_DISABLE_SYMLINKS_OFF },
- { ngx_string("if_not_owner"), NGX_DISABLE_SYMLINKS_NOTOWNER },
- { ngx_string("on"), NGX_DISABLE_SYMLINKS_ON },
- { ngx_null_string, 0 }
-};
-
-#endif
-
-
static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("variables_hash_max_size"),
@@ -779,11 +771,11 @@ static ngx_command_t ngx_http_core_commands[] = {
#if (NGX_HAVE_OPENAT)
{ ngx_string("disable_symlinks"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
+ ngx_http_disable_symlinks,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, disable_symlinks),
- &ngx_http_core_disable_symlinks },
+ 0,
+ NULL },
#endif
@@ -1320,9 +1312,11 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
of.test_only = 1;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_OK;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
@@ -1824,8 +1818,11 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (status >= NGX_HTTP_MOVED_PERMANENTLY && status <= NGX_HTTP_SEE_OTHER) {
-
+ if (status == NGX_HTTP_MOVED_PERMANENTLY
+ || status == NGX_HTTP_MOVED_TEMPORARILY
+ || status == NGX_HTTP_SEE_OTHER
+ || status == NGX_HTTP_TEMPORARY_REDIRECT)
+ {
ngx_http_clear_location(r);
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
@@ -2642,6 +2639,56 @@ ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
}
+ngx_int_t
+ngx_http_set_disable_symlinks(ngx_http_request_t *r,
+ ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of)
+{
+#if (NGX_HAVE_OPENAT)
+ u_char *p;
+ ngx_str_t from;
+
+ of->disable_symlinks = clcf->disable_symlinks;
+
+ if (clcf->disable_symlinks_from == NULL) {
+ return NGX_OK;
+ }
+
+ if (ngx_http_complex_value(r, clcf->disable_symlinks_from, &from)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ if (from.len == 0
+ || from.len > path->len
+ || ngx_memcmp(path->data, from.data, from.len) != 0)
+ {
+ return NGX_OK;
+ }
+
+ if (from.len == path->len) {
+ of->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
+ return NGX_OK;
+ }
+
+ p = path->data + from.len;
+
+ if (*p == '/') {
+ of->disable_symlinks_from = from.len;
+ return NGX_OK;
+ }
+
+ p--;
+
+ if (*p == '/') {
+ of->disable_symlinks_from = from.len - 1;
+ }
+#endif
+
+ return NGX_OK;
+}
+
+
static char *
ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{
@@ -3372,6 +3419,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HAVE_OPENAT)
clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
+ clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR;
#endif
return clcf;
@@ -3656,6 +3704,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
#if (NGX_HAVE_OPENAT)
ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
NGX_DISABLE_SYMLINKS_OFF);
+ ngx_conf_merge_ptr_value(conf->disable_symlinks_from,
+ prev->disable_symlinks_from, NULL);
#endif
return NGX_CONF_OK;
@@ -4791,6 +4841,100 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#endif
+#if (NGX_HAVE_OPENAT)
+
+static char *
+ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_core_loc_conf_t *clcf = conf;
+
+ ngx_str_t *value;
+ ngx_uint_t i;
+ ngx_http_compile_complex_value_t ccv;
+
+ if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+ clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "if_not_owner") == 0) {
+ clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER;
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "on") == 0) {
+ clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON;
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "from=", 5) == 0) {
+ value[i].len -= 5;
+ value[i].data += 5;
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[i];
+ ccv.complex_value = ngx_palloc(cf->pool,
+ sizeof(ngx_http_complex_value_t));
+ if (ccv.complex_value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ clcf->disable_symlinks_from = ccv.complex_value;
+
+ continue;
+ }
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"%V\" must have \"off\", \"on\" "
+ "or \"if_not_owner\" parameter",
+ &cmd->name);
+ return NGX_CONF_ERROR;
+ }
+
+ if (cf->args->nelts == 2) {
+ clcf->disable_symlinks_from = NULL;
+ return NGX_CONF_OK;
+ }
+
+ if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "duplicate parameters \"%V %V\"",
+ &value[1], &value[2]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"from=\" cannot be used with \"off\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+#endif
+
+
static char *
ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 3d6408a1e..bfa0b419e 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -406,6 +406,7 @@ struct ngx_http_core_loc_conf_s {
#if (NGX_HAVE_OPENAT)
ngx_uint_t disable_symlinks; /* disable_symlinks */
+ ngx_http_complex_value_t *disable_symlinks_from;
#endif
ngx_array_t *error_pages; /* error_page */
@@ -509,6 +510,10 @@ ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
+ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
+ ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of);
+
+
extern ngx_module_t ngx_http_core_module;
extern ngx_uint_t ngx_http_max_module;
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index eb1e99015..bd6cebadd 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -799,21 +799,16 @@ ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key)
/* 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;
- }
-
- node = (rc < 0) ? node->left : node->right;
-
- } while (node != sentinel && node_key == node->key);
+ if (rc == 0) {
+ return fcn;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
/* not found */
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 1d8fee9d7..8a6080f60 100644
--- 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"),
diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c
index 7d3aeaeff..3801df2fd 100644
--- 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_t len)
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 */
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 108dba92d..70ca6097e 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -10,7 +10,7 @@
#define NGX_HTTP_MAX_URI_CHANGES 10
-#define NGX_HTTP_MAX_SUBREQUESTS 50
+#define NGX_HTTP_MAX_SUBREQUESTS 200
/* must be 2^n */
#define NGX_HTTP_LC_HEADER_LEN 32
@@ -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
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index a8f193a32..ce290f4ef 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1505,9 +1505,12 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
of.test_only = 1;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
-#if (NGX_HAVE_OPENAT)
- of.disable_symlinks = clcf->disable_symlinks;
-#endif
+
+ if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
+ e->ip = ngx_http_script_exit;
+ e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return;
+ }
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index a07ebe28d..77b3dd13f 100644
--- 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_http_request_t *r, ngx_int_t error)
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_request_t *r, ngx_http_err_page_t *err_page)
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_request_t *r, ngx_http_err_page_t *err_page)
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_request_t *r,
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;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 4504d9823..7e368c1c1 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2293,7 +2293,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
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;
}
diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c
index 0a073288d..51bc257a5 100644
--- 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 *rev)
break;
- /* suppress warinings */
+ /* suppress warnings */
case ngx_pop3_passwd:
break;
diff --git a/src/os/unix/ngx_darwin_sendfile_chain.c b/src/os/unix/ngx_darwin_sendfile_chain.c
index c86976549..ec247d21b 100644
--- 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_t *c, ngx_chain_t *in, off_t limit)
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;
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 1526f9b77..ffe732c47 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -78,8 +78,25 @@ typedef struct {
#if (NGX_HAVE_OPENAT)
#define NGX_FILE_NOFOLLOW O_NOFOLLOW
+
+#if defined(O_DIRECTORY)
+#define NGX_FILE_DIRECTORY O_DIRECTORY
+#else
+#define NGX_FILE_DIRECTORY 0
#endif
+#if defined(O_SEARCH)
+#define NGX_FILE_SEARCH O_SEARCH|NGX_FILE_DIRECTORY
+
+#elif defined(O_EXEC)
+#define NGX_FILE_SEARCH O_EXEC|NGX_FILE_DIRECTORY
+
+#else
+#define NGX_FILE_SEARCH O_RDONLY|NGX_FILE_DIRECTORY
+#endif
+
+#endif /* NGX_HAVE_OPENAT */
+
#define NGX_FILE_DEFAULT_ACCESS 0644
#define NGX_FILE_OWNER_ACCESS 0600
@@ -163,7 +180,7 @@ ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
#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
@@ -259,7 +276,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
@@ -340,6 +358,8 @@ size_t ngx_fs_bsize(u_char *name);
#define ngx_file_at_info_n "fstatat()"
+#define NGX_AT_FDCWD (ngx_fd_t) AT_FDCWD
+
#endif
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index 610697d77..26b326705 100644
--- 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_connection_t *c, ngx_chain_t *in, off_t limit)
if (file) {
- /* create the tailer iovec and coalesce the neighbouring bufs */
+ /* create the trailer iovec and coalesce the neighbouring bufs */
prev = NULL;
iov = NULL;
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 080d40c1e..2b6f4c72a 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -250,6 +250,10 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_JUST_RESPAWN);
ngx_start_cache_manager_processes(cycle, 1);
+
+ /* allow new processes to start */
+ ngx_msleep(100);
+
live = 1;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
diff --git a/src/os/unix/ngx_user.c b/src/os/unix/ngx_user.c
index cb452e62b..27f990e83 100644
--- 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 *key, u_char *salt, u_char **encrypted)
#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;