summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-02-11 15:24:26 +0000
committerJonathan Kolb <jon@b0g.us>2008-02-11 15:24:26 +0000
commit2ef4ceba25a749bcf048b03863a4424ff64eb466 (patch)
treea130392ba645b05b8d7e20aeaf4fffe49446e2cf
parentff0f3a24f75d926146615335500f7619e70824a0 (diff)
downloadnginx-2ef4ceba25a749bcf048b03863a4424ff64eb466.tar.gz
Changes with nginx 0.6.26 11 Feb 2008v0.6.26
*) Bugfix: the "proxy_store" and "fastcgi_store" directives did not check a response length. *) Bugfix: a segmentation fault occurred in worker process, if big value was used in a "expires" directive. Thanks to Joaquin Cuenca Abela. *) Bugfix: nginx incorrectly detected cache line size on Pentium 4. Thanks to Gena Makhomed. *) Bugfix: in proxied or FastCGI subrequests a client original method was used instead of the GET method. *) Bugfix: socket leak in HTTPS mode if deferred accept was used. Thanks to Ben Maurer. *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed (SSL: )"; bug appeared in 0.6.23. *) Bugfix: in HTTPS mode requests might fail with the "bad write retry" error; bug appeared in 0.6.23.
-rw-r--r--CHANGES25
-rw-r--r--CHANGES.ru28
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_connection.c3
-rw-r--r--src/core/ngx_cpuinfo.c11
-rw-r--r--src/core/ngx_inet.c2
-rw-r--r--src/core/ngx_resolver.c7
-rw-r--r--src/core/ngx_string.c10
-rw-r--r--src/core/ngx_times.c17
-rw-r--r--src/event/modules/ngx_eventport_module.c11
-rw-r--r--src/event/modules/ngx_rtsig_module.c3
-rw-r--r--src/event/ngx_event_connect.c8
-rw-r--r--src/event/ngx_event_openssl.c66
-rw-r--r--src/http/modules/ngx_http_dav_module.c2
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c57
-rw-r--r--src/http/modules/ngx_http_proxy_module.c3
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c7
-rw-r--r--src/http/ngx_http_request.c12
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/http/ngx_http_upstream.c17
-rw-r--r--src/http/ngx_http_upstream.h2
-rw-r--r--src/http/ngx_http_upstream_round_robin.c2
-rw-r--r--src/os/unix/ngx_errno.h3
-rw-r--r--src/os/unix/ngx_recv.c1
25 files changed, 220 insertions, 83 deletions
diff --git a/CHANGES b/CHANGES
index 8cb3e8608..1b24142ac 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,29 @@
+Changes with nginx 0.6.26 11 Feb 2008
+
+ *) Bugfix: the "proxy_store" and "fastcgi_store" directives did not
+ check a response length.
+
+ *) Bugfix: a segmentation fault occurred in worker process, if big
+ value was used in a "expires" directive.
+ Thanks to Joaquin Cuenca Abela.
+
+ *) Bugfix: nginx incorrectly detected cache line size on Pentium 4.
+ Thanks to Gena Makhomed.
+
+ *) Bugfix: in proxied or FastCGI subrequests a client original method
+ was used instead of the GET method.
+
+ *) Bugfix: socket leak in HTTPS mode if deferred accept was used.
+ Thanks to Ben Maurer.
+
+ *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed
+ (SSL: )"; bug appeared in 0.6.23.
+
+ *) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
+ error; bug appeared in 0.6.23.
+
+
Changes with nginx 0.6.25 08 Jan 2008
*) Change: now the "server_name_in_redirect" directive is used instead
diff --git a/CHANGES.ru b/CHANGES.ru
index 45a7196d2..f819f8262 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,32 @@
+Изменения в nginx 0.6.26 11.02.2008
+
+ *) Исправление: директивы proxy_store и fastcgi_store не проверяли
+ длину ответа.
+
+ *) Исправление: при использовании большого значения в директиве expires
+ в рабочем процессе происходил segmentation fault.
+ Спасибо Joaquin Cuenca Abela.
+
+ *) Исправление: nginx неверно определял длину строки кэша на
+ Pentium 4.
+ Спасибо Gena Makhomed.
+
+ *) Исправление: в проксированных подзапросах и подзапросах к
+ FastCGI-серверу вместо метода GET использовался оригинальный метод
+ клиента.
+
+ *) Исправление: утечки сокетов в режиме HTTPS при использовании
+ отложенного accept'а.
+ Спасибо Ben Maurer.
+
+ *) Исправление: nginx выдавал ошибочное сообщение "SSL_shutdown()
+ failed (SSL: )"; ошибка появилась в 0.6.23.
+
+ *) Исправление: при использовании HTTPS запросы могли завершаться с
+ ошибкой "bad write retry"; ошибка появилась в 0.6.23.
+
+
Изменения в nginx 0.6.25 08.01.2008
*) Изменение: вместо специального параметра "*" в директиве server_name
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 7e7dd10fa..c62b15bd4 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.25"
+#define NGINX_VERSION "0.6.26"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index e0a6ba23a..b31daaa57 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -767,6 +767,9 @@ ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
|| err == NGX_ENOTCONN
|| err == NGX_ETIMEDOUT
|| err == NGX_ECONNREFUSED
+ || err == NGX_ENETDOWN
+ || err == NGX_ENETUNREACH
+ || err == NGX_EHOSTDOWN
|| err == NGX_EHOSTUNREACH)
{
switch (c->log_error) {
diff --git a/src/core/ngx_cpuinfo.c b/src/core/ngx_cpuinfo.c
index 2ed26b8d4..68eb094c9 100644
--- a/src/core/ngx_cpuinfo.c
+++ b/src/core/ngx_cpuinfo.c
@@ -92,13 +92,22 @@ ngx_cpuinfo(void)
if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
- switch (cpu[0] & 0xf00) {
+ switch ((cpu[0] & 0xf00) >> 8) {
/* Pentium */
case 5:
+ ngx_cacheline_size = 32;
+ break;
+
/* Pentium Pro, II, III */
case 6:
ngx_cacheline_size = 32;
+
+ if ((cpu[0] & 0xf0) >= 0xd0) {
+ /* Intel Core */
+ ngx_cacheline_size = 64;
+ }
+
break;
/*
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index ca6c5f6e8..f54a05721 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -212,7 +212,7 @@ ngx_sprint_uchar(u_char *text, u_char c, size_t len)
c2 = c % 10;
- *text++ = (u_char) (c2 + '0');
+ *text = (u_char) (c2 + '0');
n++;
return n;
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index ef2c92ba4..ade500533 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -215,10 +215,9 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
if (ctx->event) {
ngx_resolver_free_locked(r, ctx->event);
+ ctx->event = NULL;
}
- ngx_resolver_free_locked(r, ctx);
-
/* unlock alloc mutex */
return NGX_ERROR;
@@ -787,9 +786,9 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
rn->expire = now + r->resend_timeout;
ngx_queue_insert_head(queue, &rn->queue);
-
- continue;
}
+
+ continue;
}
ngx_rbtree_delete(tree, &rn->node);
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index d9a5480da..acd9382dd 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -147,7 +147,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
sign = 1;
hexadecimal = 0;
max_width = 0;
- slen = 0;
+ slen = (size_t) -1;
p = temp + NGX_INT64_LEN;
@@ -182,7 +182,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
continue;
case '*':
- slen = va_arg(args, u_int);
+ slen = va_arg(args, size_t);
fmt++;
continue;
@@ -221,13 +221,15 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
case 's':
p = va_arg(args, u_char *);
- if (slen == 0) {
+ if (slen == (size_t) -1) {
while (*p && buf < last) {
*buf++ = *p++;
}
} else {
- buf = ngx_cpymem(buf, p, slen);
+ len = (buf + slen < last) ? slen : (size_t) (last - buf);
+
+ buf = ngx_cpymem(buf, p, len);
}
fmt++;
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 949e0c6f7..1ba1210f0 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -203,18 +203,21 @@ ngx_http_cookie_time(u_char *buf, time_t t)
void
ngx_gmtime(time_t t, ngx_tm_t *tp)
{
- ngx_int_t sec, min, hour, mday, mon, year, wday, yday, days;
+ ngx_uint_t n, sec, min, hour, mday, mon, year, wday, yday, days;
- days = (ngx_int_t) (t / 86400);
+ /* the calculation is valid for positive time_t only */
+ n = (ngx_uint_t) t;
+
+ days = n / 86400;
/* Jaunary 1, 1970 was Thursday */
wday = (4 + days) % 7;
- t %= 86400;
- hour = (ngx_int_t) (t / 3600);
- t %= 3600;
- min = (ngx_int_t) (t / 60);
- sec = (ngx_int_t) (t % 60);
+ n %= 86400;
+ hour = n / 3600;
+ n %= 3600;
+ min = n / 60;
+ sec = n % 60;
/* the algorithm based on Gauss's formula */
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index 85cd1958d..f9a8e88a4 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -40,11 +40,6 @@ typedef struct port_notify {
void *portnfy_user; /* user defined */
} port_notify_t;
-typedef struct itimerspec { /* definition per POSIX.4 */
- struct timespec it_interval;/* timer period */
- struct timespec it_value; /* timer expiration */
-} itimerspec_t;
-
int port_create(void)
{
return -1;
@@ -106,7 +101,7 @@ static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);
static int ep = -1;
static port_event_t *event_list;
static ngx_uint_t nevents;
-static timer_t event_timer = -1;
+static timer_t event_timer = (timer_t) -1;
static ngx_str_t eventport_name = ngx_string("eventport");
@@ -237,13 +232,13 @@ ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer)
static void
ngx_eventport_done(ngx_cycle_t *cycle)
{
- if (event_timer != -1) {
+ if (event_timer != (timer_t) -1) {
if (timer_delete(event_timer) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"timer_delete() failed");
}
- event_timer = -1;
+ event_timer = (timer_t) -1;
}
if (close(ep) == -1) {
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index 761ebe68c..c753854ff 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -12,8 +12,7 @@
#if (NGX_TEST_BUILD_RTSIG)
#define F_SETSIG 10
-#define SIGRTMIN 33
-#define si_fd __spare__[0]
+#define si_fd _reason.__spare__.__spare2__[0]
#define KERN_RTSIGNR 30
#define KERN_RTSIGMAX 31
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index d8bd7f4a2..5ae7b23bf 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -143,8 +143,14 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
if (err != NGX_EINPROGRESS && err != NGX_EAGAIN) {
- if (err == NGX_ECONNREFUSED || err == NGX_EHOSTUNREACH) {
+ if (err == NGX_ECONNREFUSED
+ || err == NGX_ENETDOWN
+ || err == NGX_ENETUNREACH
+ || err == NGX_EHOSTDOWN
+ || err == NGX_EHOSTUNREACH)
+ {
level = NGX_LOG_ERR;
+
} else {
level = NGX_LOG_CRIT;
}
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index d7fc4d223..8ba3e8e39 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -187,6 +187,13 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
}
+ /*
+ * we need this option because in ngx_ssl_send_chain()
+ * we may switch to a buffered write and may copy leftover part of
+ * previously unbuffered data to our internal buffer
+ */
+ SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+
SSL_CTX_set_read_ahead(ssl->ctx, 1);
return NGX_OK;
@@ -1035,19 +1042,16 @@ ngx_ssl_shutdown(ngx_connection_t *c)
sslerr = 0;
- /* SSL_shutdown() never return -1, on error it return 0 */
+ /* SSL_shutdown() never returns -1, on error it returns 0 */
- if (n != 1) {
+ if (n != 1 && ERR_peek_error()) {
sslerr = SSL_get_error(c->ssl->connection, n);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL_get_error: %d", sslerr);
}
- if (n == 1
- || sslerr == SSL_ERROR_ZERO_RETURN
- || (sslerr == 0 && c->timedout))
- {
+ if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
SSL_free(c->ssl->connection);
c->ssl = NULL;
@@ -1111,6 +1115,7 @@ static void
ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
char *text)
{
+ int n;
ngx_uint_t level;
level = NGX_LOG_CRIT;
@@ -1124,6 +1129,9 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|| err == NGX_ETIMEDOUT
#endif
|| err == NGX_ECONNREFUSED
+ || err == NGX_ENETDOWN
+ || err == NGX_ENETUNREACH
+ || err == NGX_EHOSTDOWN
|| err == NGX_EHOSTUNREACH)
{
switch (c->log_error) {
@@ -1141,6 +1149,35 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
break;
}
}
+
+ } else if (sslerr == SSL_ERROR_SSL) {
+
+ n = ERR_GET_REASON(ERR_peek_error());
+
+ /* handshake failures */
+ if (n == SSL_R_NO_SHARED_CIPHER
+ || n == SSL_R_UNEXPECTED_MESSAGE
+ || n == SSL_R_WRONG_VERSION_NUMBER
+ || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
+ || n == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED
+ || n == SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER
+ || n == SSL_R_TLSV1_ALERT_UNKNOWN_CA)
+ {
+ switch (c->log_error) {
+
+ case NGX_ERROR_IGNORE_ECONNRESET:
+ case NGX_ERROR_INFO:
+ level = NGX_LOG_INFO;
+ break;
+
+ case NGX_ERROR_ERR:
+ level = NGX_LOG_ERR;
+ break;
+
+ default:
+ break;
+ }
+ }
}
ngx_ssl_error(level, c->log, err, text);
@@ -1150,18 +1187,21 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
static void
ngx_ssl_clear_error(ngx_log_t *log)
{
- if (ERR_peek_error()) {
+ while (ERR_peek_error()) {
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
}
+
+ ERR_clear_error();
}
void ngx_cdecl
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
{
- u_long n;
- va_list args;
- u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
+ u_long n;
+ va_list args;
+ u_char *p, *last;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
last = errstr + NGX_MAX_CONF_ERRSTR;
@@ -1171,7 +1211,7 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);
- while (p < last) {
+ for ( ;; ) {
n = ERR_get_error();
@@ -1179,6 +1219,10 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
break;
}
+ if (p >= last) {
+ continue;
+ }
+
*p++ = ' ';
ERR_error_string_n(n, (char *) p, last - p);
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 09dac0ef4..e597923e0 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -1140,7 +1140,7 @@ ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
* conf->methods = 0;
*/
- conf->min_delete_depth = NGX_CONF_UNSET;
+ conf->min_delete_depth = NGX_CONF_UNSET_UINT;
conf->access = NGX_CONF_UNSET_UINT;
conf->create_full_put_path = NGX_CONF_UNSET;
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 8cfef63c9..b912e19b7 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -135,33 +135,6 @@ static char *ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
-static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
- { 1, /* version */
- NGX_HTTP_FASTCGI_BEGIN_REQUEST, /* type */
- 0, /* request_id_hi */
- 1, /* request_id_lo */
- 0, /* content_length_hi */
- sizeof(ngx_http_fastcgi_begin_request_t), /* content_length_lo */
- 0, /* padding_length */
- 0 }, /* reserved */
-
- { 0, /* role_hi */
- NGX_HTTP_FASTCGI_RESPONDER, /* role_lo */
- 0, /* NGX_HTTP_FASTCGI_KEEP_CONN */ /* flags */
- { 0, 0, 0, 0, 0 } }, /* reserved[5] */
-
- { 1, /* version */
- NGX_HTTP_FASTCGI_PARAMS, /* type */
- 0, /* request_id_hi */
- 1 }, /* request_id_lo */
-
-};
-
-
-static ngx_str_t ngx_http_fastcgi_script_name =
- ngx_string("fastcgi_script_name");
-
-
static ngx_conf_post_t ngx_http_fastcgi_lowat_post =
{ ngx_http_fastcgi_lowat_check };
@@ -412,12 +385,40 @@ ngx_module_t ngx_http_fastcgi_module = {
};
+static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
+ { 1, /* version */
+ NGX_HTTP_FASTCGI_BEGIN_REQUEST, /* type */
+ 0, /* request_id_hi */
+ 1, /* request_id_lo */
+ 0, /* content_length_hi */
+ sizeof(ngx_http_fastcgi_begin_request_t), /* content_length_lo */
+ 0, /* padding_length */
+ 0 }, /* reserved */
+
+ { 0, /* role_hi */
+ NGX_HTTP_FASTCGI_RESPONDER, /* role_lo */
+ 0, /* NGX_HTTP_FASTCGI_KEEP_CONN */ /* flags */
+ { 0, 0, 0, 0, 0 } }, /* reserved[5] */
+
+ { 1, /* version */
+ NGX_HTTP_FASTCGI_PARAMS, /* type */
+ 0, /* request_id_hi */
+ 1 }, /* request_id_lo */
+
+};
+
+
+static ngx_str_t ngx_http_fastcgi_script_name =
+ ngx_string("fastcgi_script_name");
+
+
static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
ngx_string("Status"),
ngx_string("X-Accel-Expires"),
ngx_string("X-Accel-Redirect"),
ngx_string("X-Accel-Limit-Rate"),
- ngx_string("X-Accel-Buffer"),
+ ngx_string("X-Accel-Buffering"),
+ ngx_string("X-Accel-Charset"),
ngx_null_string
};
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 0849668ee..d3f4c60ea 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -435,7 +435,8 @@ static ngx_str_t ngx_http_proxy_hide_headers[] = {
ngx_string("X-Accel-Expires"),
ngx_string("X-Accel-Redirect"),
ngx_string("X-Accel-Limit-Rate"),
- ngx_string("X-Accel-Buffer"),
+ ngx_string("X-Accel-Buffering"),
+ ngx_string("X-Accel-Charset"),
ngx_null_string
};
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index aec158b04..f20be2e6e 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.6.25';
+our $VERSION = '0.6.26';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 27e723a5d..8a9a4769d 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -652,6 +652,9 @@ ngx_module_t ngx_http_core_module = {
};
+static ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " };
+
+
void
ngx_http_handler(ngx_http_request_t *r)
{
@@ -1760,7 +1763,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
sr->unparsed_uri = r->unparsed_uri;
- sr->method_name = r->method_name;
+ sr->method_name = ngx_http_core_get_method;
sr->http_protocol = r->http_protocol;
if (ngx_http_set_exten(sr) != NGX_OK) {
@@ -2909,7 +2912,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->resolver == NULL) {
conf->resolver = ngx_resolver_create(NULL, cf->cycle->new_log);
if (conf->resolver == NULL) {
- return NGX_OK;
+ return NGX_CONF_ERROR;
}
}
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index bb21b71b2..4d21a002a 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -479,6 +479,15 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
+
+ if (!rev->timer_set) {
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
+ }
+
+ if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ }
+
return;
}
@@ -985,10 +994,9 @@ ngx_http_read_request_header(ngx_http_request_t *r)
}
if (n == NGX_AGAIN) {
- if (!r->header_timeout_set) {
+ if (!rev->timer_set) {
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
ngx_add_timer(rev, cscf->client_header_timeout);
- r->header_timeout_set = 1;
}
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index db1292b8c..9073be928 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -427,8 +427,6 @@ struct ngx_http_request_s {
unsigned fast_subrequest:1;
unsigned subrequest_in_memory:1;
- unsigned header_timeout_set:1;
-
unsigned gzip:2;
unsigned proxy:1;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index cb9bcd044..89240c0b1 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1352,6 +1352,8 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
r->headers_out.status = u->headers_in.status_n;
r->headers_out.status_line = u->headers_in.status_line;
+ u->headers_in.content_length_n = r->headers_out.content_length_n;
+
if (r->headers_out.content_length_n != -1) {
u->length = (size_t) r->headers_out.content_length_n;
@@ -1955,6 +1957,7 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
static void
ngx_http_upstream_process_body(ngx_event_t *ev)
{
+ ngx_temp_file_t *tf;
ngx_event_pipe_t *p;
ngx_connection_t *c, *downstream;
ngx_http_log_ctx_t *ctx;
@@ -2049,18 +2052,22 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
if (u->store) {
- if (p->upstream_eof && u->headers_in.status_n == NGX_HTTP_OK) {
+ tf = u->pipe->temp_file;
+ if (p->upstream_eof
+ && u->headers_in.status_n == NGX_HTTP_OK
+ && (u->headers_in.content_length_n == -1
+ || (u->headers_in.content_length_n == tf->offset)))
+ {
ngx_http_upstream_store(r, u);
} else if ((p->upstream_error
|| (p->upstream_eof
&& u->headers_in.status_n != NGX_HTTP_OK))
- && u->pipe->temp_file->file.fd != NGX_INVALID_FILE)
+ && tf->file.fd != NGX_INVALID_FILE)
{
- if (ngx_delete_file(u->pipe->temp_file->file.name.data)
- == NGX_FILE_ERROR)
- {
+ if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
+
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_delete_file_n " \"%s\" failed",
u->pipe->temp_file->file.name.data);
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index a7a9a6351..15615caec 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -192,6 +192,8 @@ typedef struct {
ngx_table_elt_t *content_encoding;
#endif
+ off_t content_length_n;
+
ngx_array_t cache_control;
} ngx_http_upstream_headers_in_t;
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index 79747f6c4..c25c076b4 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -605,7 +605,7 @@ ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers)
}
for (i = 0; i < peers->number; i++) {
- peer[i].current_weight += peer[i].weight;
+ peer[i].current_weight = peer[i].weight;
}
}
}
diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h
index b941a43eb..c50d7879a 100644
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -37,6 +37,9 @@ typedef int ngx_err_t;
#define NGX_ETIMEDOUT ETIMEDOUT
#define NGX_ECONNREFUSED ECONNREFUSED
#define NGX_ENAMETOOLONG ENAMETOOLONG
+#define NGX_ENETDOWN ENETDOWN
+#define NGX_ENETUNREACH ENETUNREACH
+#define NGX_EHOSTDOWN EHOSTDOWN
#define NGX_EHOSTUNREACH EHOSTUNREACH
#define NGX_ENOSYS ENOSYS
#define NGX_ECANCELED ECANCELED
diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c
index 6361b3ce0..f4d6a2bcc 100644
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -41,6 +41,7 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
return 0;
} else {
+ rev->ready = 0;
return NGX_AGAIN;
}
}