From: Yann Ylavic Date: Wed, 24 Nov 2021 17:49:47 +0000 (+0000) Subject: mod_proxy: SetEnv proxy-nohalfclose to disable half-close tunneling. PR 65662. X-Git-Tag: 2.5.0-alpha2-ci-test-only~687 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5338e45798e2be5296b57c5b31c0de763f2d8962;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy: SetEnv proxy-nohalfclose to disable half-close tunneling. PR 65662. Some connect/wstunnel protocols might want half-close forwarding while some might not, let's provide an r->subprocess_env opt-out. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1895304 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/changes-entries/proxy_half_close.txt b/changes-entries/proxy_half_close.txt new file mode 100644 index 00000000000..266cbb7b501 --- /dev/null +++ b/changes-entries/proxy_half_close.txt @@ -0,0 +1,2 @@ + *) mod_proxy: SetEnv proxy-nohalfclose (or alike) allows to disable TCP + half-close forwarding when tunneling protocols. [Yann Ylavic] diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index ad9a9eba32a..f0f09947886 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -1360,7 +1360,8 @@ typedef struct { proxy_tunnel_conn_t *client, *origin; apr_size_t read_buf_size; - int replied; + int replied; /* TODO 2.5+: one bit to merge in below bitmask */ + unsigned int nohalfclose :1; } proxy_tunnel_rec; /** diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 00492d77392..8c444aa05ea 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -4818,6 +4818,11 @@ PROXY_DECLARE(apr_status_t) ap_proxy_tunnel_create(proxy_tunnel_rec **ptunnel, c_i->keepalive = AP_CONN_CLOSE; c_o->keepalive = AP_CONN_CLOSE; + /* Disable half-close forwarding for this request? */ + if (apr_table_get(r->subprocess_env, "proxy-nohalfclose")) { + tunnel->nohalfclose = 1; + } + /* Start with POLLOUT and let ap_proxy_tunnel_run() schedule both * directions when there are no output data pending (anymore). */ @@ -4920,6 +4925,12 @@ static int proxy_tunnel_transfer(proxy_tunnel_rec *tunnel, ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, tunnel->r, "proxy: %s: %s read shutdown", tunnel->scheme, in->name); + if (tunnel->nohalfclose) { + /* No half-close forwarding, we are done both ways as + * soon as one side shuts down. + */ + return DONE; + } in->down_in = 1; } else { @@ -5093,11 +5104,14 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) } while (!client->down_out || !origin->down_out); done: + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10223) + "proxy: %s: tunneling returns (%i)", scheme, status); if (client->bytes_out > 0) { tunnel->replied = 1; } - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10223) - "proxy: %s: tunneling returns (%i)", scheme, status); + if (status == DONE) { + status = OK; + } return status; }