1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-07 04:02:58 +03:00

mod_proxy: Handle ap_proxy_buckets_lifetime_transform() errors.

* modules/proxy/mod_proxy.h,modules/proxy/proxy_util.c:
  Add ap_proxy_fill_error_brigade() to factorize proxy error handling
  on the client connection side.

* modules/proxy/mod_proxy_{http,ajp,uwsgi}.c:
  Use ap_proxy_fill_error_brigade() where needed, including when an
  empty brigade is returned on the backend side or when calling
  ap_proxy_buckets_lifetime_transform fails.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1893595 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yann Ylavic
2021-09-24 11:25:42 +00:00
parent 074d55133a
commit b44b9b6b2a
7 changed files with 138 additions and 66 deletions

View File

@@ -3542,11 +3542,54 @@ PROXY_DECLARE(int) ap_proxy_should_override(proxy_dir_conf *conf, int code)
code);
}
PROXY_DECLARE(void) ap_proxy_fill_error_brigade(request_rec *r, int status,
apr_bucket_brigade *bb,
int eoc)
{
apr_bucket *e, *eos;
conn_rec *c = r->connection;
/*
* Add an error and (eventually) EOC buckets to signal the http filter
* that it should get out of our way, BUT ensure that they are inserted
* BEFORE an EOS bucket in bb as some resource filters like mod_deflate
* pass everything up to the EOS down the chain immediately and sent the
* remainder of the brigade later (or even never). But in this case the
* ap_http_header_filter does not get out of our way soon enough.
*/
eos = APR_BRIGADE_LAST(bb);
while (eos != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(eos)) {
eos = APR_BUCKET_PREV(eos);
}
e = ap_bucket_error_create(status, NULL, c->pool, c->bucket_alloc);
if (eos == APR_BRIGADE_SENTINEL(bb)) {
APR_BRIGADE_INSERT_TAIL(bb, e);
eos = APR_BRIGADE_SENTINEL(bb);
}
else {
APR_BUCKET_INSERT_BEFORE(eos, e);
}
/* If asked to (eoc > 0) or if heuristically (eoc < 0) the header was
* sent already we need to terminate the connection.
*/
if (eoc > 0 || (eoc < 0 && r->sent_bodyct)) {
e = ap_bucket_eoc_create(c->bucket_alloc);
if (eos == APR_BRIGADE_SENTINEL(bb)) {
APR_BRIGADE_INSERT_TAIL(bb, e);
}
else {
APR_BUCKET_INSERT_BEFORE(eos, e);
}
}
}
/* deprecated - to be removed in v2.6 */
PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
apr_bucket_brigade *brigade)
{
apr_bucket *e;
conn_rec *c = r->connection;
r->no_cache = 1;
@@ -3556,11 +3599,9 @@ PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
*/
if (r->main)
r->main->no_cache = 1;
e = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, c->pool,
c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, e);
e = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, e);
APR_BRIGADE_INSERT_TAIL(brigade, apr_bucket_eos_create(c->bucket_alloc));
ap_proxy_fill_error_brigade(r, HTTP_BAD_GATEWAY, brigade, 0);
}
/*