]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) mod_proxy_http2: improved error handling on connection errors while
authorStefan Eissing <icing@apache.org>
Mon, 28 Aug 2023 13:27:10 +0000 (13:27 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 28 Aug 2023 13:27:10 +0000 (13:27 +0000)
     response is already underway.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1911964 13f79535-47bb-0310-9956-ffa450edef68

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

diff --git a/changes-entries/h2_proxy_errors.txt b/changes-entries/h2_proxy_errors.txt
new file mode 100644 (file)
index 0000000..6c50d5f
--- /dev/null
@@ -0,0 +1,3 @@
+  *) mod_proxy_http2: improved error handling on connection errors while
+     response is already underway.
+     [Stefan Eissing]
index 4835ec3e6cda0ab70d866b3ce27efafbd41eb79b..8a5c591ab8255d90a31fd9c651e953ecd4ec4f0e 100644 (file)
@@ -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;
 }
 
index 6e24dde4d47f8a3548cfbb09529570ef7fd9312c..ebf8f61b81b8d17f52023accec16b56ed46fccc0 100644 (file)
@@ -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;
 }