From: Stefan Eissing Date: Mon, 28 Aug 2023 13:27:10 +0000 (+0000) Subject: *) mod_proxy_http2: improved error handling on connection errors while X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c50a846c1cd24a0ce9c084393b063767d9b250a;p=thirdparty%2Fapache%2Fhttpd.git *) mod_proxy_http2: improved error handling on connection errors while response is already underway. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1911964 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/changes-entries/h2_proxy_errors.txt b/changes-entries/h2_proxy_errors.txt new file mode 100644 index 00000000000..6c50d5f3423 --- /dev/null +++ b/changes-entries/h2_proxy_errors.txt @@ -0,0 +1,3 @@ + *) mod_proxy_http2: improved error handling on connection errors while + response is already underway. + [Stefan Eissing] diff --git a/modules/http2/h2_proxy_session.c b/modules/http2/h2_proxy_session.c index 4835ec3e6cd..8a5c591ab82 100644 --- a/modules/http2/h2_proxy_session.c +++ b/modules/http2/h2_proxy_session.c @@ -1681,7 +1681,17 @@ static int done_iter(void *udata, void *val) h2_proxy_stream *stream = val; int touched = (stream->data_sent || stream->data_received || stream->id <= ctx->session->last_stream_id); - ctx->done(ctx->session, stream->r, APR_ECONNABORTED, touched, stream->error_code); + if (touched && stream->output) { + apr_bucket *b = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, + stream->r->pool, + stream->cfront->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(stream->output, b); + b = apr_bucket_eos_create(stream->cfront->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(stream->output, b); + ap_pass_brigade(stream->r->output_filters, stream->output); + } + ctx->done(ctx->session, stream->r, APR_ECONNABORTED, touched, + stream->error_code); return 1; } diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index 6e24dde4d47..ebf8f61b81b 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -65,7 +65,7 @@ typedef struct h2_proxy_ctx { unsigned is_ssl : 1; request_rec *r; /* the request processed in this ctx */ - apr_status_t r_status; /* status of request work */ + int r_status; /* status of request work */ int r_done; /* request was processed, not necessarily successfully */ int r_may_retry; /* request may be retried */ int has_reusable_session; /* http2 session is live and clean */ @@ -413,7 +413,7 @@ run_connect: "setup new connection: is_ssl=%d %s %s %s", ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, locurl, ctx->p_conn->hostname); - ctx->r_status = status; + ctx->r_status = ap_map_http_request_error(status, HTTP_SERVICE_UNAVAILABLE); goto cleanup; } @@ -427,7 +427,7 @@ run_connect: if (ctx->cfront->aborted) goto cleanup; status = ctx_run(ctx); - if (ctx->r_status != APR_SUCCESS && ctx->r_may_retry && !ctx->cfront->aborted) { + if (ctx->r_status != OK && ctx->r_may_retry && !ctx->cfront->aborted) { /* Not successfully processed, but may retry, tear down old conn and start over */ if (ctx->p_conn) { ctx->p_conn->close = 1; @@ -463,6 +463,12 @@ cleanup: ap_set_module_config(ctx->cfront->conn_config, &proxy_http2_module, NULL); ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->cfront, APLOGNO(03377) "leaving handler"); + if (ctx->r_status != OK) { + ap_die(ctx->r_status, r); + } + else if (status != APR_SUCCESS) { + ap_die(ap_map_http_request_error(status, HTTP_SERVICE_UNAVAILABLE), r); + } return ctx->r_status; }