summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornginx <nginx@nginx.org>2014-09-16 14:45:43 +0000
committerJon Kolb <kolbyjack@gmail.com>2014-09-16 14:45:43 +0000
commitbb8c0683da773566e09797ef8a4ee00ad1e0f956 (patch)
tree5e2b511fa7d6f189171a65220d502d88f065d59d
parent1176952193ccf47078dc84b8494d0496ad1ac4a2 (diff)
downloadnginx-bb8c0683da773566e09797ef8a4ee00ad1e0f956.tar.gz
Changes with nginx 1.7.5 16 Sep 2014v1.7.5
*) Security: it was possible to reuse SSL sessions in unrelated contexts if a shared SSL session cache or the same TLS session ticket key was used for multiple "server" blocks (CVE-2014-3616). Thanks to Antoine Delignat-Lavaud. *) Change: now the "stub_status" directive does not require a parameter. *) Feature: the "always" parameter of the "add_header" directive. *) Feature: the "proxy_next_upstream_tries", "proxy_next_upstream_timeout", "fastcgi_next_upstream_tries", "fastcgi_next_upstream_timeout", "memcached_next_upstream_tries", "memcached_next_upstream_timeout", "scgi_next_upstream_tries", "scgi_next_upstream_timeout", "uwsgi_next_upstream_tries", and "uwsgi_next_upstream_timeout" directives. *) Bugfix: in the "if" parameter of the "access_log" directive. *) Bugfix: in the ngx_http_perl_module. Thanks to Piotr Sikora. *) Bugfix: the "listen" directive of the mail proxy module did not allow to specify more than two parameters. *) Bugfix: the "sub_filter" directive did not work with a string to replace consisting of a single character. *) Bugfix: requests might hang if resolver was used and a timeout occurred during a DNS request. *) Bugfix: in the ngx_http_spdy_module when using with AIO. *) Bugfix: a segmentation fault might occur in a worker process if the "set" directive was used to change the "$http_...", "$sent_http_...", or "$upstream_http_..." variables. *) Bugfix: in memory allocation error handling. Thanks to Markus Linnala and Feng Gu.
-rw-r--r--CHANGES42
-rw-r--r--CHANGES.ru45
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_connection.c25
-rw-r--r--src/core/ngx_regex.c14
-rw-r--r--src/core/ngx_resolver.c35
-rw-r--r--src/event/modules/ngx_devpoll_module.c31
-rw-r--r--src/event/modules/ngx_epoll_module.c29
-rw-r--r--src/event/modules/ngx_eventport_module.c31
-rw-r--r--src/event/modules/ngx_kqueue_module.c32
-rw-r--r--src/event/modules/ngx_poll_module.c54
-rw-r--r--src/event/modules/ngx_rtsig_module.c40
-rw-r--r--src/event/modules/ngx_select_module.c18
-rw-r--r--src/event/modules/ngx_win32_select_module.c14
-rw-r--r--src/event/ngx_event.c32
-rw-r--r--src/event/ngx_event.h36
-rw-r--r--src/event/ngx_event_accept.c7
-rw-r--r--src/event/ngx_event_connect.c11
-rw-r--r--src/event/ngx_event_connect.h1
-rw-r--r--src/event/ngx_event_mutex.c2
-rw-r--r--src/event/ngx_event_openssl.c115
-rw-r--r--src/event/ngx_event_posted.c152
-rw-r--r--src/event/ngx_event_posted.h45
-rw-r--r--src/event/ngx_event_timer.c30
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c27
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c54
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c1
-rw-r--r--src/http/modules/ngx_http_log_module.c58
-rw-r--r--src/http/modules/ngx_http_memcached_module.c24
-rw-r--r--src/http/modules/ngx_http_mp4_module.c2
-rw-r--r--src/http/modules/ngx_http_proxy_module.c22
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c6
-rw-r--r--src/http/modules/ngx_http_scgi_module.c30
-rw-r--r--src/http/modules/ngx_http_stub_status_module.c2
-rw-r--r--src/http/modules/ngx_http_sub_filter_module.c8
-rw-r--r--src/http/modules/ngx_http_upstream_keepalive_module.c21
-rw-r--r--src/http/modules/ngx_http_upstream_least_conn_module.c5
-rw-r--r--src/http/modules/ngx_http_uwsgi_module.c30
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c3
-rw-r--r--src/http/ngx_http_core_module.c1
-rw-r--r--src/http/ngx_http_core_module.h2
-rw-r--r--src/http/ngx_http_file_cache.c4
-rw-r--r--src/http/ngx_http_request.c6
-rw-r--r--src/http/ngx_http_spdy.c4
-rw-r--r--src/http/ngx_http_spdy_filter_module.c5
-rw-r--r--src/http/ngx_http_upstream.c39
-rw-r--r--src/http/ngx_http_upstream.h2
-rw-r--r--src/http/ngx_http_upstream_round_robin.c13
-rw-r--r--src/http/ngx_http_variables.c7
-rw-r--r--src/mail/ngx_mail.c3
-rw-r--r--src/mail/ngx_mail_core_module.c2
-rw-r--r--src/mail/ngx_mail_handler.c2
-rw-r--r--src/os/unix/ngx_channel.c7
-rw-r--r--src/os/unix/ngx_posix_init.c4
-rw-r--r--src/os/unix/ngx_process_cycle.c9
-rw-r--r--src/os/unix/ngx_setproctitle.h4
56 files changed, 628 insertions, 624 deletions
diff --git a/CHANGES b/CHANGES
index 5ff1c201d..ac1fac018 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,46 @@
+Changes with nginx 1.7.5 16 Sep 2014
+
+ *) Security: it was possible to reuse SSL sessions in unrelated contexts
+ if a shared SSL session cache or the same TLS session ticket key was
+ used for multiple "server" blocks (CVE-2014-3616).
+ Thanks to Antoine Delignat-Lavaud.
+
+ *) Change: now the "stub_status" directive does not require a parameter.
+
+ *) Feature: the "always" parameter of the "add_header" directive.
+
+ *) Feature: the "proxy_next_upstream_tries",
+ "proxy_next_upstream_timeout", "fastcgi_next_upstream_tries",
+ "fastcgi_next_upstream_timeout", "memcached_next_upstream_tries",
+ "memcached_next_upstream_timeout", "scgi_next_upstream_tries",
+ "scgi_next_upstream_timeout", "uwsgi_next_upstream_tries", and
+ "uwsgi_next_upstream_timeout" directives.
+
+ *) Bugfix: in the "if" parameter of the "access_log" directive.
+
+ *) Bugfix: in the ngx_http_perl_module.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: the "listen" directive of the mail proxy module did not allow
+ to specify more than two parameters.
+
+ *) Bugfix: the "sub_filter" directive did not work with a string to
+ replace consisting of a single character.
+
+ *) Bugfix: requests might hang if resolver was used and a timeout
+ occurred during a DNS request.
+
+ *) Bugfix: in the ngx_http_spdy_module when using with AIO.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if the
+ "set" directive was used to change the "$http_...", "$sent_http_...",
+ or "$upstream_http_..." variables.
+
+ *) Bugfix: in memory allocation error handling.
+ Thanks to Markus Linnala and Feng Gu.
+
+
Changes with nginx 1.7.4 05 Aug 2014
*) Security: pipelined commands were not discarded after STARTTLS
diff --git a/CHANGES.ru b/CHANGES.ru
index 720180c01..dcdab4e0a 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,49 @@
+Изменения в nginx 1.7.5 16.09.2014
+
+ *) Безопасность: при использовании общего для нескольких блоков server
+ разделяемого кэша SSL-сессий или общего ключа для шифрования TLS
+ session tickets было возможно повторно использовать SSL-сессию в
+ контексте другого блока server (CVE-2014-3616).
+ Спасибо Antoine Delignat-Lavaud.
+
+ *) Изменение: директиву stub_status теперь можно указывать без
+ параметров.
+
+ *) Добавление: параметр always директивы add_header.
+
+ *) Добавление: директивы proxy_next_upstream_tries,
+ proxy_next_upstream_timeout, fastcgi_next_upstream_tries,
+ fastcgi_next_upstream_timeout, memcached_next_upstream_tries,
+ memcached_next_upstream_timeout, scgi_next_upstream_tries,
+ scgi_next_upstream_timeout, uwsgi_next_upstream_tries и
+ uwsgi_next_upstream_timeout.
+
+ *) Исправление: в параметре if директивы access_log.
+
+ *) Исправление: в модуле ngx_http_perl_module.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: директива listen почтового прокси-сервера не позволяла
+ указать более двух параметров.
+
+ *) Исправление: директива sub_filter не работала с заменяемой строкой из
+ одного символа.
+
+ *) Исправление: запросы могли зависать, если использовался resolver и в
+ процессе обращения к DNS-серверу происходил таймаут.
+
+ *) Исправление: в модуле ngx_http_spdy_module при использовании
+ совместно с AIO.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если с помощью директивы set изменялись переменные "$http_...",
+ "$sent_http_..." или "$upstream_http_...".
+
+ *) Исправление: в обработке ошибок выделения памяти.
+ Спасибо Markus Linnala и Feng Gu.
+
+
Изменения в nginx 1.7.4 05.08.2014
*) Безопасность: pipelined-команды не отбрасывались после команды
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 3cdf3ec6a..4524e005e 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1007004
-#define NGINX_VERSION "1.7.4"
+#define nginx_version 1007005
+#define NGINX_VERSION "1.7.5"
#define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 4c42ffc0d..b687d76b2 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -951,40 +951,21 @@ ngx_close_connection(ngx_connection_t *c)
* before we clean the connection
*/
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- if (c->read->prev) {
- ngx_delete_posted_event(c->read);
- }
-
- if (c->write->prev) {
- ngx_delete_posted_event(c->write);
- }
-
- c->read->closed = 1;
- c->write->closed = 1;
-
ngx_unlock(&c->lock);
- c->read->locked = 0;
- c->write->locked = 0;
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
-#else
+#endif
- if (c->read->prev) {
+ if (c->read->posted) {
ngx_delete_posted_event(c->read);
}
- if (c->write->prev) {
+ if (c->write->posted) {
ngx_delete_posted_event(c->write);
}
c->read->closed = 1;
c->write->closed = 1;
-#endif
-
ngx_reusable_connection(c, 0);
log_error = c->log_error;
diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
index 3771aab8e..30acca5fc 100644
--- a/src/core/ngx_regex.c
+++ b/src/core/ngx_regex.c
@@ -149,7 +149,7 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t));
if (rc->regex == NULL) {
- return NGX_ERROR;
+ goto nomem;
}
rc->regex->code = re;
@@ -159,7 +159,7 @@ ngx_regex_compile(ngx_regex_compile_t *rc)
if (ngx_pcre_studies != NULL) {
elt = ngx_list_push(ngx_pcre_studies);
if (elt == NULL) {
- return NGX_ERROR;
+ goto nomem;
}
elt->regex = rc->regex;
@@ -204,7 +204,15 @@ failed:
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
- rc->err.data;
- return NGX_OK;
+ return NGX_ERROR;
+
+nomem:
+
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
+ "regex \"%V\" compilation failed: no memory",
+ &rc->pattern)
+ - rc->err.data;
+ return NGX_ERROR;
}
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index dfe3dcb1e..a17793b13 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -417,7 +417,7 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
/* lock name mutex */
- if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
+ if (ctx->state == NGX_AGAIN) {
hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
@@ -664,7 +664,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
}
ctx->event->handler = ngx_resolver_timeout_handler;
- ctx->event->data = ctx;
+ ctx->event->data = rn;
ctx->event->log = r->log;
ctx->ident = -1;
@@ -857,7 +857,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
}
ctx->event->handler = ngx_resolver_timeout_handler;
- ctx->event->data = ctx;
+ ctx->event->data = rn;
ctx->event->log = r->log;
ctx->ident = -1;
@@ -949,7 +949,7 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
/* lock addr mutex */
- if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
+ if (ctx->state == NGX_AGAIN) {
switch (ctx->addr.sockaddr->sa_family) {
@@ -2790,13 +2790,21 @@ done:
static void
ngx_resolver_timeout_handler(ngx_event_t *ev)
{
- ngx_resolver_ctx_t *ctx;
+ ngx_resolver_ctx_t *ctx, *next;
+ ngx_resolver_node_t *rn;
- ctx = ev->data;
+ rn = ev->data;
+ ctx = rn->waiting;
+ rn->waiting = NULL;
+
+ do {
+ ctx->state = NGX_RESOLVE_TIMEDOUT;
+ next = ctx->next;
- ctx->state = NGX_RESOLVE_TIMEDOUT;
+ ctx->handler(ctx);
- ctx->handler(ctx);
+ ctx = next;
+ } while (ctx);
}
@@ -3074,17 +3082,6 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
-#if (NGX_THREADS)
-
- /* TODO: lock event when call completion handler */
-
- rev->lock = &c->lock;
- wev->lock = &c->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-
-#endif
-
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0,
"connect to %V, fd:%d #%uA", &uc->server, s, c->number);
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 0506103e6..5658e8620 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -344,7 +344,8 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_err_t err;
ngx_int_t i;
ngx_uint_t level, instance;
- ngx_event_t *rev, *wev, **queue;
+ ngx_event_t *rev, *wev;
+ ngx_queue_t *queue;
ngx_connection_t *c;
struct pollfd pfd;
struct dvpoll dvp;
@@ -404,8 +405,6 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
for (i = 0; i < events; i++) {
fd = event_list[i].fd;
@@ -495,19 +494,13 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
rev = c->read;
if ((revents & POLLIN) && rev->active) {
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
+ rev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
+ queue = rev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
- ngx_locked_post_event(rev, queue);
+ ngx_post_event(rev, queue);
} else {
instance = rev->instance;
@@ -523,16 +516,10 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
wev = c->write;
if ((revents & POLLOUT) && wev->active) {
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
+ wev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
+ ngx_post_event(wev, &ngx_posted_events);
} else {
wev->handler(wev);
@@ -540,8 +527,6 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
return NGX_OK;
}
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index a098c1c00..2674d382b 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -568,7 +568,8 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
ngx_int_t instance, i;
ngx_uint_t level;
ngx_err_t err;
- ngx_event_t *rev, *wev, **queue;
+ ngx_event_t *rev, *wev;
+ ngx_queue_t *queue;
ngx_connection_t *c;
/* NGX_TIMER_INFINITE == INFTIM */
@@ -612,8 +613,6 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
for (i = 0; i < events; i++) {
c = event_list[i].data.ptr;
@@ -674,18 +673,13 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
}
#endif
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
+ rev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
+ queue = rev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
- ngx_locked_post_event(rev, queue);
+ ngx_post_event(rev, queue);
} else {
rev->handler(rev);
@@ -708,15 +702,10 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
continue;
}
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
+ wev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
+ ngx_post_event(wev, &ngx_posted_events);
} else {
wev->handler(wev);
@@ -724,8 +713,6 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
return NGX_OK;
}
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index 5f9cf4e35..a9d8a6246 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -414,7 +414,8 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_err_t err;
ngx_int_t instance;
ngx_uint_t i, level;
- ngx_event_t *ev, *rev, *wev, **queue;
+ ngx_event_t *ev, *rev, *wev;
+ ngx_queue_t *queue;
ngx_connection_t *c;
struct timespec ts, *tp;
@@ -466,8 +467,6 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
for (i = 0; i < events; i++) {
if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
@@ -534,19 +533,13 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
wev->active = 0;
if (revents & POLLIN) {
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
+ rev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
+ queue = rev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
- ngx_locked_post_event(rev, queue);
+ ngx_post_event(rev, queue);
} else {
rev->handler(rev);
@@ -574,16 +567,10 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
if (revents & POLLOUT) {
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
+ wev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
+ ngx_post_event(wev, &ngx_posted_events);
} else {
wev->handler(wev);
@@ -600,8 +587,6 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
return NGX_OK;
}
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 30e456c4d..9e7a1bdb6 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -495,7 +495,8 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_int_t i, instance;
ngx_uint_t level;
ngx_err_t err;
- ngx_event_t *ev, **queue;
+ ngx_event_t *ev;
+ ngx_queue_t *queue;
struct timespec ts, *tp;
if (ngx_threaded) {
@@ -573,8 +574,6 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
for (i = 0; i < events; i++) {
ngx_kqueue_dump_event(cycle->log, &event_list[i]);
@@ -626,24 +625,6 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ev->active = 0;
}
-#if (NGX_THREADS)
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) {
- ev->posted_ready = 1;
- ev->posted_available = event_list[i].data;
-
- if (event_list[i].flags & EV_EOF) {
- ev->posted_eof = 1;
- ev->posted_errno = event_list[i].fflags;
- }
-
- ngx_locked_post_event(ev, &ngx_posted_events);
-
- continue;
- }
-
-#endif
-
ev->available = event_list[i].data;
if (event_list[i].flags & EV_EOF) {
@@ -674,9 +655,10 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
+ queue = ev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
+
+ ngx_post_event(ev, queue);
continue;
}
@@ -684,8 +666,6 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ev->handler(ev);
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
return NGX_OK;
}
diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c
index 4d4521845..bad1a7d2a 100644
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -22,7 +22,7 @@ static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf);
static struct pollfd *event_list;
-static ngx_int_t nevents;
+static ngx_uint_t nevents;
static ngx_str_t poll_name = ngx_string("poll");
@@ -198,7 +198,7 @@ ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
if (e == NULL || e->index == NGX_INVALID_INDEX) {
nevents--;
- if (ev->index < (ngx_uint_t) nevents) {
+ if (ev->index < nevents) {
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"index: copy event %ui to %i", nevents, ev->index);
@@ -212,11 +212,11 @@ ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
"unexpected last event");
} else {
- if (c->read->index == (ngx_uint_t) nevents) {
+ if (c->read->index == nevents) {
c->read->index = ev->index;
}
- if (c->write->index == (ngx_uint_t) nevents) {
+ if (c->write->index == nevents) {
c->write->index = ev->index;
}
}
@@ -240,9 +240,9 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
{
int ready, revents;
ngx_err_t err;
- ngx_int_t i, nready;
- ngx_uint_t found, level;
- ngx_event_t *ev, **queue;
+ ngx_uint_t i, found, level;
+ ngx_event_t *ev;
+ ngx_queue_t *queue;
ngx_connection_t *c;
/* NGX_TIMER_INFINITE == INFTIM */
@@ -251,7 +251,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
for (i = 0; i < nevents; i++) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll: %d: fd:%d ev:%04Xd",
+ "poll: %ui: fd:%d ev:%04Xd",
i, event_list[i].fd, event_list[i].events);
}
}
@@ -268,7 +268,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll ready %d of %d", ready, nevents);
+ "poll ready %d of %ui", ready, nevents);
if (err) {
if (err == NGX_EINTR) {
@@ -298,22 +298,18 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- nready = 0;
-
for (i = 0; i < nevents && ready; i++) {
revents = event_list[i].revents;
#if 1
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll: %d: fd:%d ev:%04Xd rev:%04Xd",
+ "poll: %ui: fd:%d ev:%04Xd rev:%04Xd",
i, event_list[i].fd, event_list[i].events, revents);
#else
if (revents) {
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll: %d: fd:%d ev:%04Xd rev:%04Xd",
+ "poll: %ui: fd:%d ev:%04Xd rev:%04Xd",
i, event_list[i].fd, event_list[i].events, revents);
}
#endif
@@ -375,31 +371,21 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
found = 1;
ev = c->read;
+ ev->ready = 1;
- if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) {
- ev->posted_ready = 1;
-
- } else {
- ev->ready = 1;
- }
+ queue = ev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
+ ngx_post_event(ev, queue);
}
if ((revents & POLLOUT) && c->write->active) {
found = 1;
- ev = c->write;
- if (flags & NGX_POST_THREAD_EVENTS) {
- ev->posted_ready = 1;
-
- } else {
- ev->ready = 1;
- }
+ ev = c->write;
+ ev->ready = 1;
- ngx_locked_post_event(ev, &ngx_posted_events);
+ ngx_post_event(ev, &ngx_posted_events);
}
if (found) {
@@ -408,13 +394,11 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
if (ready != 0) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events");
}
- return nready;
+ return NGX_OK;
}
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index b36230c76..9e31afa1c 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -307,7 +307,8 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
ngx_int_t instance;
ngx_err_t err;
siginfo_t si;
- ngx_event_t *rev, *wev, **queue;
+ ngx_event_t *rev, *wev;
+ ngx_queue_t *queue;
struct timespec ts, *tp;
struct sigaction sa;
ngx_connection_t *c;
@@ -404,10 +405,10 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
rev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
+ queue = rev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
- ngx_locked_post_event(rev, queue);
+ ngx_post_event(rev, queue);
} else {
rev->handler(rev);
@@ -421,7 +422,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
wev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
+ ngx_post_event(wev, &ngx_posted_events);
} else {
wev->handler(wev);
@@ -480,7 +481,8 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
size_t len;
ngx_err_t err;
ngx_uint_t tested, n, i;
- ngx_event_t *rev, *wev, **queue;
+ ngx_event_t *rev, *wev;
+ ngx_queue_t *queue;
ngx_connection_t *c;
ngx_rtsig_conf_t *rtscf;
@@ -554,8 +556,6 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
continue;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
for (i = 0; i < n; i++) {
c = cycle->files[overflow_list[i].fd];
@@ -573,18 +573,13 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
{
tested++;
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
+ rev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
+ queue = rev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
- ngx_locked_post_event(rev, queue);
+ ngx_post_event(rev, queue);
} else {
rev->handler(rev);
@@ -601,15 +596,10 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
{
tested++;
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
+ wev->ready = 1;
if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
+ ngx_post_event(wev, &ngx_posted_events);
} else {
wev->handler(wev);
@@ -617,8 +607,6 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
if (tested >= rtscf->overflow_test) {
if (ngx_linux_rtsig_max) {
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index 51690558e..fa2d55ae2 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -214,7 +214,8 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
int ready, nready;
ngx_err_t err;
ngx_uint_t i, found;
- ngx_event_t *ev, **queue;
+ ngx_event_t *ev;
+ ngx_queue_t *queue;
struct timeval tv, *tp;
ngx_connection_t *c;
@@ -227,7 +228,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "change max_fd: %d", max_fd);
+ "change max_fd: %i", max_fd);
}
#if (NGX_DEBUG)
@@ -240,7 +241,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "max_fd: %d", max_fd);
+ "max_fd: %i", max_fd);
}
#endif
@@ -305,8 +306,6 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
nready = 0;
for (i = 0; i < nevents; i++) {
@@ -332,16 +331,15 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
if (found) {
ev->ready = 1;
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
+ queue = ev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
+
+ ngx_post_event(ev, queue);
nready++;
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
if (ready != nready) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"select ready != events: %d:%d", ready, nready);
diff --git a/src/event/modules/ngx_win32_select_module.c b/src/event/modules/ngx_win32_select_module.c
index eb5382d4e..be87ded24 100644
--- a/src/event/modules/ngx_win32_select_module.c
+++ b/src/event/modules/ngx_win32_select_module.c
@@ -221,7 +221,8 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
int ready, nready;
ngx_err_t err;
ngx_uint_t i, found;
- ngx_event_t *ev, **queue;
+ ngx_event_t *ev;
+ ngx_queue_t *queue;
struct timeval tv, *tp;
ngx_connection_t *c;
@@ -296,8 +297,6 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
return NGX_ERROR;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
nready = 0;
for (i = 0; i < nevents; i++) {
@@ -323,16 +322,15 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
if (found) {
ev->ready = 1;
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
+ queue = ev->accept ? &ngx_posted_accept_events
+ : &ngx_posted_events;
+
+ ngx_post_event(ev, queue);
nready++;
}
}
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
if (ready != nready) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"select ready != events: %d:%d", ready, nready);
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index e2857f0c0..26c3b9716 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -252,9 +252,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"timer delta: %M", delta);
- if (ngx_posted_accept_events) {
- ngx_event_process_posted(cycle, &ngx_posted_accept_events);
- }
+ ngx_event_process_posted(cycle, &ngx_posted_accept_events);
if (ngx_accept_mutex_held) {
ngx_shmtx_unlock(&ngx_accept_mutex);
@@ -264,17 +262,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
ngx_event_expire_timers();
}
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted events %p", ngx_posted_events);
-
- if (ngx_posted_events) {
- if (ngx_threaded) {
- ngx_wakeup_worker_thread(cycle);
-
- } else {
- ngx_event_process_posted(cycle, &ngx_posted_events);
- }
- }
+ ngx_event_process_posted(cycle, &ngx_posted_events);
}
@@ -617,12 +605,8 @@ ngx_event_process_init(ngx_cycle_t *cycle)
#endif
-#if (NGX_THREADS)
- ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
- if (ngx_posted_events_mutex == NULL) {
- return NGX_ERROR;
- }
-#endif
+ ngx_queue_init(&ngx_posted_accept_events);
+ ngx_queue_init(&ngx_posted_events);
if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
return NGX_ERROR;
@@ -712,10 +696,6 @@ ngx_event_process_init(ngx_cycle_t *cycle)
for (i = 0; i < cycle->connection_n; i++) {
rev[i].closed = 1;
rev[i].instance = 1;
-#if (NGX_THREADS)
- rev[i].lock = &c[i].lock;
- rev[i].own_lock = &c[i].lock;
-#endif
}
cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
@@ -727,10 +707,6 @@ ngx_event_process_init(ngx_cycle_t *cycle)
wev = cycle->write_events;
for (i = 0; i < cycle->connection_n; i++) {
wev[i].closed = 1;
-#if (NGX_THREADS)
- wev[i].lock = &c[i].lock;
- wev[i].own_lock = &c[i].lock;
-#endif
}
i = cycle->connection_n;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 530c9486c..6531ec7ad 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -74,9 +74,7 @@ struct ngx_event_s {
/* the pending eof reported by kqueue, epoll or in aio chain operation */
unsigned pending_eof:1;
-#if !(NGX_THREADS)
- unsigned posted_ready:1;
-#endif
+ unsigned posted:1;
#if (NGX_WIN32)
/* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
@@ -129,40 +127,15 @@ struct ngx_event_s {
ngx_rbtree_node_t timer;
+ /* the posted queue */
+ ngx_queue_t queue;
+
unsigned closed:1;
/* to test on worker exit */
unsigned channel:1;
unsigned resolver:1;
-#if (NGX_THREADS)
-
- unsigned locked:1;
-
- unsigned posted_ready:1;
- unsigned posted_timedout:1;
- unsigned posted_eof:1;
-
-#if (NGX_HAVE_KQUEUE)
- /* the pending errno reported by kqueue */
- int posted_errno;
-#endif
-
-#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
- int posted_available;
-#else
- unsigned posted_available:1;
-#endif
-
- ngx_atomic_t *lock;
- ngx_atomic_t *own_lock;
-
-#endif
-
- /* the links of the posted queue */
- ngx_event_t *next;
- ngx_event_t **prev;
-
#if 0
@@ -519,7 +492,6 @@ extern ngx_atomic_t *ngx_stat_waiting;
#define NGX_UPDATE_TIME 1
#define NGX_POST_EVENTS 2
-#define NGX_POST_THREAD_EVENTS 4
extern sig_atomic_t ngx_event_timer_alarm;
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 575ee4bdb..6285baafb 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -262,13 +262,6 @@ ngx_event_accept(ngx_event_t *ev)
(void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
#endif
-#if (NGX_THREADS)
- rev->lock = &c->lock;
- wev->lock = &c->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-#endif
-
if (ls->addr_ntop) {
c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
if (c->addr_text.data == NULL) {
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index 5fcabcfd1..a09d2e5d7 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -104,17 +104,6 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
-#if (NGX_THREADS)
-
- /* TODO: lock event when call completion handler */
-
- rev->lock = pc->lock;
- wev->lock = pc->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-
-#endif
-
if (ngx_add_conn) {
if (ngx_add_conn(c) == NGX_ERROR) {
goto failed;
diff --git a/src/event/ngx_event_connect.h b/src/event/ngx_event_connect.h
index 951c24f41..e73825885 100644
--- a/src/event/ngx_event_connect.h
+++ b/src/event/ngx_event_connect.h
@@ -42,6 +42,7 @@ struct ngx_peer_connection_s {
ngx_str_t *name;
ngx_uint_t tries;
+ ngx_msec_t start_time;
ngx_event_get_peer_pt get;
ngx_event_free_peer_pt free;
diff --git a/src/event/ngx_event_mutex.c b/src/event/ngx_event_mutex.c
index 2bdfd5b4e..98efbb0d8 100644
--- a/src/event/ngx_event_mutex.c
+++ b/src/event/ngx_event_mutex.c
@@ -62,7 +62,7 @@ ngx_int_t ngx_event_mutex_unlock(ngx_event_mutex_t *m, ngx_log_t *log)
ev = m->events;
m->events = ev->next;
- ev->next = (ngx_event_t *) ngx_posted_events;
+ ev->next = ngx_posted_events;
ngx_posted_events = ev;
}
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index bb82143d3..975a8e001 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -33,6 +33,8 @@ static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
static void ngx_ssl_clear_error(ngx_log_t *log);
+static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl,
+ ngx_str_t *sess_ctx);
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
ngx_ssl_session_t *sess);
@@ -206,13 +208,23 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
/* client side options */
+#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
+#endif
+
+#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
+#endif
/* server side options */
+#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
+#endif
+
+#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
+#endif
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
/* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */
@@ -223,10 +235,17 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
#endif
+#ifdef SSL_OP_TLS_D5_BUG
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
+#endif
+
+#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
+#endif
+#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+#endif
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
@@ -1956,13 +1975,15 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
+ if (ngx_ssl_session_id_context(ssl, sess_ctx) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
return NGX_OK;
}
- SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
-
if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
/*
@@ -2019,6 +2040,96 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
}
+static ngx_int_t
+ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
+{
+ int n, i;
+ X509 *cert;
+ X509_NAME *name;
+ EVP_MD_CTX md;
+ unsigned int len;
+ STACK_OF(X509_NAME) *list;
+ u_char buf[EVP_MAX_MD_SIZE];
+
+ /*
+ * Session ID context is set based on the string provided,
+ * the server certificate, and the client CA list.
+ */
+
+ EVP_MD_CTX_init(&md);
+
+ if (EVP_DigestInit_ex(&md, EVP_sha1(), NULL) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "EVP_DigestInit_ex() failed");
+ goto failed;
+ }
+
+ if (EVP_DigestUpdate(&md, sess_ctx->data, sess_ctx->len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "EVP_DigestUpdate() failed");
+ goto failed;
+ }
+
+ cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
+
+ if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_digest() failed");
+ goto failed;
+ }
+
+ if (EVP_DigestUpdate(&md, buf, len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "EVP_DigestUpdate() failed");
+ goto failed;
+ }
+
+ list = SSL_CTX_get_client_CA_list(ssl->ctx);
+
+ if (list != NULL) {
+ n = sk_X509_NAME_num(list);
+
+ for (i = 0; i < n; i++) {
+ name = sk_X509_NAME_value(list, i);
+
+ if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_NAME_digest() failed");
+ goto failed;
+ }
+
+ if (EVP_DigestUpdate(&md, buf, len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "EVP_DigestUpdate() failed");
+ goto failed;
+ }
+ }
+ }
+
+ if (EVP_DigestFinal_ex(&md, buf, &len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "EVP_DigestUpdate() failed");
+ goto failed;
+ }
+
+ EVP_MD_CTX_cleanup(&md);
+
+ if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_set_session_id_context() failed");
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+
+failed:
+
+ EVP_MD_CTX_cleanup(&md);
+
+ return NGX_ERROR;
+}
+
+
ngx_int_t
ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
{
diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c
index e548145ed..d851f3d14 100644
--- a/src/event/ngx_event_posted.c
+++ b/src/event/ngx_event_posted.c
@@ -10,164 +10,26 @@
#include <ngx_event.h>
-ngx_thread_volatile ngx_event_t *ngx_posted_accept_events;
-ngx_thread_volatile ngx_event_t *ngx_posted_events;
-
-#if (NGX_THREADS)
-ngx_mutex_t *ngx_posted_events_mutex;
-#endif
+ngx_queue_t ngx_posted_accept_events;
+ngx_queue_t ngx_posted_events;
void
-ngx_event_process_posted(ngx_cycle_t *cycle,
- ngx_thread_volatile ngx_event_t **posted)
+ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted)
{
+ ngx_queue_t *q;
ngx_event_t *ev;
- for ( ;; ) {
+ while (!ngx_queue_empty(posted)) {
- ev = (ngx_event_t *) *posted;
+ q = ngx_queue_head(posted);
+ ev = ngx_queue_data(q, ngx_event_t, queue);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"posted event %p", ev);
- if (ev == NULL) {
- return;
- }
-
ngx_delete_posted_event(ev);
ev->handler(ev);
}
}
-
-
-#if (NGX_THREADS) && !(NGX_WIN32)
-
-void
-ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
-{
- ngx_int_t i;
-#if 0
- ngx_uint_t busy;
- ngx_event_t *ev;
-
- busy = 1;
-
- if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
- return;
- }
-
- for (ev = (ngx_event_t *) ngx_posted_events; ev; ev = ev->next) {
- if (*(ev->lock) == 0) {
- busy = 0;
- break;
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- if (busy) {
- return;
- }
-#endif
-
- for (i = 0; i < ngx_threads_n; i++) {
- if (ngx_threads[i].state == NGX_THREAD_FREE) {
- ngx_cond_signal(ngx_threads[i].cv);
- return;
- }
- }
-}
-
-
-ngx_int_t
-ngx_event_thread_process_posted(ngx_cycle_t *cycle)
-{
- ngx_event_t *ev;
-
- for ( ;; ) {
-
- ev = (ngx_event_t *) ngx_posted_events;
-
- for ( ;; ) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p", ev);
-
- if (ev == NULL) {
- return NGX_OK;
- }
-
- if (ngx_trylock(ev->lock) == 0) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p is busy", ev);
-
- ev = ev->next;
- continue;
- }
-
- if (ev->lock != ev->own_lock) {
- if (*(ev->own_lock)) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "the own lock of the posted event %p is busy", ev);
- ngx_unlock(ev->lock);
- ev = ev->next;
- continue;
- }
- *(ev->own_lock) = 1;
- }
-
- ngx_delete_posted_event(ev);
-
- ev->locked = 1;
-
- ev->ready |= ev->posted_ready;
- ev->timedout |= ev->posted_timedout;
- ev->pending_eof |= ev->posted_eof;
-#if (NGX_HAVE_KQUEUE)
- ev->kq_errno |= ev->posted_errno;
-#endif
- if (ev->posted_available) {
- ev->available = ev->posted_available;
- }
-
- ev->posted_ready = 0;
- ev->posted_timedout = 0;
- ev->posted_eof = 0;
-#if (NGX_HAVE_KQUEUE)
- ev->posted_errno = 0;
-#endif
- ev->posted_available = 0;
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- ev->handler(ev);
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- if (ev->locked) {
- ngx_unlock(ev->lock);
-
- if (ev->lock != ev->own_lock) {
- ngx_unlock(ev->own_lock);
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p is done", ev);
-
- break;
- }
- }
-}
-
-#else
-
-void
-ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
-{
-}
-
-#endif
diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h
index abd2e261d..40ba1c1e0 100644
--- a/src/event/ngx_event_posted.h
+++ b/src/event/ngx_event_posted.h
@@ -14,21 +14,11 @@
#include <ngx_event.h>
-#if (NGX_THREADS)
-extern ngx_mutex_t *ngx_posted_events_mutex;
-#endif
-
-
-#define ngx_locked_post_event(ev, queue) \
+#define ngx_post_event(ev, q) \
\
- if (ev->prev == NULL) { \
- ev->next = (ngx_event_t *) *queue; \
- ev->prev = (ngx_event_t **) queue; \
- *queue = ev; \
- \
- if (ev->next) { \
- ev->next->prev = &ev->next; \
- } \
+ if (!ev->posted) { \
+ ev->posted = 1; \
+ ngx_queue_insert_tail(q, &ev->queue); \
\
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "post event %p", ev); \
\
@@ -38,38 +28,21 @@ extern ngx_mutex_t *ngx_posted_events_mutex;
}
-#define ngx_post_event(ev, queue) \
- \
- ngx_mutex_lock(ngx_posted_events_mutex); \
- ngx_locked_post_event(ev, queue); \
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
-
#define ngx_delete_posted_event(ev) \
\
- *(ev->prev) = ev->next; \
+ ev->posted = 0; \
+ ngx_queue_remove(&ev->queue); \
\
- if (ev->next) { \
- ev->next->prev = ev->prev; \
- } \
- \
- ev->prev = NULL; \
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, \
"delete posted event %p", ev);
-void ngx_event_process_posted(ngx_cycle_t *cycle,
- ngx_thread_volatile ngx_event_t **posted);
-void ngx_wakeup_worker_thread(ngx_cycle_t *cycle);
-
-#if (NGX_THREADS)
-ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle);
-#endif
+void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted);
-extern ngx_thread_volatile ngx_event_t *ngx_posted_accept_events;
-extern ngx_thread_volatile ngx_event_t *ngx_posted_events;
+extern ngx_queue_t ngx_posted_accept_events;
+extern ngx_queue_t ngx_posted_events;
#endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index 177ac1cf1..107558649 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -98,24 +98,6 @@ ngx_event_expire_timers(void)
if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) {
ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
-#if (NGX_THREADS)
-
- if (ngx_threaded && ngx_trylock(ev->lock) == 0) {
-
- /*
- * We cannot change the timer of the event that is being
- * handled by another thread. And we cannot easy walk
- * the rbtree to find next expired timer so we exit the loop.
- * However, it should be a rare case when the event that is
- * being handled has an expired timer.
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "event %p is busy in expire timers", ev);
- break;
- }
-#endif
-
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"event timer del: %d: %M",
ngx_event_ident(ev->data), ev->timer.key);
@@ -132,18 +114,6 @@ ngx_event_expire_timers(void)
ev->timer_set = 0;
-#if (NGX_THREADS)
- if (ngx_threaded) {
- ev->posted_timedout = 1;
-
- ngx_post_event(ev, &ngx_posted_events);
-
- ngx_unlock(ev->lock);
-
- continue;
- }
-#endif
-
ev->timedout = 1;
ev->handler(ev);
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 8016f5b75..9847ec170 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -442,6 +442,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream),
&ngx_http_fastcgi_next_upstream_masks },
+ { ngx_string("fastcgi_next_upstream_tries"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream_tries),
+ NULL },
+
+ { ngx_string("fastcgi_next_upstream_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream_timeout),
+ NULL },
+
{ ngx_string("fastcgi_param"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
ngx_http_upstream_param_set_slot,
@@ -2314,6 +2328,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.store = NGX_CONF_UNSET;
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
+ conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@@ -2322,6 +2337,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
+ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
@@ -2387,6 +2403,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->upstream.store_access,
prev->upstream.store_access, 0600);
+ ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
+ prev->upstream.next_upstream_tries, 0);
+
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@@ -2405,6 +2424,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->upstream.read_timeout,
prev->upstream.read_timeout, 60000);
+ ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
+ prev->upstream.next_upstream_timeout, 0);
+
ngx_conf_merge_size_value(conf->upstream.send_lowat,
prev->upstream.send_lowat, 0);
@@ -2582,6 +2604,11 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->cache_key = prev->cache_key;
}
+ if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "no \"fastcgi_cache_key\" for \"fastcgi_cache\"");
+ }
+
ngx_conf_merge_value(conf->upstream.cache_lock,
prev->upstream.cache_lock, 0);
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index e33e7ce52..f33cfb78e 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -28,6 +28,7 @@ struct ngx_http_header_val_s {
ngx_str_t key;
ngx_http_set_header_pt handler;
ngx_uint_t offset;
+ ngx_uint_t always; /* unsigned always:1 */
};
@@ -98,7 +99,7 @@ static ngx_command_t ngx_http_headers_filter_commands[] = {
{ ngx_string("add_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE2,
+ |NGX_CONF_TAKE23,
ngx_http_headers_add,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -146,28 +147,38 @@ static ngx_int_t
ngx_http_headers_filter(ngx_http_request_t *r)
{
ngx_str_t value;
- ngx_uint_t i;
+ ngx_uint_t i, safe_status;
ngx_http_header_val_t *h;
ngx_http_headers_conf_t *conf;
conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
- || r != r->main
- || (r->headers_out.status != NGX_HTTP_OK
- && r->headers_out.status != NGX_HTTP_CREATED
- && r->headers_out.status != NGX_HTTP_NO_CONTENT
- && 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_SEE_OTHER
- && r->headers_out.status != NGX_HTTP_NOT_MODIFIED
- && r->headers_out.status != NGX_HTTP_TEMPORARY_REDIRECT))
+ || r != r->main)
{
return ngx_http_next_header_filter(r);
}
- if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
+ switch (r->headers_out.status) {
+
+ case NGX_HTTP_OK:
+ case NGX_HTTP_CREATED:
+ case NGX_HTTP_NO_CONTENT:
+ case NGX_HTTP_PARTIAL_CONTENT:
+ case NGX_HTTP_MOVED_PERMANENTLY:
+ case NGX_HTTP_MOVED_TEMPORARILY:
+ case NGX_HTTP_SEE_OTHER:
+ case NGX_HTTP_NOT_MODIFIED:
+ case NGX_HTTP_TEMPORARY_REDIRECT:
+ safe_status = 1;
+ break;
+
+ default:
+ safe_status = 0;
+ break;
+ }
+
+ if (conf->expires != NGX_HTTP_EXPIRES_OFF && safe_status) {
if (ngx_http_set_expires(r, conf) != NGX_OK) {
return NGX_ERROR;
}
@@ -177,6 +188,10 @@ ngx_http_headers_filter(ngx_http_request_t *r)
h = conf->headers->elts;
for (i = 0; i < conf->headers->nelts; i++) {
+ if (!safe_status && !h[i].always) {
+ continue;
+ }
+
if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) {
return NGX_ERROR;
}
@@ -603,6 +618,7 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
hv->key = value[1];
hv->handler = ngx_http_add_header;
hv->offset = 0;
+ hv->always = 0;
set = ngx_http_set_headers;
for (i = 0; set[i].name.len; i++) {
@@ -631,5 +647,17 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
+ if (cf->args->nelts == 3) {
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_strcmp(value[3].data, "always") != 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[3]);
+ return NGX_CONF_ERROR;
+ }
+
+ hv->always = 1;
+
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index c983b973b..bd7a30970 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -1012,6 +1012,7 @@ transparent:
b->last_buf = 1;
ngx_http_image_length(r, b);
+ ngx_http_weak_etag(r);
return b;
}
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index bc660cdd6..cec77e749 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -1136,7 +1136,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_int_t gzip;
ngx_uint_t i, n;
ngx_msec_t flush;
- ngx_str_t *value, name, s, filter;
+ ngx_str_t *value, name, s;
ngx_http_log_t *log;
ngx_syslog_peer_t *peer;
ngx_http_log_buf_t *buffer;
@@ -1254,21 +1254,9 @@ process_formats:
return NGX_CONF_ERROR;
}
- if (log->syslog_peer != NULL) {
- if (cf->args->nelts > 3) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "parameter \"%V\" is not supported by syslog",
- &value[3]);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
size = 0;
flush = 0;
gzip = 0;
- filter.len = 0;
for (i = 3; i < cf->args->nelts; i++) {
@@ -1336,8 +1324,25 @@ process_formats:
}
if (ngx_strncmp(value[i].data, "if=", 3) == 0) {
- filter.len = value[i].len - 3;
- filter.data = value[i].data + 3;
+ s.len = value[i].len - 3;
+ s.data = value[i].data + 3;
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &s;
+ 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;
+ }
+
+ log->filter = ccv.complex_value;
+
continue;
}
@@ -1361,6 +1366,12 @@ process_formats:
return NGX_CONF_ERROR;
}
+ if (log->syslog_peer) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "logs to syslog cannot be buffered");
+ return NGX_CONF_ERROR;
+ }
+
if (log->file->data) {
buffer = log->file->data;
@@ -1410,23 +1421,6 @@ process_formats:
log->file->data = buffer;
}
- if (filter.len) {
- log->filter = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (log->filter == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &filter;
- ccv.complex_value = log->filter;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index bda038da4..17f1d8e10 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -102,6 +102,20 @@ static ngx_command_t ngx_http_memcached_commands[] = {
offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream),
&ngx_http_memcached_next_upstream_masks },
+ { ngx_string("memcached_next_upstream_tries"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream_tries),
+ NULL },
+
+ { ngx_string("memcached_next_upstream_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream_timeout),
+ NULL },
+
{ ngx_string("memcached_gzip_flag"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
@@ -391,7 +405,7 @@ found:
p = line.data + line.len;
u->headers_in.content_length_n = ngx_atoof(start, p - start);
- if (u->headers_in.content_length_n == -1) {
+ if (u->headers_in.content_length_n == NGX_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"memcached sent invalid length in response \"%V\" "
"for key \"%V\"",
@@ -583,9 +597,11 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
*/
conf->upstream.local = NGX_CONF_UNSET_PTR;
+ conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
+ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
@@ -619,6 +635,9 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_ptr_value(conf->upstream.local,
prev->upstream.local, NULL);
+ ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
+ prev->upstream.next_upstream_tries, 0);
+
ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
prev->upstream.connect_timeout, 60000);
@@ -628,6 +647,9 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->upstream.read_timeout,
prev->upstream.read_timeout, 60000);
+ ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
+ prev->upstream.next_upstream_timeout, 0);
+
ngx_conf_merge_size_value(conf->upstream.buffer_size,
prev->upstream.buffer_size,
(size_t) ngx_pagesize);
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index 8f439ba92..980bf5719 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -1840,7 +1840,7 @@ ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
atom->pos = atom_header;
atom->last = atom_header + atom_size;
- trak->vmhd_size += atom_size;
+ trak->smhd_size += atom_size;
trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf = atom;
ngx_mp4_atom_next(mp4, atom_data_size);
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 52c63e138..c8a80ef48 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -505,6 +505,20 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream),
&ngx_http_proxy_next_upstream_masks },
+ { ngx_string("proxy_next_upstream_tries"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream_tries),
+ NULL },
+
+ { ngx_string("proxy_next_upstream_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream_timeout),
+ NULL },
+
{ ngx_string("proxy_pass_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_array_slot,
@@ -2455,6 +2469,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->upstream.store = NGX_CONF_UNSET;
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
+ conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@@ -2463,6 +2478,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
+ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
@@ -2543,6 +2559,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->upstream.store_access,
prev->upstream.store_access, 0600);
+ ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
+ prev->upstream.next_upstream_tries, 0);
+
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@@ -2561,6 +2580,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->upstream.read_timeout,
prev->upstream.read_timeout, 60000);
+ ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
+ prev->upstream.next_upstream_timeout, 0);
+
ngx_conf_merge_size_value(conf->upstream.send_lowat,
prev->upstream.send_lowat, 0);
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 4081f8774..f24119645 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -930,7 +930,11 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (v->get_handler == NULL
&& ngx_strncasecmp(value[1].data, (u_char *) "http_", 5) != 0
&& ngx_strncasecmp(value[1].data, (u_char *) "sent_http_", 10) != 0
- && ngx_strncasecmp(value[1].data, (u_char *) "upstream_http_", 14) != 0)
+ && ngx_strncasecmp(value[1].data, (u_char *) "upstream_http_", 14) != 0
+ && ngx_strncasecmp(value[1].data, (u_char *) "cookie_", 7) != 0
+ && ngx_strncasecmp(value[1].data, (u_char *) "upstream_cookie_", 16)
+ != 0
+ && ngx_strncasecmp(value[1].data, (u_char *) "arg_", 4) != 0)
{
v->get_handler = ngx_http_rewrite_var;
v->data = index;
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 0be5066ec..313f3b3ad 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -299,6 +299,20 @@ static ngx_command_t ngx_http_scgi_commands[] = {
offsetof(ngx_http_scgi_loc_conf_t, upstream.next_upstream),
&ngx_http_scgi_next_upstream_masks },
+ { ngx_string("scgi_next_upstream_tries"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_scgi_loc_conf_t, upstream.next_upstream_tries),
+ NULL },
+
+ { ngx_string("scgi_next_upstream_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_scgi_loc_conf_t, upstream.next_upstream_timeout),
+ NULL },
+
{ ngx_string("scgi_param"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
ngx_http_upstream_param_set_slot,
@@ -1074,6 +1088,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.store = NGX_CONF_UNSET;
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
+ conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@@ -1082,6 +1097,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
+ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
@@ -1142,6 +1158,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->upstream.store_access,
prev->upstream.store_access, 0600);
+ ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
+ prev->upstream.next_upstream_tries, 0);
+
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@@ -1160,6 +1179,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->upstream.read_timeout,
prev->upstream.read_timeout, 60000);
+ ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
+ prev->upstream.next_upstream_timeout, 0);
+
ngx_conf_merge_size_value(conf->upstream.send_lowat,
prev->upstream.send_lowat, 0);
@@ -1248,7 +1270,8 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
if (conf->upstream.max_temp_file_size != 0
- && conf->upstream.max_temp_file_size < size) {
+ && conf->upstream.max_temp_file_size < size)
+ {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"scgi_max_temp_file_size\" must be equal to zero to disable "
"temporary files usage or must be equal to or greater than "
@@ -1336,6 +1359,11 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->cache_key = prev->cache_key;
}
+ if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "no \"scgi_cache_key\" for \"scgi_cache\"");
+ }
+
ngx_conf_merge_value(conf->upstream.cache_lock,
prev->upstream.cache_lock, 0);
diff --git a/src/http/modules/ngx_http_stub_status_module.c b/src/http/modules/ngx_http_stub_status_module.c
index f4f5888b6..dd6835898 100644
--- a/src/http/modules/ngx_http_stub_status_module.c
+++ b/src/http/modules/ngx_http_stub_status_module.c
@@ -21,7 +21,7 @@ static char *ngx_http_set_stub_status(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_command_t ngx_http_status_commands[] = {
{ ngx_string("stub_status"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
ngx_http_set_stub_status,
0,
0,
diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c
index 5e6e038bf..e6a34a763 100644
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -546,6 +546,14 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
for ( ;; ) {
if (ch == match) {
+
+ if (ctx->match.len == 1) {
+ ctx->pos = p + 1;
+ ctx->copy_end = p;
+
+ return NGX_OK;
+ }
+
copy_end = p;
ctx->looked.data[0] = *p;
looked = 1;
diff --git a/src/http/modules/ngx_http_upstream_keepalive_module.c b/src/http/modules/ngx_http_upstream_keepalive_module.c
index d07ed9eda..c1c1c70d6 100644
--- a/src/http/modules/ngx_http_upstream_keepalive_module.c
+++ b/src/http/modules/ngx_http_upstream_keepalive_module.c
@@ -79,7 +79,7 @@ static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_command_t ngx_http_upstream_keepalive_commands[] = {
{ ngx_string("keepalive"),
- NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
+ NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
ngx_http_upstream_keepalive,
NGX_HTTP_SRV_CONF_OFFSET,
0,
@@ -485,7 +485,6 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_int_t n;
ngx_str_t *value;
- ngx_uint_t i;
uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
@@ -514,23 +513,5 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
kcf->max_cached = n;
- for (i = 2; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "single") == 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"single\" parameter is deprecated");
- continue;
- }
-
- goto invalid;
- }
-
return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
-
- return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_upstream_least_conn_module.c b/src/http/modules/ngx_http_upstream_least_conn_module.c
index dbef95d41..623bc9b10 100644
--- a/src/http/modules/ngx_http_upstream_least_conn_module.c
+++ b/src/http/modules/ngx_http_upstream_least_conn_module.c
@@ -299,10 +299,6 @@ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
lcp->rrp.tried[n] |= m;
lcp->conns[p]++;
- if (pc->tries == 1 && peers->next) {
- pc->tries += peers->next->number;
- }
-
return NGX_OK;
failed:
@@ -314,7 +310,6 @@ failed:
lcp->conns += peers->number;
lcp->rrp.peers = peers->next;
- pc->tries = lcp->rrp.peers->number;
n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1))
/ (8 * sizeof(uintptr_t));
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index a613b684a..9556aa4a0 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -354,6 +354,20 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream),
&ngx_http_uwsgi_next_upstream_masks },
+ { ngx_string("uwsgi_next_upstream_tries"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream_tries),
+ NULL },
+
+ { ngx_string("uwsgi_next_upstream_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream_timeout),
+ NULL },
+
{ ngx_string("uwsgi_param"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
ngx_http_upstream_param_set_slot,
@@ -1254,6 +1268,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.store = NGX_CONF_UNSET;
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
+ conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@@ -1262,6 +1277,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
+ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
@@ -1329,6 +1345,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->upstream.store_access,
prev->upstream.store_access, 0600);
+ ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
+ prev->upstream.next_upstream_tries, 0);
+
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@@ -1347,6 +1366,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->upstream.read_timeout,
prev->upstream.read_timeout, 60000);
+ ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
+ prev->upstream.next_upstream_timeout, 0);
+
ngx_conf_merge_size_value(conf->upstream.send_lowat,
prev->upstream.send_lowat, 0);
@@ -1435,7 +1457,8 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
if (conf->upstream.max_temp_file_size != 0
- && conf->upstream.max_temp_file_size < size) {
+ && conf->upstream.max_temp_file_size < size)
+ {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
"temporary files usage or must be equal to or greater than "
@@ -1523,6 +1546,11 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->cache_key = prev->cache_key;
}
+ if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "no \"uwsgi_cache_key\" for \"uwsgi_cache\"");
+ }
+
ngx_conf_merge_value(conf->upstream.cache_lock,
prev->upstream.cache_lock, 0);
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index bf4d1fe9a..6a8894cc3 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -577,7 +577,7 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0;
- embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *));
+ embedding = ngx_palloc(cf->pool, (5 + n) * sizeof(char *));
if (embedding == NULL) {
goto fail;
}
@@ -595,6 +595,7 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
embedding[n++] = "-Mnginx";
embedding[n++] = "-e";
embedding[n++] = "0";
+ embedding[n] = NULL;
n = perl_parse(perl, ngx_http_perl_xs_init, n, embedding, NULL);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 4071b6126..3b36f4a19 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1837,6 +1837,7 @@ ngx_http_set_etag(ngx_http_request_t *r)
etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
if (etag->value.data == NULL) {
+ etag->hash = 0;
return NGX_ERROR;
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 285120de7..fc2c3d49b 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -554,7 +554,7 @@ extern ngx_str_t ngx_http_core_get_method;
r->headers_out.content_length->hash = 0; \
r->headers_out.content_length = NULL; \
}
- \
+
#define ngx_http_clear_accept_ranges(r) \
\
r->allow_ranges = 0; \
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index 71e6e36c2..2eebc3068 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -145,6 +145,8 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
ngx_sprintf(cache->shpool->log_ctx, " in cache keys zone \"%V\"%Z",
&shm_zone->shm.name);
+ cache->shpool->log_nomem = 0;
+
return NGX_OK;
}
@@ -698,6 +700,8 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
fcn = ngx_slab_calloc_locked(cache->shpool,
sizeof(ngx_http_file_cache_node_t));
if (fcn == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "could not allocate node%s", cache->shpool->log_ctx);
rc = NGX_ERROR;
goto failed;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 845ada322..2b932dee4 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2656,6 +2656,12 @@ ngx_http_writer(ngx_http_request_t *r)
if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
+#if (NGX_HTTP_SPDY)
+ if (r->spdy_stream) {
+ return;
+ }
+#endif
+
if (!wev->delayed) {
ngx_add_timer(wev, clcf->send_timeout);
}
diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c
index 478036979..3c57882a6 100644
--- a/src/http/ngx_http_spdy.c
+++ b/src/http/ngx_http_spdy.c
@@ -3372,7 +3372,7 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
ngx_del_timer(ev);
}
- if (ev->prev) {
+ if (ev->posted) {
ngx_delete_posted_event(ev);
}
@@ -3387,7 +3387,7 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
ngx_del_timer(ev);
}
- if (ev->prev) {
+ if (ev->posted) {
ngx_delete_posted_event(ev);
}
diff --git a/src/http/ngx_http_spdy_filter_module.c b/src/http/ngx_http_spdy_filter_module.c
index 82405d9a1..d1406a665 100644
--- a/src/http/ngx_http_spdy_filter_module.c
+++ b/src/http/ngx_http_spdy_filter_module.c
@@ -1141,6 +1141,11 @@ ngx_http_spdy_handle_stream(ngx_http_spdy_connection_t *sc,
wev = stream->request->connection->write;
+ /*
+ * This timer can only be set if the stream was delayed because of rate
+ * limit. In that case the event should be triggered by the timer.
+ */
+
if (!wev->timer_set) {
wev->delayed = 0;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 18b04f775..000c6de69 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -519,6 +519,11 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
return;
}
+ if (rc == NGX_ERROR) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
if (rc != NGX_DECLINED) {
ngx_http_finalize_request(r, rc);
return;
@@ -693,6 +698,14 @@ found:
return;
}
+ u->peer.start_time = ngx_current_msec;
+
+ if (u->conf->next_upstream_tries
+ && u->peer.tries > u->conf->next_upstream_tries)
+ {
+ u->peer.tries = u->conf->next_upstream_tries;
+ }
+
ngx_http_upstream_connect(r, u);
}
@@ -3416,6 +3429,7 @@ static void
ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
ngx_uint_t ft_type)
{
+ ngx_msec_t timeout;
ngx_uint_t status, state;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -3485,9 +3499,12 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
if (status) {
u->state->status = status;
+ timeout = u->conf->next_upstream_timeout;
- if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) {
-
+ if (u->peer.tries == 0
+ || !(u->conf->next_upstream & ft_type)
+ || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
+ {
#if (NGX_HTTP_CACHE)
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
@@ -4973,7 +4990,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) {
- goto invalid;
+ goto not_supported;
}
weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
@@ -4988,7 +5005,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) {
- goto invalid;
+ goto not_supported;
}
max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10);
@@ -5003,7 +5020,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) {
if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) {
- goto invalid;
+ goto not_supported;
}
s.len = value[i].len - 13;
@@ -5021,7 +5038,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strcmp(value[i].data, "backup") == 0) {
if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) {
- goto invalid;
+ goto not_supported;
}
us->backup = 1;
@@ -5032,7 +5049,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strcmp(value[i].data, "down") == 0) {
if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
- goto invalid;
+ goto not_supported;
}
us->down = 1;
@@ -5072,6 +5089,14 @@ invalid:
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
+
+not_supported:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "balancing method does not support parameter \"%V\"",
+ &value[i]);
+
+ return NGX_CONF_ERROR;
}
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index dafb5a319..2ee899d83 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -136,6 +136,7 @@ typedef struct {
ngx_msec_t send_timeout;
ngx_msec_t read_timeout;
ngx_msec_t timeout;
+ ngx_msec_t next_upstream_timeout;
size_t send_lowat;
size_t buffer_size;
@@ -153,6 +154,7 @@ typedef struct {
ngx_uint_t ignore_headers;
ngx_uint_t next_upstream;
ngx_uint_t store_access;
+ ngx_uint_t next_upstream_tries;
ngx_flag_t buffering;
ngx_flag_t pass_request_headers;
ngx_flag_t pass_request_body;
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index b39eeae50..2d0649b7f 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -10,6 +10,10 @@
#include <ngx_http.h>
+#define ngx_http_upstream_tries(p) ((p)->number \
+ + ((p)->next ? (p)->next->number : 0))
+
+
static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
ngx_http_upstream_rr_peer_data_t *rrp);
@@ -255,7 +259,7 @@ ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
- r->upstream->peer.tries = rrp->peers->number;
+ r->upstream->peer.tries = ngx_http_upstream_tries(rrp->peers);
#if (NGX_HTTP_SSL)
r->upstream->peer.set_session =
ngx_http_upstream_set_round_robin_peer_session;
@@ -374,7 +378,7 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
- r->upstream->peer.tries = rrp->peers->number;
+ r->upstream->peer.tries = ngx_http_upstream_tries(rrp->peers);
#if (NGX_HTTP_SSL)
r->upstream->peer.set_session = ngx_http_upstream_empty_set_session;
r->upstream->peer.save_session = ngx_http_upstream_empty_save_session;
@@ -432,10 +436,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
/* ngx_unlock_mutex(peers->mutex); */
- if (pc->tries == 1 && peers->next) {
- pc->tries += peers->next->number;
- }
-
return NGX_OK;
failed:
@@ -447,7 +447,6 @@ failed:
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");
rrp->peers = peers->next;
- pc->tries = rrp->peers->number;
n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
/ (8 * sizeof(uintptr_t));
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 1b61c39d4..738f2237a 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -2511,8 +2511,7 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
av = key[n].value;
- if (av->get_handler
- && v[i].name.len == key[n].key.len
+ if (v[i].name.len == key[n].key.len
&& ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len)
== 0)
{
@@ -2524,6 +2523,10 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
av->index = i;
+ if (av->get_handler == NULL) {
+ break;
+ }
+
goto next;
}
}
diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c
index 350d2cdf9..5a7cb6bf6 100644
--- a/src/mail/ngx_mail.c
+++ b/src/mail/ngx_mail.c
@@ -131,8 +131,7 @@ ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/*
- * create the main_conf's, the null srv_conf's, and the null loc_conf's
- * of the all mail modules
+ * create the main_conf's and the null srv_conf's of the all mail modules
*/
for (m = 0; ngx_modules[m]; m++) {
diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c
index 4ee7c8dc3..a5388c847 100644
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -41,7 +41,7 @@ static ngx_command_t ngx_mail_core_commands[] = {
NULL },
{ ngx_string("listen"),
- NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
+ NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_mail_core_listen,
NGX_MAIL_SRV_CONF_OFFSET,
0,
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
index 784111f6e..57b69b564 100644
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -121,6 +121,8 @@ ngx_mail_init_connection(ngx_connection_t *c)
return;
}
+ s->signature = NGX_MAIL_MODULE;
+
s->main_conf = addr_conf->ctx->main_conf;
s->srv_conf = addr_conf->ctx->srv_conf;
diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c
index 8e9069660..1efa0667c 100644
--- a/src/os/unix/ngx_channel.c
+++ b/src/os/unix/ngx_channel.c
@@ -216,13 +216,6 @@ ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
rev->log = cycle->log;
wev->log = cycle->log;
-#if (NGX_THREADS)
- rev->lock = &c->lock;
- wev->lock = &c->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-#endif
-
rev->channel = 1;
wev->channel = 1;
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index 9a4de022d..bf3a310aa 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -40,7 +40,9 @@ ngx_os_init(ngx_log_t *log)
}
#endif
- ngx_init_setproctitle(log);
+ if (ngx_init_setproctitle(log) != NGX_OK) {
+ return NGX_ERROR;
+ }
ngx_pagesize = getpagesize();
ngx_cacheline_size = NGX_CPU_CACHE_LINE;
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 3205aa555..6c84ba8bd 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -1214,7 +1214,6 @@ ngx_wakeup_worker_threads(ngx_cycle_t *cycle)
/* STUB */
ngx_done_events(cycle);
ngx_mutex_destroy(ngx_event_timer_mutex);
- ngx_mutex_destroy(ngx_posted_events_mutex);
return;
}
@@ -1265,20 +1264,18 @@ ngx_worker_thread_cycle(void *data)
return (ngx_thread_value_t) 1;
}
- ngx_mutex_lock(ngx_posted_events_mutex);
-
for ( ;; ) {
thr->state = NGX_THREAD_FREE;
+#if 0
if (ngx_cond_wait(thr->cv, ngx_posted_events_mutex) == NGX_ERROR) {
return (ngx_thread_value_t) 1;
}
+#endif
if (ngx_terminate) {
thr->state = NGX_THREAD_EXIT;
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
"thread " NGX_TID_T_FMT " is done",
ngx_thread_self());
@@ -1288,6 +1285,7 @@ ngx_worker_thread_cycle(void *data)
thr->state = NGX_THREAD_BUSY;
+#if 0
if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
return (ngx_thread_value_t) 1;
}
@@ -1295,6 +1293,7 @@ ngx_worker_thread_cycle(void *data)
if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
return (ngx_thread_value_t) 1;
}
+#endif
if (ngx_process_changes) {
if (ngx_process_changes(cycle, 1) == NGX_ERROR) {
diff --git a/src/os/unix/ngx_setproctitle.h b/src/os/unix/ngx_setproctitle.h
index 2323408c4..c3636628b 100644
--- a/src/os/unix/ngx_setproctitle.h
+++ b/src/os/unix/ngx_setproctitle.h
@@ -13,7 +13,7 @@
/* FreeBSD, NetBSD, OpenBSD */
-#define ngx_init_setproctitle(log)
+#define ngx_init_setproctitle(log) NGX_OK
#define ngx_setproctitle(title) setproctitle("%s", title)
@@ -39,7 +39,7 @@ void ngx_setproctitle(char *title);
#else
-#define ngx_init_setproctitle(log)
+#define ngx_init_setproctitle(log) NGX_OK
#define ngx_setproctitle(title)
#endif /* OSes */