aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2015-03-02 21:44:32 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2015-03-02 21:44:32 +0300
commit2b032e8df6f6a97454d4c4fc73ea9c5e86fca97c (patch)
tree334a0ab5e0d3230c1cf779e6791af987c87ab4d9
parent46a2236f226d7a68a6e830b8fd2c618c12bf4ca9 (diff)
downloadnginx-2b032e8df6f6a97454d4c4fc73ea9c5e86fca97c.tar.gz
nginx-2b032e8df6f6a97454d4c4fc73ea9c5e86fca97c.zip
Upstream: avoid duplicate finalization.
A request may be already finalized when ngx_http_upstream_finalize_request() is called, due to filter finalization: after filter finalization upstream can be finalized via ngx_http_upstream_cleanup(), either from ngx_http_terminate_request(), or because a new request was initiated to an upstream. Then the upstream code will see an error returned from the filter chain and will call the ngx_http_upstream_finalize_request() function again. To prevent corruption of various upstream data in this situation, make sure to do nothing but merely call ngx_http_finalize_request(). Prodded by Yichun Zhang, for details see the thread at http://nginx.org/pipermail/nginx-devel/2015-February/006539.html.
-rw-r--r--src/http/ngx_http_upstream.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 23208c80e..7066d14af 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -3751,11 +3751,15 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"finalize http upstream request: %i", rc);
- if (u->cleanup) {
- *u->cleanup = NULL;
- u->cleanup = NULL;
+ if (u->cleanup == NULL) {
+ /* the request was already finalized */
+ ngx_http_finalize_request(r, NGX_DONE);
+ return;
}
+ *u->cleanup = NULL;
+ u->cleanup = NULL;
+
if (u->resolved && u->resolved->ctx) {
ngx_resolve_name_done(u->resolved->ctx);
u->resolved->ctx = NULL;