aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Kandaurov <pluknet@nginx.com>2025-02-11 22:54:04 +0400
committerpluknet <pluknet@nginx.com>2025-02-21 00:04:12 +0400
commitd25139db01b636a8212c13e1feeca37eaadad0b5 (patch)
tree9552074bbf881a314a1ad50d4f3514451f39321e
parentf51e2de6fe303506538ba939e9071a11387d8275 (diff)
downloadnginx-d25139db01b636a8212c13e1feeca37eaadad0b5.tar.gz
nginx-d25139db01b636a8212c13e1feeca37eaadad0b5.zip
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.
-rw-r--r--src/http/ngx_http_core_module.c16
1 files 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);
}