summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornginx <nginx@nginx.org>2015-04-07 15:42:39 +0000
committerJon Kolb <kolbyjack@gmail.com>2015-04-07 15:42:39 +0000
commit6612579e5a1459b05960a31bbbcfe4cd5afc319a (patch)
tree6959ffbbb370e1aa938c169dec4e226c160c9d44
parentae88e2338f6e27459ace8a23754afc5892c2c5be (diff)
downloadnginx-1.7.tar.gz
Changes with nginx 1.7.12 07 Apr 2015v1.7.12nginx-1.7
*) 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--CHANGES18
-rw-r--r--CHANGES.ru20
-rw-r--r--auto/make2
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_file.c6
-rw-r--r--src/core/ngx_spinlock.c2
-rw-r--r--src/event/modules/ngx_epoll_module.c4
-rw-r--r--src/event/ngx_event_openssl_stapling.c2
-rw-r--r--src/event/ngx_event_posted.h16
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c6
-rw-r--r--src/http/modules/ngx_http_proxy_module.c7
-rw-r--r--src/http/ngx_http_cache.h4
-rw-r--r--src/http/ngx_http_file_cache.c124
-rw-r--r--src/http/ngx_http_request_body.c2
-rw-r--r--src/http/ngx_http_spdy.c111
-rw-r--r--src/http/ngx_http_special_response.c4
-rw-r--r--src/http/ngx_http_upstream.c26
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c4
18 files changed, 256 insertions, 106 deletions
diff --git a/CHANGES b/CHANGES
index 8c76b9580..e85749a95 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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 более не нужен; теперь
diff --git a/auto/make b/auto/make
index 05b74543c..ed94e8f62 100644
--- a/auto/make
+++ b/auto/make
@@ -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;
}