Mercurial > hg > nginx
changeset 5994:5abf5af257a7
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 02 Mar 2015 21:44:32 +0300 |
parents | 5b549cc7f698 |
children | 5f179f344096 |
files | src/http/ngx_http_upstream.c |
diffstat | 1 files changed, 8 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/ngx_http_upstream.c Mon Mar 02 21:15:46 2015 +0300 +++ b/src/http/ngx_http_upstream.c Mon Mar 02 21:44:32 2015 +0300 @@ -3751,10 +3751,14 @@ 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);