From bddcfb1233671d5857f82c4f0cf14ab40c654cd8 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Wed, 6 Aug 2025 14:03:00 +0000 Subject: [PATCH] * mod_proxy_http2: add support for ProxyErrorOverride directive. PR69771 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1927647 13f79535-47bb-0310-9956-ffa450edef68 --- changes-entries/pr69771.txt | 1 + modules/http2/h2_proxy_session.c | 10 ++++++++++ modules/http2/h2_version.h | 4 ++-- modules/http2/mod_proxy_http2.c | 21 ++++++++++++++++----- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 changes-entries/pr69771.txt diff --git a/changes-entries/pr69771.txt b/changes-entries/pr69771.txt new file mode 100644 index 0000000000..8c8402e897 --- /dev/null +++ b/changes-entries/pr69771.txt @@ -0,0 +1 @@ + * mod_proxy_http2: add support for ProxyErrorOverride directive. PR69771 diff --git a/modules/http2/h2_proxy_session.c b/modules/http2/h2_proxy_session.c index e44d5d956e..3561c241e1 100644 --- a/modules/http2/h2_proxy_session.c +++ b/modules/http2/h2_proxy_session.c @@ -49,6 +49,7 @@ typedef struct h2_proxy_stream { unsigned int waiting_on_ping : 1; unsigned int headers_ended : 1; uint32_t error_code; + int proxy_status; apr_bucket_brigade *input; apr_off_t data_sent; @@ -310,6 +311,15 @@ static int on_frame_recv(nghttp2_session *ngh2, const nghttp2_frame *frame, ap_send_interim_response(r, 1); } } + else if (r->status >= 400) { + proxy_dir_conf *dconf; + dconf = ap_get_module_config(r->per_dir_config, &proxy_module); + if (ap_proxy_should_override(dconf, r->status)) { + apr_table_setn(r->notes, "proxy-error-override", "1"); + nghttp2_submit_rst_stream(ngh2, NGHTTP2_FLAG_NONE, + frame->hd.stream_id, NGHTTP2_STREAM_CLOSED); + } + } stream_resume(stream); break; case NGHTTP2_PING: diff --git a/modules/http2/h2_version.h b/modules/http2/h2_version.h index 13441a0935..c2e96500cf 100644 --- a/modules/http2/h2_version.h +++ b/modules/http2/h2_version.h @@ -27,7 +27,7 @@ * @macro * Version number of the http2 module as c string */ -#define MOD_HTTP2_VERSION "2.0.32" +#define MOD_HTTP2_VERSION "2.0.34" /** * @macro @@ -35,7 +35,7 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define MOD_HTTP2_VERSION_NUM 0x020020 +#define MOD_HTTP2_VERSION_NUM 0x020022 #endif /* mod_h2_h2_version_h */ diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index 2881293d89..d61448f42f 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -239,9 +239,15 @@ static void request_done(h2_proxy_ctx *ctx, request_rec *r, ctx->id, touched, error_code); ctx->r_done = 1; if (touched) ctx->r_may_retry = 0; - ctx->r_status = error_code? HTTP_BAD_GATEWAY : - ((status == APR_SUCCESS)? OK : - ap_map_http_request_error(status, HTTP_SERVICE_UNAVAILABLE)); + if (apr_table_get(r->notes, "proxy-error-override")) { + ctx->r_status = r->status; + r->status = OK; + } + else { + ctx->r_status = error_code? HTTP_BAD_GATEWAY : + ((status == APR_SUCCESS)? OK : + ap_map_http_request_error(status, HTTP_SERVICE_UNAVAILABLE)); + } } } @@ -428,7 +434,12 @@ 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 (apr_table_get(r->notes, "proxy-error-override")) { + /* pass on out */ + ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->cfront, + "proxy-error-override status %d", ctx->r_status); + } + else if (ctx->r_status != APR_SUCCESS && 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,7 +474,7 @@ 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"); + APLOGNO(03377) "leaving handler -> %d", ctx->r_status); return ctx->r_status; } -- 2.47.2