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.
This commit is contained in:
Sergey Kandaurov 2025-02-11 22:54:04 +04:00 committed by pluknet
parent f51e2de6fe
commit d25139db01
1 changed files with 11 additions and 5 deletions

View File

@ -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);
}