From 2b032e8df6f6a97454d4c4fc73ea9c5e86fca97c Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 2 Mar 2015 21:44:32 +0300 Subject: [PATCH] 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. --- src/http/ngx_http_upstream.c | 10 +++++++--- 1 file 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;