diff options
author | nginx <nginx@nginx.org> | 2014-09-16 14:45:43 +0000 |
---|---|---|
committer | Jon Kolb <kolbyjack@gmail.com> | 2014-09-16 14:45:43 +0000 |
commit | bb8c0683da773566e09797ef8a4ee00ad1e0f956 (patch) | |
tree | 5e2b511fa7d6f189171a65220d502d88f065d59d | |
parent | 1176952193ccf47078dc84b8494d0496ad1ac4a2 (diff) | |
download | nginx-1.7.5.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.
56 files changed, 628 insertions, 624 deletions
@@ -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 */ |