diff options
author | nginx <nginx@nginx.org> | 2015-04-07 15:42:39 +0000 |
---|---|---|
committer | Jon Kolb <kolbyjack@gmail.com> | 2015-04-07 15:42:39 +0000 |
commit | 6612579e5a1459b05960a31bbbcfe4cd5afc319a (patch) | |
tree | 6959ffbbb370e1aa938c169dec4e226c160c9d44 | |
parent | ae88e2338f6e27459ace8a23754afc5892c2c5be (diff) | |
download | nginx-1.7.tar.gz |
*) Feature: now the "tcp_nodelay" directive works with backend SSL
connections.
*) Feature: now thread pools can be used to read cache file headers.
*) Bugfix: in the "proxy_request_buffering" directive.
*) Bugfix: a segmentation fault might occur in a worker process when
using thread pools on Linux.
*) Bugfix: in error handling when using the "ssl_stapling" directive.
Thanks to Filipe da Silva.
*) Bugfix: in the ngx_http_spdy_module.
-rw-r--r-- | CHANGES | 18 | ||||
-rw-r--r-- | CHANGES.ru | 20 | ||||
-rw-r--r-- | auto/make | 2 | ||||
-rw-r--r-- | src/core/nginx.h | 4 | ||||
-rw-r--r-- | src/core/ngx_file.c | 6 | ||||
-rw-r--r-- | src/core/ngx_spinlock.c | 2 | ||||
-rw-r--r-- | src/event/modules/ngx_epoll_module.c | 4 | ||||
-rw-r--r-- | src/event/ngx_event_openssl_stapling.c | 2 | ||||
-rw-r--r-- | src/event/ngx_event_posted.h | 16 | ||||
-rw-r--r-- | src/http/modules/ngx_http_headers_filter_module.c | 6 | ||||
-rw-r--r-- | src/http/modules/ngx_http_proxy_module.c | 7 | ||||
-rw-r--r-- | src/http/ngx_http_cache.h | 4 | ||||
-rw-r--r-- | src/http/ngx_http_file_cache.c | 124 | ||||
-rw-r--r-- | src/http/ngx_http_request_body.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_spdy.c | 111 | ||||
-rw-r--r-- | src/http/ngx_http_special_response.c | 4 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.c | 26 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_sendfile_chain.c | 4 |
18 files changed, 256 insertions, 106 deletions
@@ -1,4 +1,22 @@ +Changes with nginx 1.7.12 07 Apr 2015 + + *) Feature: now the "tcp_nodelay" directive works with backend SSL + connections. + + *) Feature: now thread pools can be used to read cache file headers. + + *) Bugfix: in the "proxy_request_buffering" directive. + + *) Bugfix: a segmentation fault might occur in a worker process when + using thread pools on Linux. + + *) Bugfix: in error handling when using the "ssl_stapling" directive. + Thanks to Filipe da Silva. + + *) Bugfix: in the ngx_http_spdy_module. + + Changes with nginx 1.7.11 24 Mar 2015 *) Change: the "sendfile" parameter of the "aio" directive is diff --git a/CHANGES.ru b/CHANGES.ru index 7936c19cd..08b641b62 100644 --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,24 @@ +Изменения в nginx 1.7.12 07.04.2015 + + *) Добавление: теперь директива tcp_nodelay работает для SSL-соединений + с бэкендами. + + *) Добавление: теперь потоки могут использоваться для чтения заголовков + файлов в кэше. + + *) Исправление: в директиве proxy_request_buffering. + + *) Исправление: при использовании потоков на Linux в рабочем процессе + мог произойти segmentation fault. + + *) Исправление: в обработке ошибок при использовании директивы + ssl_stapling. + Спасибо Filipe da Silva. + + *) Исправление: в модуле ngx_http_spdy_module. + + Изменения в nginx 1.7.11 24.03.2015 *) Изменение: параметр sendfile директивы aio более не нужен; теперь @@ -8,7 +8,7 @@ echo "creating $NGX_MAKEFILE" mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \ $NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \ $NGX_OBJS/src/http $NGX_OBJS/src/http/modules \ - $NGX_OBJS/src/http/modules/perl \ + $NGX_OBJS/src/http/modules/perl \ $NGX_OBJS/src/mail \ $NGX_OBJS/src/misc diff --git a/src/core/nginx.h b/src/core/nginx.h index 2e84845d2..b350ef2dc 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1007011 -#define NGINX_VERSION "1.7.11" +#define nginx_version 1007012 +#define NGINX_VERSION "1.7.12" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c index ae2373511..3ebd73d8b 100644 --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -356,7 +356,7 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } if (ngx_conf_full_name(cf->cycle, &path->name, 0) != NGX_OK) { - return NULL; + return NGX_CONF_ERROR; } path->conf_file = cf->conf_file->file.name.data; @@ -372,8 +372,8 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) path->len += level + 1; } - while (i < 3) { - path->level[i++] = 0; + if (path->len > 10 + i) { + return "invalid value"; } *slot = path; diff --git a/src/core/ngx_spinlock.c b/src/core/ngx_spinlock.c index 33477e2ee..9c93afaf1 100644 --- a/src/core/ngx_spinlock.c +++ b/src/core/ngx_spinlock.c @@ -42,7 +42,7 @@ ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin) #else -#if (NGX_OLD_THREADS) +#if (NGX_THREADS) #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined ! diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c index 5f7f67859..3458b209a 100644 --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -683,14 +683,14 @@ ngx_epoll_notify(ngx_event_handler_pt handler) { static uint64_t inc = 1; + notify_event.data = handler; + if ((size_t) write(notify_fd, &inc, sizeof(uint64_t)) != sizeof(uint64_t)) { ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno, "write() to eventfd %d failed", notify_fd); return NGX_ERROR; } - notify_event.data = handler; - return NGX_OK; } diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c index 2fa067309..c39598ff5 100644 --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -310,6 +310,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_init() failed"); + X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } @@ -1118,6 +1119,7 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx) if (OCSP_request_add0_id(ocsp, id) == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, "OCSP_request_add0_id() failed"); + OCSP_CERTID_free(id); goto failed; } diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h index 40ba1c1e0..145d30fea 100644 --- a/src/event/ngx_event_posted.h +++ b/src/event/ngx_event_posted.h @@ -16,24 +16,24 @@ #define ngx_post_event(ev, q) \ \ - if (!ev->posted) { \ - ev->posted = 1; \ - ngx_queue_insert_tail(q, &ev->queue); \ + 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); \ + ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, "post event %p", ev);\ \ } else { \ - ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, \ + ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \ "update posted event %p", ev); \ } #define ngx_delete_posted_event(ev) \ \ - ev->posted = 0; \ - ngx_queue_remove(&ev->queue); \ + (ev)->posted = 0; \ + ngx_queue_remove(&(ev)->queue); \ \ - ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, \ + ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \ "delete posted event %p", ev); diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c index a10056903..a356814e4 100644 --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -378,7 +378,7 @@ ngx_http_parse_expires(ngx_str_t *value, ngx_http_expires_t *expires, } } - if (value->data[0] == '@') { + if (value->len && value->data[0] == '@') { value->data++; value->len--; minus = 0; @@ -390,12 +390,12 @@ ngx_http_parse_expires(ngx_str_t *value, ngx_http_expires_t *expires, *expires = NGX_HTTP_EXPIRES_DAILY; - } else if (value->data[0] == '+') { + } else if (value->len && value->data[0] == '+') { value->data++; value->len--; minus = 0; - } else if (value->data[0] == '-') { + } else if (value->len && value->data[0] == '-') { value->data++; value->len--; minus = 1; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index d0b1c885d..00e8923a0 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1503,7 +1503,7 @@ ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in) u_char *chunk; ngx_int_t rc; ngx_buf_t *b; - ngx_chain_t *out, *cl, *tl, **ll; + ngx_chain_t *out, *cl, *tl, **ll, **fl; ngx_http_proxy_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1546,6 +1546,7 @@ ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in) size = 0; cl = in; + fl = ll; for ( ;; ) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1602,8 +1603,8 @@ ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in) b->pos = chunk; b->last = ngx_sprintf(chunk, "%xO" CRLF, size); - tl->next = out; - out = tl; + tl->next = *fl; + *fl = tl; } if (cl->buf->last_buf) { diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h index a7d41c6f1..d36fa779c 100644 --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -91,6 +91,10 @@ struct ngx_http_cache_s { ngx_http_file_cache_t *file_cache; ngx_http_file_cache_node_t *node; +#if (NGX_THREADS) + ngx_thread_task_t *thread_task; +#endif + ngx_msec_t lock_timeout; ngx_msec_t lock_age; ngx_msec_t lock_time; diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c index 52cbdda83..fc1476133 100644 --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -23,6 +23,11 @@ static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r, #if (NGX_HAVE_FILE_AIO) static void ngx_http_cache_aio_event_handler(ngx_event_t *ev); #endif +#if (NGX_THREADS) +static ngx_int_t ngx_http_cache_thread_handler(ngx_thread_task_t *task, + ngx_file_t *file); +static void ngx_http_cache_thread_event_handler(ngx_event_t *ev); +#endif static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c); static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r, @@ -636,38 +641,49 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c) { -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_THREADS) ssize_t n; ngx_http_core_loc_conf_t *clcf; - if (!ngx_file_aio) { - goto noaio; - } - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); +#endif - if (clcf->aio != NGX_HTTP_AIO_ON) { - goto noaio; - } +#if (NGX_HAVE_FILE_AIO) - n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool); + if (clcf->aio == NGX_HTTP_AIO_ON && ngx_file_aio) { + n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool); - if (n != NGX_AGAIN) { - c->reading = 0; - return n; + if (n != NGX_AGAIN) { + c->reading = 0; + return n; + } + + c->reading = 1; + + c->file.aio->data = r; + c->file.aio->handler = ngx_http_cache_aio_event_handler; + + r->main->blocked++; + r->aio = 1; + + return NGX_AGAIN; } - c->reading = 1; +#endif - c->file.aio->data = r; - c->file.aio->handler = ngx_http_cache_aio_event_handler; +#if (NGX_THREADS) - r->main->blocked++; - r->aio = 1; + if (clcf->aio == NGX_HTTP_AIO_THREADS) { + c->file.thread_handler = ngx_http_cache_thread_handler; + c->file.thread_ctx = r; - return NGX_AGAIN; + n = ngx_thread_read(&c->thread_task, &c->file, c->buf->pos, + c->body_start, 0, r->pool); -noaio: + c->reading = (n == NGX_AGAIN); + + return n; + } #endif @@ -704,6 +720,76 @@ ngx_http_cache_aio_event_handler(ngx_event_t *ev) #endif +#if (NGX_THREADS) + +static ngx_int_t +ngx_http_cache_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) +{ + ngx_str_t name; + ngx_thread_pool_t *tp; + ngx_http_request_t *r; + ngx_http_core_loc_conf_t *clcf; + + r = file->thread_ctx; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + tp = clcf->thread_pool; + + if (tp == NULL) { + if (ngx_http_complex_value(r, clcf->thread_pool_value, &name) + != NGX_OK) + { + return NGX_ERROR; + } + + tp = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name); + + if (tp == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "thread pool \"%V\" not found", &name); + return NGX_ERROR; + } + } + + task->event.data = r; + task->event.handler = ngx_http_cache_thread_event_handler; + + if (ngx_thread_task_post(tp, task) != NGX_OK) { + return NGX_ERROR; + } + + r->main->blocked++; + r->aio = 1; + + return NGX_OK; +} + + +static void +ngx_http_cache_thread_event_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + ngx_http_request_t *r; + + r = ev->data; + c = r->connection; + + ngx_http_set_log_request(c->log, r); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http file cache thread: \"%V?%V\"", &r->uri, &r->args); + + r->main->blocked--; + r->aio = 0; + + r->write_event_handler(r); + + ngx_http_run_posted_requests(c); +} + +#endif + + static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c) { diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index ac5b530ba..9c169845e 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -949,6 +949,7 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in) b->pos = cl->buf->pos; b->last = cl->buf->last; b->end = cl->buf->end; + b->flush = r->request_body_no_buffering; size = cl->buf->last - cl->buf->pos; @@ -1056,6 +1057,7 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in) b->pos = cl->buf->pos; b->last = cl->buf->last; b->end = cl->buf->end; + b->flush = r->request_body_no_buffering; *ll = tl; ll = &tl->next; diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c index 13b81a63a..6bb79b88b 100644 --- a/src/http/ngx_http_spdy.c +++ b/src/http/ngx_http_spdy.c @@ -662,6 +662,7 @@ ngx_http_spdy_write_handler(ngx_event_t *wev) ngx_int_t ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc) { + int tcp_nodelay; ngx_chain_t *cl; ngx_event_t *wev; ngx_connection_t *c; @@ -700,20 +701,52 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc) cl = c->send_chain(c, cl, 0); if (cl == NGX_CHAIN_ERROR) { - c->error = 1; - - if (!sc->blocked) { - ngx_post_event(wev, &ngx_posted_events); - } - - return NGX_ERROR; + goto error; } clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx, ngx_http_core_module); if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { - return NGX_ERROR; /* FIXME */ + goto error; + } + + if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { + if (ngx_tcp_push(c->fd) == -1) { + ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed"); + goto error; + } + + c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; + tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0; + + } else { + tcp_nodelay = 1; + } + + if (tcp_nodelay + && clcf->tcp_nodelay + && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) + == -1) + { +#if (NGX_SOLARIS) + /* Solaris returns EINVAL if a socket has been shut down */ + c->log_error = NGX_ERROR_IGNORE_EINVAL; +#endif + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + + c->log_error = NGX_ERROR_INFO; + goto error; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; } if (cl) { @@ -751,6 +784,16 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc) sc->last_out = frame; return NGX_OK; + +error: + + c->error = 1; + + if (!sc->blocked) { + ngx_post_event(wev, &ngx_posted_events); + } + + return NGX_ERROR; } @@ -3317,10 +3360,8 @@ ngx_http_spdy_close_stream_handler(ngx_event_t *ev) void ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) { - int tcp_nodelay; ngx_event_t *ev; - ngx_connection_t *c, *fc; - ngx_http_core_loc_conf_t *clcf; + ngx_connection_t *fc; ngx_http_spdy_stream_t **index, *s; ngx_http_spdy_srv_conf_t *sscf; ngx_http_spdy_connection_t *sc; @@ -3346,54 +3387,6 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) { sc->connection->error = 1; } - - } else { - c = sc->connection; - - if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { - if (ngx_tcp_push(c->fd) == -1) { - ngx_connection_error(c, ngx_socket_errno, - ngx_tcp_push_n " failed"); - c->error = 1; - tcp_nodelay = 0; - - } else { - c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; - tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0; - } - - } else { - tcp_nodelay = 1; - } - - clcf = ngx_http_get_module_loc_conf(stream->request, - ngx_http_core_module); - - if (tcp_nodelay - && clcf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) - == -1) - { -#if (NGX_SOLARIS) - /* Solaris returns EINVAL if a socket has been shut down */ - c->log_error = NGX_ERROR_IGNORE_EINVAL; -#endif - - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - - c->log_error = NGX_ERROR_INFO; - c->error = 1; - - } else { - c->tcp_nodelay = NGX_TCP_NODELAY_SET; - } - } } if (sc->stream == stream) { diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 546400539..a97791e8b 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -553,7 +553,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page) return NGX_ERROR; } - if (uri.data[0] == '/') { + if (uri.len && uri.data[0] == '/') { if (err_page->value.lengths) { ngx_http_split_args(r, &uri, &args); @@ -570,7 +570,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page) return ngx_http_internal_redirect(r, &uri, &args); } - if (uri.data[0] == '@') { + if (uri.len && uri.data[0] == '@') { return ngx_http_named_location(r, &uri); } diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 0a04e611c..56091fa98 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -1448,7 +1448,9 @@ static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_connection_t *c) { - ngx_int_t rc; + int tcp_nodelay; + ngx_int_t rc; + ngx_http_core_loc_conf_t *clcf; if (ngx_http_upstream_test_connect(c) != NGX_OK) { ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); @@ -1481,6 +1483,28 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } + + /* abbreviated SSL handshake may interact badly with Nagle */ + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + } } r->connection->log->action = "SSL handshaking to upstream"; diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c index 25790b6b6..3f17dc6e4 100644 --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -266,9 +266,9 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) c->busy_count = 0; } - rc = aio->preload_handler(file); + n = aio->preload_handler(file); - if (rc > 0) { + if (n > 0) { send = prev_send + sent; continue; } |