diff options
author | nginx <nginx@nginx.org> | 2013-07-30 13:40:42 +0000 |
---|---|---|
committer | Jon Kolb <jon@b0g.us> | 2013-07-30 13:40:42 +0000 |
commit | c1d6dbb45ec3f5494f8d94d51e44807e04eda5fc (patch) | |
tree | 98cf70852a2947868c7379ec4422c70854b6cbc8 | |
parent | 76075f523f38baa374d5d0bc46e26bdded4ec6b4 (diff) | |
download | nginx-c1d6dbb45ec3f5494f8d94d51e44807e04eda5fc.tar.gz |
Changes with nginx 1.5.3 30 Jul 2013v1.5.3
*) Change in internal API: now u->length defaults to -1 if working with
backends in unbuffered mode.
*) Change: now after receiving an incomplete response from a backend
server nginx tries to send an available part of the response to a
client, and then closes client connection.
*) Bugfix: a segmentation fault might occur in a worker process if the
ngx_http_spdy_module was used with the "client_body_in_file_only"
directive.
*) Bugfix: the "so_keepalive" parameter of the "listen" directive might
be handled incorrectly on DragonFlyBSD.
Thanks to Sepherosa Ziehau.
*) Bugfix: in the ngx_http_xslt_filter_module.
*) Bugfix: in the ngx_http_sub_filter_module.
33 files changed, 423 insertions, 282 deletions
@@ -1,4 +1,26 @@ +Changes with nginx 1.5.3 30 Jul 2013 + + *) Change in internal API: now u->length defaults to -1 if working with + backends in unbuffered mode. + + *) Change: now after receiving an incomplete response from a backend + server nginx tries to send an available part of the response to a + client, and then closes client connection. + + *) Bugfix: a segmentation fault might occur in a worker process if the + ngx_http_spdy_module was used with the "client_body_in_file_only" + directive. + + *) Bugfix: the "so_keepalive" parameter of the "listen" directive might + be handled incorrectly on DragonFlyBSD. + Thanks to Sepherosa Ziehau. + + *) Bugfix: in the ngx_http_xslt_filter_module. + + *) Bugfix: in the ngx_http_sub_filter_module. + + Changes with nginx 1.5.2 02 Jul 2013 *) Feature: now several "error_log" directives can be used. diff --git a/CHANGES.ru b/CHANGES.ru index a6dd78b48..cd732bd93 100644 --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,26 @@ +Изменения в nginx 1.5.3 30.07.2013 + + *) Изменение во внутреннем API: теперь при небуферизированной работе с + бэкендами u->length по умолчанию устанавливается в -1. + + *) Изменение: теперь при получении неполного ответа от бэкенда nginx + отправляет полученную часть ответа, после чего закрывает соединение с + клиентом. + + *) Исправление: в рабочем процессе мог произойти segmentation fault, + если использовался модуль ngx_http_spdy_module и директива + client_body_in_file_only. + + *) Исправление: параметр so_keepalive директивы listen мог работать + некорректно на DragonFlyBSD. + Спасибо Sepherosa Ziehau. + + *) Исправление: в модуле ngx_http_xslt_filter_module. + + *) Исправление: в модуле ngx_http_sub_filter_module. + + Изменения в nginx 1.5.2 02.07.2013 *) Добавление: теперь можно использовать несколько директив error_log. diff --git a/auto/lib/perl/make b/auto/lib/perl/make index 260bd95a0..d1c1b9e48 100644 --- a/auto/lib/perl/make +++ b/auto/lib/perl/make @@ -18,6 +18,7 @@ $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\ $NGX_OBJS/src/http/modules/perl/Makefile: \\ + $NGX_AUTO_CONFIG_H \\ src/core/nginx.h \\ src/http/modules/perl/Makefile.PL \\ src/http/modules/perl/nginx.pm \\ diff --git a/src/core/nginx.c b/src/core/nginx.c index 796717ab9..4cc80826e 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -387,13 +387,8 @@ main(int argc, char *const *argv) return 1; } - if (!cycle->log_use_stderr && cycle->log->file->fd != ngx_stderr) { - - if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - ngx_set_stderr_n " failed"); - return 1; - } + if (ngx_log_redirect_stderr(cycle) != NGX_OK) { + return 1; } if (log->file->fd != ngx_stderr) { diff --git a/src/core/nginx.h b/src/core/nginx.h index e7105610c..396abacc5 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1005002 -#define NGINX_VERSION "1.5.2" +#define nginx_version 1005003 +#define NGINX_VERSION "1.5.3" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h index b0cb17fca..1da71f8d1 100644 --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -80,8 +80,8 @@ typedef uintptr_t ngx_uint_t; typedef intptr_t ngx_flag_t; -#define NGX_INT32_LEN sizeof("-2147483648") - 1 -#define NGX_INT64_LEN sizeof("-9223372036854775808") - 1 +#define NGX_INT32_LEN (sizeof("-2147483648") - 1) +#define NGX_INT64_LEN (sizeof("-9223372036854775808") - 1) #if (NGX_PTR_SIZE == 4) #define NGX_INT_T_LEN NGX_INT32_LEN diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 7ed781e0a..e12d3efc0 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -41,7 +41,7 @@ ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen) ls->sockaddr = sa; ls->socklen = socklen; - len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1); + len = ngx_sock_ntop(sa, socklen, text, NGX_SOCKADDR_STRLEN, 1); ls->addr_text.len = len; switch (ls->sockaddr->sa_family) { @@ -152,7 +152,8 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle) return NGX_ERROR; } - len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data, len, 1); + len = ngx_sock_ntop(ls[i].sockaddr, ls[i].socklen, + ls[i].addr_text.data, len, 1); if (len == 0) { return NGX_ERROR; } @@ -463,16 +464,13 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle) void ngx_configure_listening_sockets(ngx_cycle_t *cycle) { - int keepalive; + int value; ngx_uint_t i; ngx_listening_t *ls; #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) struct accept_filter_arg af; #endif -#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) - int timeout; -#endif ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { @@ -502,39 +500,51 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle) } if (ls[i].keepalive) { - keepalive = (ls[i].keepalive == 1) ? 1 : 0; + value = (ls[i].keepalive == 1) ? 1 : 0; if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE, - (const void *) &keepalive, sizeof(int)) + (const void *) &value, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored", - keepalive, &ls[i].addr_text); + value, &ls[i].addr_text); } } #if (NGX_HAVE_KEEPALIVE_TUNABLE) if (ls[i].keepidle) { + value = ls[i].keepidle; + +#if (NGX_KEEPALIVE_FACTOR) + value *= NGX_KEEPALIVE_FACTOR; +#endif + if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE, - (const void *) &ls[i].keepidle, sizeof(int)) + (const void *) &value, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored", - ls[i].keepidle, &ls[i].addr_text); + value, &ls[i].addr_text); } } if (ls[i].keepintvl) { + value = ls[i].keepintvl; + +#if (NGX_KEEPALIVE_FACTOR) + value *= NGX_KEEPALIVE_FACTOR; +#endif + if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL, - (const void *) &ls[i].keepintvl, sizeof(int)) + (const void *) &value, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored", - ls[i].keepintvl, &ls[i].addr_text); + value, &ls[i].addr_text); } } @@ -647,20 +657,20 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle) if (ls[i].add_deferred || ls[i].delete_deferred) { if (ls[i].add_deferred) { - timeout = (int) (ls[i].post_accept_timeout / 1000); + value = (int) (ls[i].post_accept_timeout / 1000); } else { - timeout = 0; + value = 0; } if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, - &timeout, sizeof(int)) + &value, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, " "ignored", - timeout, &ls[i].addr_text); + value, &ls[i].addr_text); continue; } @@ -1033,6 +1043,7 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s, #if (NGX_HAVE_INET6) case AF_INET6: sin6 = (struct sockaddr_in6 *) c->local_sockaddr; + len = sizeof(struct sockaddr_in6); for (addr = 0, i = 0; addr == 0 && i < 16; i++) { addr |= sin6->sin6_addr.s6_addr[i]; @@ -1043,6 +1054,7 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s, default: /* AF_INET */ sin = (struct sockaddr_in *) c->local_sockaddr; + len = sizeof(struct sockaddr_in); addr = sin->sin_addr.s_addr; break; } @@ -1068,7 +1080,7 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s, return NGX_OK; } - s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, port); + s->len = ngx_sock_ntop(c->local_sockaddr, len, s->data, s->len, port); return NGX_OK; } diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index 44edbafd4..2c006bcb2 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -36,8 +36,6 @@ ngx_tls_key_t ngx_core_tls_key; static ngx_connection_t dumb; /* STUB */ -static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH); - ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) @@ -338,13 +336,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } - if (cycle->new_log.file == NULL) { - cycle->new_log.file = ngx_conf_open_file(cycle, &error_log); - if (cycle->new_log.file == NULL) { - goto failed; - } - - cycle->new_log.log_level = NGX_LOG_ERR; + if (ngx_log_open_default(cycle) != NGX_OK) { + goto failed; } /* open the new files */ @@ -583,13 +576,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) /* commit the new cycle configuration */ - if (!ngx_use_stderr && !cycle->log_use_stderr - && cycle->log->file->fd != ngx_stderr) - { - if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_set_stderr_n " failed"); - } + if (!ngx_use_stderr) { + (void) ngx_log_redirect_stderr(cycle); } pool->log = cycle->log; @@ -1230,13 +1218,7 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user) file[i].fd = fd; } - if (!cycle->log_use_stderr && cycle->log->file->fd != ngx_stderr) { - - if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_set_stderr_n " failed"); - } - } + (void) ngx_log_redirect_stderr(cycle); } diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 7757ab7d9..5dca72bc2 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -174,7 +174,8 @@ ngx_inet6_addr(u_char *p, size_t len, u_char *addr) size_t -ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port) +ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, size_t len, + ngx_uint_t port) { u_char *p; struct sockaddr_in *sin; @@ -230,9 +231,18 @@ ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port) case AF_UNIX: saun = (struct sockaddr_un *) sa; + /* on Linux sockaddr might not include sun_path at all */ + + if (socklen <= offsetof(struct sockaddr_un, sun_path)) { + p = ngx_snprintf(text, len, "unix:%Z"); + + } else { + p = ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path); + } + /* we do not include trailing zero in address length */ - return ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path) - text - 1; + return (p - text - 1); #endif @@ -1020,7 +1030,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) goto failed; } - len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1); + len = ngx_sock_ntop((struct sockaddr *) sin, rp->ai_addrlen, p, len, 1); u->addrs[i].name.len = len; u->addrs[i].name.data = p; @@ -1053,7 +1063,8 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) goto failed; } - len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1); + len = ngx_sock_ntop((struct sockaddr *) sin6, rp->ai_addrlen, p, + len, 1); u->addrs[i].name.len = len; u->addrs[i].name.data = p; @@ -1138,7 +1149,8 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) return NGX_ERROR; } - len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1); + len = ngx_sock_ntop((struct sockaddr *) sin, + sizeof(struct sockaddr_in), p, len, 1); u->addrs[i].name.len = len; u->addrs[i].name.data = p; diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h index 6a5a3687d..d8f44c1e7 100644 --- a/src/core/ngx_inet.h +++ b/src/core/ngx_inet.h @@ -107,8 +107,8 @@ in_addr_t ngx_inet_addr(u_char *text, size_t len); ngx_int_t ngx_inet6_addr(u_char *p, size_t len, u_char *addr); size_t ngx_inet6_ntop(u_char *p, u_char *text, size_t len); #endif -size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, - ngx_uint_t port); +size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, + size_t len, ngx_uint_t port); size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr); ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c index b35a43218..edf30043d 100644 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -363,6 +363,48 @@ ngx_log_init(u_char *prefix) } +ngx_int_t +ngx_log_open_default(ngx_cycle_t *cycle) +{ + static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH); + + if (cycle->new_log.file == NULL) { + cycle->new_log.file = ngx_conf_open_file(cycle, &error_log); + if (cycle->new_log.file == NULL) { + return NGX_ERROR; + } + + cycle->new_log.log_level = NGX_LOG_ERR; + } + + return NGX_OK; +} + + +ngx_int_t +ngx_log_redirect_stderr(ngx_cycle_t *cycle) +{ + ngx_fd_t fd; + + if (cycle->log_use_stderr) { + return NGX_OK; + } + + fd = cycle->log->file->fd; + + if (fd != ngx_stderr) { + if (ngx_set_stderr(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_set_stderr_n " failed"); + + return NGX_ERROR; + } + } + + return NGX_OK; +} + + static char * ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log) { diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h index 82e1e2451..878fb0a27 100644 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -225,6 +225,8 @@ ngx_log_t *ngx_log_init(u_char *prefix); void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...); void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...); u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err); +ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle); +ngx_int_t ngx_log_redirect_stderr(ngx_cycle_t *cycle); char *ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head); diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 6087d60da..e3f828da8 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -275,7 +275,8 @@ ngx_event_accept(ngx_event_t *ev) return; } - c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data, + c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, + c->addr_text.data, ls->addr_text_max_len, 0); if (c->addr_text.len == 0) { ngx_close_accepted_connection(c); diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c index 23097f33d..77076141c 100644 --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -878,7 +878,8 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve) goto failed; } - len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1); + len = ngx_sock_ntop((struct sockaddr *) sin, sizeof(struct sockaddr_in), + p, len, 1); ctx->addrs[i].name.len = len; ctx->addrs[i].name.data = p; diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c index 476d56e30..4dfb88f6d 100644 --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -454,7 +454,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) size_t bsize; ngx_int_t rc; ngx_uint_t flush, flushed, prev_last_shadow; - ngx_chain_t *out, **ll, *cl, file; + ngx_chain_t *out, **ll, *cl; ngx_connection_t *downstream; downstream = p->downstream; @@ -514,13 +514,10 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p) } if (p->cacheable && p->buf_to_file) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe write chain"); - file.buf = p->buf_to_file; - file.next = NULL; - - if (ngx_write_chain_to_temp_file(p->temp_file, &file) - == NGX_ERROR) - { + if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) { return NGX_ABORT; } } diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index 35dd07ec4..837b0bc98 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -368,6 +368,8 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) { goto failed; } + + r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED; } if (ctx->nomem) { @@ -620,8 +622,6 @@ ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r, return NGX_ERROR; } - r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED; - ctx->last_out = &ctx->out; ctx->crc32 = crc32(0L, Z_NULL, 0); ctx->flush = Z_NO_FLUSH; @@ -854,6 +854,8 @@ ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) *ctx->last_out = cl; ctx->last_out = &cl->next; + r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED; + return NGX_OK; } diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c index c36ad0ffb..bfff1bfc2 100644 --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -441,8 +441,11 @@ ngx_http_memcached_filter_init(void *data) u = ctx->request->upstream; if (u->headers_in.status_n != 404) { - u->length += NGX_HTTP_MEMCACHED_END; + u->length = u->headers_in.content_length_n + NGX_HTTP_MEMCACHED_END; ctx->rest = NGX_HTTP_MEMCACHED_END; + + } else { + u->length = 0; } return NGX_OK; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 2cf0133a3..a22ed0fcb 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1542,7 +1542,7 @@ ngx_http_proxy_input_filter_init(void *data) u->pipe->length = 3; /* "0" LF LF */ u->input_filter = ngx_http_proxy_non_buffered_chunked_filter; - u->length = -1; + u->length = 1; } else if (u->headers_in.content_length_n == 0) { /* empty body: special case as filter won't be called */ diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c index ed9c5f9e8..b15954759 100644 --- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -230,7 +230,8 @@ ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr) c = r->connection; - len = ngx_sock_ntop(addr->sockaddr, text, NGX_SOCKADDR_STRLEN, 0); + len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text, + NGX_SOCKADDR_STRLEN, 0); if (len == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c index e0b2c5b67..a4d666bed 100644 --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -261,66 +261,43 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return rc; } - if (ctx->copy_start != ctx->copy_end) { + if (ctx->saved.len) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "saved: \"%V\"", &ctx->saved); - if (ctx->saved.len) { + cl = ngx_chain_get_free_buf(r->pool, &ctx->free); + if (cl == NULL) { + return NGX_ERROR; + } - if (ctx->free) { - cl = ctx->free; - ctx->free = ctx->free->next; - b = cl->buf; - ngx_memzero(b, sizeof(ngx_buf_t)); + b = cl->buf; - } else { - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } + ngx_memzero(b, sizeof(ngx_buf_t)); - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } + b->pos = ngx_pnalloc(r->pool, ctx->saved.len); + if (b->pos == NULL) { + return NGX_ERROR; + } - cl->buf = b; - } + ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len); + b->last = b->pos + ctx->saved.len; + b->memory = 1; - b->pos = ngx_pnalloc(r->pool, ctx->saved.len); - if (b->pos == NULL) { - return NGX_ERROR; - } + *ctx->last_out = cl; + ctx->last_out = &cl->next; - ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len); - b->last = b->pos + ctx->saved.len; - b->memory = 1; + ctx->saved.len = 0; + } - *ctx->last_out = cl; - ctx->last_out = &cl->next; + if (ctx->copy_start != ctx->copy_end) { - ctx->saved.len = 0; + cl = ngx_chain_get_free_buf(r->pool, &ctx->free); + if (cl == NULL) { + return NGX_ERROR; } - if (ctx->free) { - cl = ctx->free; - ctx->free = ctx->free->next; - b = cl->buf; - - } else { - b = ngx_alloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - } + b = cl->buf; ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t)); @@ -335,7 +312,6 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) b->file_pos += b->pos - ctx->buf->pos; } - cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; } @@ -349,6 +325,11 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->copy_end = NULL; } + if (ctx->looked.len > (size_t) (ctx->pos - ctx->buf->pos)) { + ctx->saved.len = ctx->looked.len - (ctx->pos - ctx->buf->pos); + ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->saved.len); + } + if (rc == NGX_AGAIN) { continue; } @@ -356,16 +337,15 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) /* rc == NGX_OK */ - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - cl = ngx_alloc_chain_link(r->pool); + cl = ngx_chain_get_free_buf(r->pool, &ctx->free); if (cl == NULL) { return NGX_ERROR; } + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); if (ctx->sub.data == NULL) { @@ -386,8 +366,6 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) b->sync = 1; } - cl->buf = b; - cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; @@ -396,36 +374,47 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) continue; } - if (ctx->buf->last_buf || ngx_buf_in_memory(ctx->buf)) { + if (ctx->buf->last_buf && ctx->looked.len) { + cl = ngx_chain_get_free_buf(r->pool, &ctx->free); + if (cl == NULL) { + return NGX_ERROR; + } + + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->pos = ctx->looked.data; + b->last = b->pos + ctx->looked.len; + b->memory = 1; + + *ctx->last_out = cl; + ctx->last_out = &cl->next; + + ctx->looked.len = 0; + } + + if (ctx->buf->last_buf || ctx->buf->flush + || ngx_buf_in_memory(ctx->buf)) + { if (b == NULL) { - if (ctx->free) { - cl = ctx->free; - ctx->free = ctx->free->next; - b = cl->buf; - ngx_memzero(b, sizeof(ngx_buf_t)); - - } else { - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; + cl = ngx_chain_get_free_buf(r->pool, &ctx->free); + if (cl == NULL) { + return NGX_ERROR; } + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + b->sync = 1; - cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; } b->last_buf = ctx->buf->last_buf; + b->flush = ctx->buf->flush; b->shadow = ctx->buf; b->recycled = ctx->buf->recycled; @@ -518,7 +507,7 @@ static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) { u_char *p, *last, *copy_end, ch, match; - size_t looked; + size_t looked, i; ngx_http_sub_state_e state; if (ctx->once) { @@ -589,13 +578,11 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) looked++; if (looked == ctx->match.len) { - if ((size_t) (p - ctx->pos) < looked) { - ctx->saved.len = 0; - } ctx->state = sub_start_state; ctx->pos = p + 1; ctx->looked.len = 0; + ctx->saved.len = 0; ctx->copy_end = copy_end; if (ctx->copy_start == NULL && copy_end) { @@ -605,18 +592,53 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) return NGX_OK; } - } else if (ch == ctx->match.data[0]) { - copy_end = p; - ctx->looked.data[0] = *p; - looked = 1; - } else { - copy_end = p; - looked = 0; - state = sub_start_state; + /* + * check if there is another partial match in previously + * matched substring to catch cases like "aab" in "aaab" + */ + + ctx->looked.data[looked] = *p; + looked++; + + for (i = 1; i < looked; i++) { + if (ngx_strncasecmp(ctx->looked.data + i, + ctx->match.data, looked - i) + == 0) + { + break; + } + } + + if (i < looked) { + if (ctx->saved.len > i) { + ctx->saved.len = i; + } + + if ((size_t) (p + 1 - ctx->buf->pos) >= looked - i) { + copy_end = p + 1 - (looked - i); + } + + ngx_memmove(ctx->looked.data, ctx->looked.data + i, looked - i); + looked = looked - i; + + } else { + copy_end = p; + looked = 0; + state = sub_start_state; + } + + if (ctx->saved.len) { + p++; + goto out; + } } } + ctx->saved.len = 0; + +out: + ctx->state = state; ctx->pos = p; ctx->looked.len = looked; @@ -677,9 +699,6 @@ ngx_http_sub_create_conf(ngx_conf_t *cf) * set by ngx_pcalloc(): * * conf->match = { 0, NULL }; - * conf->sub = { 0, NULL }; - * conf->sub_lengths = NULL; - * conf->sub_values = NULL; * conf->types = { NULL }; * conf->types_keys = NULL; */ diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c index 3198b7aba..9e85693bc 100644 --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -104,6 +104,7 @@ static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf); static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf); static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child); +static ngx_int_t ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf); static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf); static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle); @@ -163,7 +164,7 @@ static ngx_command_t ngx_http_xslt_filter_commands[] = { static ngx_http_module_t ngx_http_xslt_filter_module_ctx = { - NULL, /* preconfiguration */ + ngx_http_xslt_filter_preconfiguration, /* preconfiguration */ ngx_http_xslt_filter_init, /* postconfiguration */ ngx_http_xslt_filter_create_main_conf, /* create main configuration */ @@ -1111,7 +1112,7 @@ ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) static ngx_int_t -ngx_http_xslt_filter_init(ngx_conf_t *cf) +ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf) { xmlInitParser(); @@ -1119,6 +1120,13 @@ ngx_http_xslt_filter_init(ngx_conf_t *cf) exsltRegisterAll(); #endif + return NGX_OK; +} + + +static ngx_int_t +ngx_http_xslt_filter_init(ngx_conf_t *cf) +{ ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_xslt_header_filter; diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index 77fb65373..71f17a8bb 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -261,13 +261,12 @@ header_in(r, key) sep = ';'; goto multi; } - - #if (NGX_HTTP_X_FORWARDED_FOR) +#if (NGX_HTTP_X_FORWARDED_FOR) if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) { sep = ','; goto multi; } - #endif +#endif if (hh->offset) { @@ -898,8 +897,7 @@ variable(r, name, value = NULL) var.len = len; var.data = lowcase; - - #if (NGX_DEBUG) +#if (NGX_DEBUG) if (value) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -908,8 +906,7 @@ variable(r, name, value = NULL) ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl variable: \"%V\"", &var); } - - #endif +#endif vv = ngx_http_get_variable(r, &var, hash); if (vv == NULL) { diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index b32a8842c..12a82eb9c 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -3033,7 +3033,7 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) #endif lsopt.wildcard = 1; - (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr, + (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr, NGX_SOCKADDR_STRLEN, 1); if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) { @@ -3984,7 +3984,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) lsopt.ipv6only = 1; #endif - (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr, + (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr, NGX_SOCKADDR_STRLEN, 1); for (n = 2; n < cf->args->nelts; n++) { @@ -4469,7 +4469,7 @@ static ngx_http_method_name_t ngx_methods_names[] = { { (u_char *) "COPY", (uint32_t) ~NGX_HTTP_COPY }, { (u_char *) "MOVE", (uint32_t) ~NGX_HTTP_MOVE }, { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS }, - { (u_char *) "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND }, + { (u_char *) "PROPFIND", (uint32_t) ~NGX_HTTP_PROPFIND }, { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH }, { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK }, { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK }, diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 64f31b2c3..ca738cbb6 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2733,7 +2733,7 @@ closed: ngx_log_error(NGX_LOG_INFO, c->log, err, "client prematurely closed connection"); - ngx_http_finalize_request(r, 0); + ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST); } diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c index acadaf232..f8136213a 100644 --- a/src/http/ngx_http_spdy.c +++ b/src/http/ngx_http_spdy.c @@ -2529,13 +2529,6 @@ ngx_http_spdy_init_request_body(ngx_http_request_t *r) return NGX_ERROR; } - if (rb->rest == 0) { - buf->in_file = 1; - buf->file = &tf->file; - } else { - rb->buf = buf; - } - } else { if (rb->rest == 0) { @@ -2546,10 +2539,10 @@ ngx_http_spdy_init_request_body(ngx_http_request_t *r) if (buf == NULL) { return NGX_ERROR; } - - rb->buf = buf; } + rb->buf = buf; + rb->bufs = ngx_alloc_chain_link(r->pool); if (rb->bufs == NULL) { return NGX_ERROR; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 16e660245..9e2830d07 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -1181,7 +1181,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) return; } - /* rc == NGX_OK || rc == NGX_AGAIN */ + /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */ c = u->peer.connection; @@ -1282,6 +1282,11 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, { ngx_int_t rc; + if (ngx_http_upstream_test_connect(c) != NGX_OK) { + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); + return; + } + if (ngx_ssl_create_connection(u->conf->ssl, c, NGX_SSL_BUFFER|NGX_SSL_CLIENT) != NGX_OK) @@ -1472,22 +1477,10 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) ngx_add_timer(c->read, u->conf->read_timeout); -#if 1 if (c->read->ready) { - - /* post aio operation */ - - /* - * TODO comment - * although we can post aio operation just in the end - * of ngx_http_upstream_connect() CHECK IT !!! - * it's better to do here because we postpone header buffer allocation - */ - ngx_http_upstream_process_header(r, u); return; } -#endif u->write_event_handler = ngx_http_upstream_dummy_handler; @@ -1694,8 +1687,7 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) } if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, - NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2007,7 +1999,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u) r->headers_out.content_length_n = u->headers_in.content_length_n; - u->length = u->headers_in.content_length_n; + u->length = -1; return NGX_OK; } @@ -2031,7 +2023,7 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r, if (rev->timedout) { ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); - ngx_http_upstream_finalize_request(r, u, NGX_ETIMEDOUT); + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT); return; } @@ -2157,7 +2149,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) r->limit_rate = 0; if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2171,7 +2163,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) { ngx_connection_error(c, ngx_socket_errno, "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2186,7 +2178,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) u->state->response_length += n; if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2197,7 +2189,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) u->buffer.last = u->buffer.start; if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2221,7 +2213,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) switch (ngx_http_test_predicates(r, u->conf->no_cache)) { case NGX_ERROR: - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; case NGX_DECLINED: @@ -2237,7 +2229,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) r->cache->file_cache = u->conf->cache->data; if (ngx_http_file_cache_create(r) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } } @@ -2298,7 +2290,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); if (p->temp_file == NULL) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2321,7 +2313,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) p->preread_bufs = ngx_alloc_chain_link(r->pool); if (p->preread_bufs == NULL) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2335,7 +2327,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) p->buf_to_file = ngx_calloc_buf(r->pool); if (p->buf_to_file == NULL) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2383,7 +2375,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) if (u->input_filter_init && u->input_filter_init(p->input_ctx) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2425,7 +2417,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) { ngx_connection_error(c, ngx_socket_errno, "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2441,7 +2433,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) { ngx_connection_error(u->peer.connection, ngx_socket_errno, "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2450,7 +2442,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) } if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2527,7 +2519,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, if (upstream->read->timedout || upstream->write->timedout) { ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT); return; } @@ -2550,7 +2542,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, if (b->start == NULL) { b->start = ngx_palloc(r->pool, u->conf->buffer_size); if (b->start == NULL) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2573,7 +2565,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, n = dst->send(dst, b->pos, size); if (n == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2628,7 +2620,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, if (ngx_handle_write_event(upstream->write, u->conf->send_lowat) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2640,7 +2632,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, } if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2654,12 +2646,12 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, if (ngx_handle_write_event(downstream->write, clcf->send_lowat) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2714,7 +2706,7 @@ ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r, if (c->read->timedout) { ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT); return; } @@ -2750,7 +2742,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, rc = ngx_http_output_filter(r, u->out_bufs); if (rc == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2761,13 +2753,27 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, if (u->busy_bufs == NULL) { if (u->length == 0 - || upstream->read->eof - || upstream->read->error) + || (upstream->read->eof && u->length == -1)) { ngx_http_upstream_finalize_request(r, u, 0); return; } + if (upstream->read->eof) { + ngx_log_error(NGX_LOG_ERR, upstream->log, 0, + "upstream prematurely closed connection"); + + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_BAD_GATEWAY); + return; + } + + if (upstream->read->error) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_BAD_GATEWAY); + return; + } + b->pos = b->start; b->last = b->start; } @@ -2787,7 +2793,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, u->state->response_length += n; if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } } @@ -2806,7 +2812,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, if (ngx_handle_write_event(downstream->write, clcf->send_lowat) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } } @@ -2819,7 +2825,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, } if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2910,14 +2916,14 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r) ngx_add_timer(wev, p->send_timeout); if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); } return; } if (ngx_event_pipe(p, wev->write) == NGX_ABORT) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } @@ -2935,14 +2941,14 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r) "http downstream delayed"); if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); } return; } if (ngx_event_pipe(p, 1) == NGX_ABORT) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } } @@ -2970,7 +2976,7 @@ ngx_http_upstream_process_upstream(ngx_http_request_t *r, } else { if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); return; } } @@ -2995,11 +3001,12 @@ ngx_http_upstream_process_request(ngx_http_request_t *r) if (p->upstream_eof || p->upstream_done) { - tf = u->pipe->temp_file; + tf = p->temp_file; if (u->headers_in.status_n == NGX_HTTP_OK + && (p->upstream_done || p->length == -1) && (u->headers_in.content_length_n == -1 - || (u->headers_in.content_length_n == tf->offset))) + || u->headers_in.content_length_n == tf->offset)) { ngx_http_upstream_store(r, u); u->store = 0; @@ -3012,15 +3019,16 @@ ngx_http_upstream_process_request(ngx_http_request_t *r) if (u->cacheable) { if (p->upstream_done) { - ngx_http_file_cache_update(r, u->pipe->temp_file); + ngx_http_file_cache_update(r, p->temp_file); } else if (p->upstream_eof) { - tf = u->pipe->temp_file; + tf = p->temp_file; - if (u->headers_in.content_length_n == -1 - || u->headers_in.content_length_n - == tf->offset - (off_t) r->cache->body_start) + if (p->length == -1 + && (u->headers_in.content_length_n == -1 + || u->headers_in.content_length_n + == tf->offset - (off_t) r->cache->body_start)) { ngx_http_file_cache_update(r, tf); @@ -3029,7 +3037,7 @@ ngx_http_upstream_process_request(ngx_http_request_t *r) } } else if (p->upstream_error) { - ngx_http_file_cache_free(r->cache, u->pipe->temp_file); + ngx_http_file_cache_free(r->cache, p->temp_file); } } @@ -3038,10 +3046,20 @@ ngx_http_upstream_process_request(ngx_http_request_t *r) if (p->upstream_done || p->upstream_eof || p->upstream_error) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http upstream exit: %p", p->out); -#if 0 - ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); -#endif - ngx_http_upstream_finalize_request(r, u, 0); + + if (p->upstream_done + || (p->upstream_eof && p->length == -1)) + { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (p->upstream_eof) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream prematurely closed connection"); + } + + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY); return; } } @@ -3051,7 +3069,7 @@ ngx_http_upstream_process_request(ngx_http_request_t *r) "http upstream downstream error"); if (!u->cacheable && !u->store && u->peer.connection) { - ngx_http_upstream_finalize_request(r, u, 0); + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); } } } @@ -3151,10 +3169,6 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http next upstream, %xi", ft_type); -#if 0 - ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); -#endif - if (u->peer.sockaddr) { if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403 @@ -3268,13 +3282,6 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, u->peer.connection = NULL; } -#if 0 - if (u->conf->busy_lock && !u->busy_locked) { - ngx_http_upstream_busy_lock(p); - return; - } -#endif - ngx_http_upstream_connect(r, u); } @@ -3295,6 +3302,7 @@ static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_int_t rc) { + ngx_uint_t flush; ngx_time_t *tp; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -3401,27 +3409,38 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, #endif - if (u->header_sent - && rc != NGX_HTTP_REQUEST_TIME_OUT - && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) - { - rc = 0; - } - if (rc == NGX_DECLINED) { return; } r->connection->log->action = "sending to client"; - if (rc == 0 - && !r->header_only -#if (NGX_HTTP_CACHE) - && !r->cached -#endif - ) + if (!u->header_sent + || rc == NGX_HTTP_REQUEST_TIME_OUT + || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST) { + ngx_http_finalize_request(r, rc); + return; + } + + flush = 0; + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + rc = NGX_ERROR; + flush = 1; + } + + if (r->header_only) { + ngx_http_finalize_request(r, rc); + return; + } + + if (rc == 0) { rc = ngx_http_send_special(r, NGX_HTTP_LAST); + + } else if (flush) { + r->keepalive = 0; + rc = ngx_http_send_special(r, NGX_HTTP_FLUSH); } ngx_http_finalize_request(r, rc); diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c index 3812e1517..350d2cdf9 100644 --- a/src/mail/ngx_mail.c +++ b/src/mail/ngx_mail.c @@ -465,7 +465,8 @@ ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport, addrs[i].conf.ssl = addr[i].ssl; #endif - len = ngx_sock_ntop(addr[i].sockaddr, buf, NGX_SOCKADDR_STRLEN, 1); + len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf, + NGX_SOCKADDR_STRLEN, 1); p = ngx_pnalloc(cf->pool, len); if (p == NULL) { @@ -513,7 +514,8 @@ ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport, addrs6[i].conf.ssl = addr[i].ssl; #endif - len = ngx_sock_ntop(addr[i].sockaddr, buf, NGX_SOCKADDR_STRLEN, 1); + len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf, + NGX_SOCKADDR_STRLEN, 1); p = ngx_pnalloc(cf->pool, len); if (p == NULL) { diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index be8673c29..4ee7c8dc3 100644 --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -439,7 +439,8 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ls->bind = 1; } else { - len = ngx_sock_ntop(sa, buf, NGX_SOCKADDR_STRLEN, 1); + len = ngx_sock_ntop(sa, ls->socklen, buf, + NGX_SOCKADDR_STRLEN, 1); ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "ipv6only is not supported " diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h index 9c97e2bb7..4e3ed7db4 100644 --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -72,8 +72,8 @@ typedef struct { #define NGX_FILE_RDWR O_RDWR #define NGX_FILE_CREATE_OR_OPEN O_CREAT #define NGX_FILE_OPEN 0 -#define NGX_FILE_TRUNCATE O_CREAT|O_TRUNC -#define NGX_FILE_APPEND O_WRONLY|O_APPEND +#define NGX_FILE_TRUNCATE (O_CREAT|O_TRUNC) +#define NGX_FILE_APPEND (O_WRONLY|O_APPEND) #define NGX_FILE_NONBLOCK O_NONBLOCK #if (NGX_HAVE_OPENAT) @@ -86,13 +86,13 @@ typedef struct { #endif #if defined(O_SEARCH) -#define NGX_FILE_SEARCH O_SEARCH|NGX_FILE_DIRECTORY +#define NGX_FILE_SEARCH (O_SEARCH|NGX_FILE_DIRECTORY) #elif defined(O_EXEC) -#define NGX_FILE_SEARCH O_EXEC|NGX_FILE_DIRECTORY +#define NGX_FILE_SEARCH (O_EXEC|NGX_FILE_DIRECTORY) #else -#define NGX_FILE_SEARCH O_RDONLY|NGX_FILE_DIRECTORY +#define NGX_FILE_SEARCH (O_RDONLY|NGX_FILE_DIRECTORY) #endif #endif /* NGX_HAVE_OPENAT */ diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h index 5b3ff278c..248e7a731 100644 --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -94,6 +94,11 @@ typedef struct aiocb ngx_aiocb_t; #define NGX_LISTEN_BACKLOG -1 +#ifdef __DragonFly__ +#define NGX_KEEPALIVE_FACTOR 1000 +#endif + + #if (__FreeBSD_version < 430000 || __FreeBSD_version < 500012) pid_t rfork_thread(int flags, void *stack, int (*func)(void *arg), void *arg); diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 8ada10652..9d23a73d0 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -536,7 +536,7 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo) } ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, - "kill (%P, %d)" , ngx_processes[i].pid, signo); + "kill (%P, %d)", ngx_processes[i].pid, signo); if (kill(ngx_processes[i].pid, signo) == -1) { err = ngx_errno; diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c index 7b6badfa8..c2c21b407 100644 --- a/src/os/unix/ngx_readv_chain.c +++ b/src/os/unix/ngx_readv_chain.c @@ -136,7 +136,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain) return n; } - if (n < size) { + if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { rev->ready = 0; } diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c index 6a4a09966..1640cdb27 100644 --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -87,7 +87,9 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) return n; } - if ((size_t) n < size) { + if ((size_t) n < size + && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) + { rev->ready = 0; } |