]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge of /httpd/httpd/trunk:r1911964
authorStefan Eissing <icing@apache.org>
Fri, 8 Sep 2023 13:18:58 +0000 (13:18 +0000)
committerStefan Eissing <icing@apache.org>
Fri, 8 Sep 2023 13:18:58 +0000 (13:18 +0000)
  *) 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/branches/2.4.x@1912193 13f79535-47bb-0310-9956-ffa450edef68

STATUS
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/STATUS b/STATUS
index 7ebf9177b96212b1576b5726eec2b590d6863631..c5a7e0da70b1b6d35b410bd4f5f8d50bbc756c42 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -196,14 +196,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK:
      +1: rpluem,
      ylavic: see https://lists.apache.org/thread/jftfd6mo6p3b0tw694rlh09gdl7189hq
 
-  *) mod_proxy_http2: improved error handling on connection errors while
-     response is already underway.
-     Trunk version of patch:
-        https://svn.apache.org/r1911964
-     Backport version for 2.4.x of patch:
-      svn merge -c 1911964 ^/httpd/httpd/trunk .
-     +1: icing, gbechis
-
   *) mod_ssl: Silence info log message "SSL Library Error: error:0A000126:
      SSL routines::unexpected eof while reading" when using
      OpenSSL 3 by setting SSL_OP_IGNORE_UNEXPECTED_EOF if
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;
 }