summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-05-04 11:17:51 +0000
committerJonathan Kolb <jon@b0g.us>2008-05-04 11:17:51 +0000
commitc7ca0c3d39814ee70bb3bf513dbf3b94e2110111 (patch)
tree37589a43e3d2c14febf88075bb41b61d8c69e45b
parent9eddf800bf2de94f105b8877e290fb0f2250b04b (diff)
downloadnginx-0.5.36.tar.gz
Changes with nginx 0.5.36 04 May 2008v0.5.36
*) Bugfix: the "sub_filter" directive might set text to change into output. *) Bugfix: a segmentation fault occurred in worker process, if empty stub block was used second time in SSI. *) Bugfix: the "proxy_store" and "fastcgi_store" directives did not check a response length. *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed (SSL: )"; bug appeared in 0.5.35. *) Bugfix: in HTTPS mode requests might fail with the "bad write retry" error; bug appeared in 0.5.35. *) Bugfix: the "fastcgi_catch_stderr" directive did return error code; now it returns 502 code, that can be rerouted to a next server using the "fastcgi_next_upstream invalid_header" directive. *) Bugfix: a segmentation fault occurred in master process if the "fastcgi_catch_stderr" directive was used; bug appeared in 0.5.32. Thanks to Manlio Perillo.
-rw-r--r--CHANGES30
-rw-r--r--CHANGES.ru27
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_conf_file.c2
-rw-r--r--src/event/modules/ngx_eventport_module.c10
-rw-r--r--src/event/modules/ngx_rtsig_module.c7
-rw-r--r--src/event/ngx_event_openssl.c31
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c132
-rw-r--r--src/http/modules/ngx_http_proxy_module.c122
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c1
-rw-r--r--src/http/modules/ngx_http_sub_filter_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_upstream.c130
-rw-r--r--src/http/ngx_http_upstream.h5
14 files changed, 262 insertions, 241 deletions
diff --git a/CHANGES b/CHANGES
index dd43c080f..bcdf23438 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,31 @@
+Changes with nginx 0.5.36 04 May 2008
+
+ *) Bugfix: the "sub_filter" directive might set text to change into
+ output.
+
+ *) Bugfix: a segmentation fault occurred in worker process, if empty
+ stub block was used second time in SSI.
+
+ *) Bugfix: the "proxy_store" and "fastcgi_store" directives did not
+ check a response length.
+
+ *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed
+ (SSL: )"; bug appeared in 0.5.35.
+
+ *) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
+ error; bug appeared in 0.5.35.
+
+ *) Bugfix: the "fastcgi_catch_stderr" directive did return error code;
+ now it returns 502 code, that can be rerouted to a next server using
+ the "fastcgi_next_upstream invalid_header" directive.
+
+ *) Bugfix: a segmentation fault occurred in master process if the
+ "fastcgi_catch_stderr" directive was used; bug appeared in
+ 0.5.32.
+ Thanks to Manlio Perillo.
+
+
Changes with nginx 0.5.35 08 Jan 2008
*) Change: now the ngx_http_userid_module adds start time microseconds
@@ -344,7 +371,8 @@ Changes with nginx 0.5.20 07 May 2007
Studio.
Thanks to Andrei Nigmatulin.
- *) Bugfix: the ngx_http_perl_module could not built by Solaris make.
+ *) Bugfix: the ngx_http_perl_module could not be built by Solaris
+ make.
Thanks to Andrei Nigmatulin.
diff --git a/CHANGES.ru b/CHANGES.ru
index e33342c46..707748d49 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,31 @@
+Изменения в nginx 0.5.36 04.05.2008
+
+ *) Исправление: директива sub_filter могла вставлять заменяемый текст в
+ вывод.
+
+ *) Исправление: при повторном использовании в SSI пустого block'а в
+ качестве заглушки в рабочем процессе происходил segmentation fault.
+
+ *) Исправление: директивы proxy_store и fastcgi_store не проверяли
+ длину ответа.
+
+ *) Исправление: nginx выдавал ошибочное сообщение "SSL_shutdown()
+ failed (SSL: )"; ошибка появилась в 0.5.35.
+
+ *) Исправление: при использовании HTTPS запросы могли завершаться с
+ ошибкой "bad write retry"; ошибка появилась в 0.5.35.
+
+ *) Исправление: директива fastcgi_catch_stderr не возвращала ошибку;
+ теперь она возвращает ошибку 502, которую можно направить на
+ следующий сервер с помощью "fastcgi_next_upstream invalid_header".
+
+ *) Исправление: при использовании директивы fastcgi_catch_stderr в
+ основном процессе происходил segmentation fault; ошибка появилась в
+ 0.5.32.
+ Спасибо Manlio Perillo.
+
+
Изменения в nginx 0.5.35 08.01.2008
*) Изменение: теперь модуль ngx_http_userid_module в поле куки с
diff --git a/src/core/nginx.h b/src/core/nginx.h
index cf3e5d21a..50e943c8c 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.5.35"
+#define NGINX_VERSION "0.5.36"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index c5cfded99..90cd30c9b 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -925,7 +925,7 @@ ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
a = (ngx_array_t **) (p + cmd->offset);
- if (*a == NULL) {
+ if (*a == NGX_CONF_UNSET_PTR) {
*a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
if (*a == NULL) {
return NGX_CONF_ERROR;
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index 85cd1958d..4becf75d0 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -40,11 +40,15 @@ typedef struct port_notify {
void *portnfy_user; /* user defined */
} port_notify_t;
+#if (__FreeBSD_version < 700005)
+
typedef struct itimerspec { /* definition per POSIX.4 */
struct timespec it_interval;/* timer period */
struct timespec it_value; /* timer expiration */
} itimerspec_t;
+#endif
+
int port_create(void)
{
return -1;
@@ -106,7 +110,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 +241,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..6020936b7 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -11,9 +11,14 @@
#if (NGX_TEST_BUILD_RTSIG)
-#define F_SETSIG 10
+#ifdef SIGRTMIN
+#define si_fd _reason.__spare__.__spare2__[0]
+#else
#define SIGRTMIN 33
#define si_fd __spare__[0]
+#endif
+
+#define F_SETSIG 10
#define KERN_RTSIGNR 30
#define KERN_RTSIGMAX 31
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 26411cb89..dad71f91e 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;
@@ -1000,17 +1007,14 @@ ngx_ssl_shutdown(ngx_connection_t *c)
/* SSL_shutdown() never return -1, on error it return 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;
@@ -1113,18 +1117,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;
@@ -1134,7 +1141,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();
@@ -1142,6 +1149,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_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index df8054466..15909fca6 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -885,7 +885,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
if (f == NULL) {
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
if (f == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
@@ -993,7 +993,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
for (i = 0; i < flcf->catch_stderr->nelts; i++) {
if (ngx_strstr(line.data, pattern[i].data)) {
- return NGX_HTTP_BAD_GATEWAY;
+ return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
}
}
@@ -1061,7 +1061,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h = ngx_list_push(&u->headers_in.headers);
if (h == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
if (f->split_parts && f->split_parts->nelts) {
@@ -1075,7 +1075,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
p = ngx_palloc(r->pool, size);
if (p == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
buf.pos = p;
@@ -1103,7 +1103,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h->lowcase_key = ngx_palloc(r->pool, h->key.len);
if (h->lowcase_key == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
} else {
@@ -1115,7 +1115,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h->key.len + 1 + h->value.len + 1
+ h->key.len);
if (h->key.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
@@ -1143,7 +1143,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h->lowcase_key, h->key.len);
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1172,7 +1172,10 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
status = ngx_atoi(status_line->data, 3);
if (status == NGX_ERROR) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent invalid status \"%V\"",
+ status_line);
+ return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
u->headers_in.status_n = status;
@@ -1233,7 +1236,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
f->split_parts = ngx_array_create(r->pool, 1,
sizeof(ngx_http_fastcgi_split_part_t));
if (f->split_parts == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
}
@@ -1638,8 +1641,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
* conf->upstream.hide_headers_hash = { NULL, 0 };
- * conf->upstream.hide_headers = NULL;
- * conf->upstream.pass_headers = NULL;
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
@@ -1669,6 +1670,9 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
conf->upstream.pass_request_body = NGX_CONF_UNSET;
+ conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
+ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
+
conf->upstream.intercept_errors = NGX_CONF_UNSET;
/* "fastcgi_cyclic_temp_file" is disabled */
@@ -1689,11 +1693,8 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
- ngx_str_t *header;
- ngx_uint_t i, j;
- ngx_array_t hide_headers;
+ ngx_uint_t i;
ngx_keyval_t *src;
- ngx_hash_key_t *hk;
ngx_hash_init_t hash;
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
@@ -1855,108 +1856,19 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->index, prev->index, "");
- if (conf->upstream.hide_headers == NULL
- && conf->upstream.pass_headers == NULL)
- {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
-
- if (conf->upstream.hide_headers_hash.buckets) {
- goto peers;
- }
-
- } else {
- if (conf->upstream.hide_headers == NULL) {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- }
-
- if (conf->upstream.pass_headers == NULL) {
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- }
- }
-
- if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- for (header = ngx_http_fastcgi_hide_headers; header->len; header++) {
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = *header;
- hk->key_hash = ngx_hash_key_lc(header->data, header->len);
- hk->value = (void *) 1;
- }
-
- if (conf->upstream.hide_headers) {
-
- header = conf->upstream.hide_headers->elts;
-
- for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
-
- hk = hide_headers.elts;
-
- for (j = 0; j < hide_headers.nelts; j++) {
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- goto exist;
- }
- }
-
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = header[i];
- hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
- hk->value = (void *) 1;
-
- exist:
-
- continue;
- }
- }
-
- if (conf->upstream.pass_headers) {
-
- hk = hide_headers.elts;
- header = conf->upstream.pass_headers->elts;
-
- for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
-
- for (j = 0; j < hide_headers.nelts; j++) {
-
- if (hk[j].key.data == NULL) {
- continue;
- }
-
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- hk[j].key.data = NULL;
- break;
- }
- }
- }
- }
-
- hash.hash = &conf->upstream.hide_headers_hash;
- hash.key = ngx_hash_key_lc;
hash.max_size = 512;
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
hash.name = "fastcgi_hide_headers_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
- if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
+ if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
+ &prev->upstream,
+ ngx_http_fastcgi_hide_headers,
+ &hash)
+ != NGX_OK)
+ {
return NGX_CONF_ERROR;
}
-peers:
-
if (conf->upstream.upstream == NULL) {
conf->upstream.upstream = prev->upstream.upstream;
conf->upstream.schema = prev->upstream.schema;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 9eae90324..bd166a4d5 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -838,7 +838,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (p == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
rc = ngx_http_proxy_parse_status_line(r, p);
@@ -873,7 +873,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
u->headers_in.status_line.data = ngx_palloc(r->pool,
u->headers_in.status_line.len);
if (u->headers_in.status_line.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
ngx_memcpy(u->headers_in.status_line.data, p->status_start,
@@ -1117,7 +1117,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h = ngx_list_push(&r->upstream->headers_in.headers);
if (h == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
h->hash = r->header_hash;
@@ -1128,7 +1128,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h->key.data = ngx_palloc(r->pool,
h->key.len + 1 + h->value.len + 1 + h->key.len);
if (h->key.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
@@ -1150,7 +1150,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h->lowcase_key, h->key.len);
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1175,7 +1175,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
if (r->upstream->headers_in.server == NULL) {
h = ngx_list_push(&r->upstream->headers_in.headers);
if (h == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
@@ -1191,7 +1191,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
if (r->upstream->headers_in.date == NULL) {
h = ngx_list_push(&r->upstream->headers_in.headers);
if (h == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');
@@ -1502,8 +1502,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
* conf->upstream.hide_headers_hash = { NULL, 0 };
- * conf->upstream.hide_headers = NULL;
- * conf->upstream.pass_headers = NULL;
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
@@ -1540,6 +1538,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
conf->upstream.pass_request_body = NGX_CONF_UNSET;
+ conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
+ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
+
conf->upstream.intercept_errors = NGX_CONF_UNSET;
/* "proxy_cyclic_temp_file" is disabled */
@@ -1564,9 +1565,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
- ngx_str_t *header;
- ngx_uint_t i, j;
- ngx_array_t hide_headers;
+ ngx_uint_t i;
ngx_keyval_t *src, *s, *h;
ngx_hash_key_t *hk;
ngx_hash_init_t hash;
@@ -1775,107 +1774,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size,
ngx_cacheline_size);
- if (conf->upstream.hide_headers == NULL
- && conf->upstream.pass_headers == NULL)
- {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
-
- if (conf->upstream.hide_headers_hash.buckets) {
- goto peers;
- }
-
- } else {
- if (conf->upstream.hide_headers == NULL) {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- }
-
- if (conf->upstream.pass_headers == NULL) {
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- }
- }
-
- if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- for (header = ngx_http_proxy_hide_headers; header->len; header++) {
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = *header;
- hk->key_hash = ngx_hash_key_lc(header->data, header->len);
- hk->value = (void *) 1;
- }
-
- if (conf->upstream.hide_headers) {
-
- header = conf->upstream.hide_headers->elts;
-
- for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
-
- hk = hide_headers.elts;
-
- for (j = 0; j < hide_headers.nelts; j++) {
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- goto exist;
- }
- }
-
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = header[i];
- hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
- hk->value = (void *) 1;
-
- exist:
-
- continue;
- }
- }
-
- if (conf->upstream.pass_headers) {
-
- hk = hide_headers.elts;
- header = conf->upstream.pass_headers->elts;
-
- for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
- for (j = 0; j < hide_headers.nelts; j++) {
-
- if (hk[j].key.data == NULL) {
- continue;
- }
-
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- hk[j].key.data = NULL;
- break;
- }
- }
- }
- }
-
- hash.hash = &conf->upstream.hide_headers_hash;
- hash.key = ngx_hash_key_lc;
hash.max_size = conf->headers_hash_max_size;
hash.bucket_size = conf->headers_hash_bucket_size;
hash.name = "proxy_headers_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
- if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
+ if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
+ &prev->upstream,
+ ngx_http_proxy_hide_headers, &hash)
+ != NGX_OK)
+ {
return NGX_CONF_ERROR;
}
-peers:
-
if (conf->upstream.upstream == NULL) {
conf->upstream.upstream = prev->upstream.upstream;
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index ae72ee379..5f01bb522 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -1983,6 +1983,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
if (bl[i].count++) {
+ out = NULL;
ll = &out;
for (tl = bl[i].bufs; tl; tl = tl->next) {
diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c
index 93d1b36ef..663a9f5b7 100644
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -590,7 +590,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
ctx->state = sub_start_state;
ctx->pos = p + 1;
- ctx->looked = looked;
+ ctx->looked = 0;
ctx->copy_end = copy_end;
if (ctx->copy_start == NULL && copy_end) {
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index b99804f13..bd0e8c0e4 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.5.35';
+our $VERSION = '0.5.36';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index a407a1787..08f81013e 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1041,7 +1041,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
return;
}
- if (rc == NGX_ERROR || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
+ if (rc == NGX_ERROR) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
@@ -1235,6 +1235,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;
@@ -1838,6 +1840,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;
@@ -1932,18 +1935,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);
@@ -2536,6 +2543,10 @@ ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
while (*++p == ' ') { /* void */ }
+ if (*p == '\0') {
+ return NGX_OK;
+ }
+
if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
continue;
}
@@ -3265,6 +3276,113 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
}
+ngx_int_t
+ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
+ ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
+ ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
+{
+ ngx_str_t *h;
+ ngx_uint_t i, j;
+ ngx_array_t hide_headers;
+ ngx_hash_key_t *hk;
+
+ if (conf->hide_headers == NGX_CONF_UNSET_PTR
+ && conf->pass_headers == NGX_CONF_UNSET_PTR)
+ {
+ conf->hide_headers_hash = prev->hide_headers_hash;
+
+ if (conf->hide_headers_hash.buckets) {
+ return NGX_OK;
+ }
+
+ conf->hide_headers = prev->hide_headers;
+ conf->pass_headers = prev->pass_headers;
+
+ } else {
+ if (conf->hide_headers == NGX_CONF_UNSET_PTR) {
+ conf->hide_headers = prev->hide_headers;
+ }
+
+ if (conf->pass_headers == NGX_CONF_UNSET_PTR) {
+ conf->pass_headers = prev->pass_headers;
+ }
+ }
+
+ if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ for (h = default_hide_headers; h->len; h++) {
+ hk = ngx_array_push(&hide_headers);
+ if (hk == NULL) {
+ return NGX_ERROR;
+ }
+
+ hk->key = *h;
+ hk->key_hash = ngx_hash_key_lc(h->data, h->len);
+ hk->value = (void *) 1;
+ }
+
+ if (conf->hide_headers != NGX_CONF_UNSET_PTR) {
+
+ h = conf->hide_headers->elts;
+
+ for (i = 0; i < conf->hide_headers->nelts; i++) {
+
+ hk = hide_headers.elts;
+
+ for (j = 0; j < hide_headers.nelts; j++) {
+ if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
+ goto exist;
+ }
+ }
+
+ hk = ngx_array_push(&hide_headers);
+ if (hk == NULL) {
+ return NGX_ERROR;
+ }
+
+ hk->key = h[i];
+ hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);
+ hk->value = (void *) 1;
+
+ exist:
+
+ continue;
+ }
+ }
+
+ if (conf->pass_headers != NGX_CONF_UNSET_PTR) {
+
+ h = conf->pass_headers->elts;
+ hk = hide_headers.elts;
+
+ for (i = 0; i < conf->pass_headers->nelts; i++) {
+ for (j = 0; j < hide_headers.nelts; j++) {
+
+ if (hk[j].key.data == NULL) {
+ continue;
+ }
+
+ if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
+ hk[j].key.data = NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ hash->hash = &conf->hide_headers_hash;
+ hash->key = ngx_hash_key_lc;
+ hash->pool = cf->pool;
+ hash->temp_pool = NULL;
+
+ return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
+}
+
+
static void *
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
{
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index c1ec48fcc..f6184b6ff 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -194,6 +194,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;
@@ -259,6 +261,9 @@ ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
void ngx_http_upstream_init(ngx_http_request_t *r);
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
ngx_url_t *u, ngx_uint_t flags);
+ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
+ ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
+ ngx_str_t *default_hide_headers, ngx_hash_init_t *hash);
#define ngx_http_conf_upstream_srv_conf(uscf, module) \