]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* mod_proxy_http2: add support for ProxyErrorOverride directive. PR69771 trunk trunk
authorStefan Eissing <icing@apache.org>
Wed, 6 Aug 2025 14:03:00 +0000 (14:03 +0000)
committerStefan Eissing <icing@apache.org>
Wed, 6 Aug 2025 14:03:00 +0000 (14:03 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1927647 13f79535-47bb-0310-9956-ffa450edef68

changes-entries/pr69771.txt [new file with mode: 0644]
modules/http2/h2_proxy_session.c
modules/http2/h2_version.h
modules/http2/mod_proxy_http2.c

diff --git a/changes-entries/pr69771.txt b/changes-entries/pr69771.txt
new file mode 100644 (file)
index 0000000..8c8402e
--- /dev/null
@@ -0,0 +1 @@
+  * mod_proxy_http2: add support for ProxyErrorOverride directive. PR69771
index e44d5d956ea74fc174b5b043b43d2e72b898475a..3561c241e1beef7614db07a0ad4d084332f8879d 100644 (file)
@@ -49,6 +49,7 @@ typedef struct h2_proxy_stream {
     unsigned int waiting_on_ping : 1;
     unsigned int headers_ended : 1;
     uint32_t error_code;
     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;
 
     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);
                 }
             }
                     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:
             stream_resume(stream);
             break;
         case NGHTTP2_PING:
index 13441a093548ffb20c4ef37f08476cbe4b0a80c2..c2e96500cf8ef9f03267fc06d0b9f132ee89876e 100644 (file)
@@ -27,7 +27,7 @@
  * @macro
  * Version number of the http2 module as c string
  */
  * @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
 
 /**
  * @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.
  */
  * 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 */
 
 
 #endif /* mod_h2_h2_version_h */
index 2881293d89241bd8f805ffd3cd2fcfc8e6059d29..d61448f42f8eced1c1944c67211a9f6c2b118a6b 100644 (file)
@@ -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->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->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;
         /* 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,
 
     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;
 }
 
     return ctx->r_status;
 }