[nginx] Improved ngx_http_subrequest() error handling.
noreply at nginx.com
noreply at nginx.com
Thu Feb 20 20:05:02 UTC 2025
details: https://github.com/nginx/nginx/commit/d25139db01b636a8212c13e1feeca37eaadad0b5
branches: master
commit: d25139db01b636a8212c13e1feeca37eaadad0b5
user: Sergey Kandaurov <pluknet at nginx.com>
date: Tue, 11 Feb 2025 22:54:04 +0400
description:
Improved ngx_http_subrequest() error handling.
Previously, request might be left in inconsistent state in case of error,
which manifested in "http request count is zero" alerts when used by SSI
filter.
The fix is to reshuffle initialization order to postpone committing state
changes until after any potentially failing parts.
Found by bad memory allocator simulation.
---
src/http/ngx_http_core_module.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index a1540c018..92c3eae8a 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2327,6 +2327,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
ngx_connection_t *c;
ngx_http_request_t *sr;
ngx_http_core_srv_conf_t *cscf;
+ ngx_http_posted_request_t *posted;
ngx_http_postponed_request_t *pr, *p;
if (r->subrequests == 0) {
@@ -2380,6 +2381,11 @@ ngx_http_subrequest(ngx_http_request_t *r,
return NGX_ERROR;
}
+ posted = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
+ if (posted == NULL) {
+ return NGX_ERROR;
+ }
+
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
sr->main_conf = cscf->ctx->main_conf;
sr->srv_conf = cscf->ctx->srv_conf;
@@ -2438,10 +2444,6 @@ ngx_http_subrequest(ngx_http_request_t *r,
}
if (!sr->background) {
- if (c->data == r && r->postponed == NULL) {
- c->data = sr;
- }
-
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
if (pr == NULL) {
return NGX_ERROR;
@@ -2451,6 +2453,10 @@ ngx_http_subrequest(ngx_http_request_t *r,
pr->out = NULL;
pr->next = NULL;
+ if (c->data == r && r->postponed == NULL) {
+ c->data = sr;
+ }
+
if (r->postponed) {
for (p = r->postponed; p->next; p = p->next) { /* void */ }
p->next = pr;
@@ -2498,7 +2504,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
ngx_http_update_location_config(sr);
}
- return ngx_http_post_request(sr, NULL);
+ return ngx_http_post_request(sr, posted);
}
More information about the nginx-devel
mailing list