fix: wake parent request when HTTP/2 subrequest finishes with error

When a client disconnects during an HTTP/2 subrequest (e.g., while
ngx.sleep() is yielding), the subrequest fails to wake up its parent
request, causing the parent's Lua coroutine to hang indefinitely.

Root cause: HTTP/2 sets c->error=1 immediately on client disconnect,
triggering the error path in ngx_http_finalize_request(). This path
calls ngx_http_terminate_request(), which clears the posted_requests
queue before the parent can be processed.

Solution: In ngx_http_finalize_request(), when a subrequest completes
with c->error set, manually update subrequest state and wake the parent
request, then return immediately to avoid ngx_http_terminate_request().

This fix ensures the parent request can process the subrequest response
even when the client connection is closed, which is critical for
OpenResty's async subrequest mechanism with ngx.location.capture().

Signed-off-by: tzssangglass <tzssangglass@gmail.com>
pull/1083/head
tzssangglass 1 month ago
parent d52d5b4b99
commit 3839690b77

@ -0,0 +1,20 @@
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 9593b7f..dbc23ff 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2560,8 +2560,15 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
return;
}
+#if (NGX_HTTP_V2)
+ if (r->http_version < NGX_HTTP_VERSION_20 || r == r->main) {
+ ngx_http_terminate_request(r, rc);
+ return;
+ }
+#else
ngx_http_terminate_request(r, rc);
return;
+#endif
}
if (rc >= NGX_HTTP_SPECIAL_RESPONSE

@ -0,0 +1,20 @@
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 16d79c4..760e0e5 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2559,8 +2559,15 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
return;
}
+#if (NGX_HTTP_V2)
+ if (r->http_version < NGX_HTTP_VERSION_20 || r == r->main) {
+ ngx_http_terminate_request(r, rc);
+ return;
+ }
+#else
ngx_http_terminate_request(r, rc);
return;
+#endif
}
if (rc >= NGX_HTTP_SPECIAL_RESPONSE

@ -576,6 +576,12 @@ if [ "$answer" = "Y" ]; then
patch -p1 < $root/patches/nginx/$main_ver/nginx-$main_ver-quic_ssl_lua_yield.patch || exit 1
fi
answer=`$root/util/ver-ge "$main_ver" 1.27.1`
if [ "$answer" = "Y" ]; then
echo "$info_txt applying nginx-$main_ver-http2_subreq_error_wakeup patch for nginx"
patch -p1 < $root/patches/nginx/$main_ver/nginx-$main_ver-http2_subreq_error_wakeup.patch || exit 1
fi
cp $root/html/index.html docs/html/ || exit 1
cp $root/html/50x.html docs/html/ || exit 1

Loading…
Cancel
Save