diff options
author | Dmitry Volyntsev <xeioex@nginx.com> | 2020-03-02 20:07:36 +0300 |
---|---|---|
committer | Dmitry Volyntsev <xeioex@nginx.com> | 2020-03-02 20:07:36 +0300 |
commit | 3733c6fd70a9e9ce64901982621629a8cfcc66a8 (patch) | |
tree | 0d11cb60703a3b65e26b575edb178d7f45ef8093 | |
parent | 6ba18bc35ee1bdf95130ee653adf451928ae8b74 (diff) | |
download | nginx-3733c6fd70a9e9ce64901982621629a8cfcc66a8.tar.gz nginx-3733c6fd70a9e9ce64901982621629a8cfcc66a8.zip |
Fixed premature background subrequest finalization.
When "aio" or "aio threads" is used while processing the response body of an
in-memory background subrequest, the subrequest could be finalized with an aio
operation still in progress. Upon aio completion either parent request is
woken or the old r->write_event_handler is called again. The latter may result
in request errors. In either case post_subrequest handler is never called with
the full response body, which is typically expected when using in-memory
subrequests.
Currently in nginx background subrequests are created by the upstream module
and the mirror module. The issue does not manifest itself with these
subrequests because they are header-only. But it can manifest itself with
third-party modules which create in-memory background subrequests.
-rw-r--r-- | src/http/ngx_http_request.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index bb69e71d0..5fcaa2c33 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2490,6 +2490,15 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) if (r != r->main) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + if (r->buffered || r->postponed) { + + if (ngx_http_set_write_handler(r) != NGX_OK) { + ngx_http_terminate_request(r, 0); + } + + return; + } + if (r->background) { if (!r->logged) { if (clcf->log_subrequest) { @@ -2509,15 +2518,6 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) return; } - if (r->buffered || r->postponed) { - - if (ngx_http_set_write_handler(r) != NGX_OK) { - ngx_http_terminate_request(r, 0); - } - - return; - } - pr = r->parent; if (r == c->data) { |