changeset 7631:b4dbf8b98f9a

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.
author Dmitry Volyntsev <xeioex@nginx.com>
date Mon, 02 Mar 2020 20:07:36 +0300
parents f001d9384293
children 1d207b77b44a
files src/http/ngx_http_request.c
diffstat 1 files changed, 9 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2490,6 +2490,15 @@ ngx_http_finalize_request(ngx_http_reque
     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_reque
             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) {