From: Yann Ylavic Date: Thu, 2 Mar 2023 14:30:20 +0000 (+0000) Subject: mod_proxy: Don't decode r->uri and reencode in r->filename for mapping=encoded. X-Git-Tag: 2.5.0-alpha2-ci-test-only~92 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52930446f6789abc1a77f70b3f24a3f960e5aa64;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy: Don't decode r->uri and reencode in r->filename for mapping=encoded. Decoding was not done for mapping=servlet only (a subset), but overlooked for mapping=encoded. To avoid double-encoding in the canon_handler hook, use a new "proxy-noencode" (similarly to "proxy-nocanon") entry in r->notes. * proxy/mod_proxy.c(ap_proxy_trans_match): Set "proxy-noencode" in r->notes for PROXYPASS_MAP_ENCODED, and return DONE to avoid decoding in ap_process_request_internal(). * proxy/mod_proxy_http.c, proxy/mod_proxy_ajp.c, proxy/mod_proxy_wstunnel.c, proxy/mod_proxy_fcgi.c, proxy/mod_proxy_ajp.c, http2/mod_proxy_http2.c: Don't process the url through ap_proxy_canonenc() in canon_handler if "proxy-noencode" is set. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1907972 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index 3faf03472bb..11d2c785c51 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -154,6 +154,10 @@ static int proxy_http2_canon(request_rec *r, char *url) if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } + else if (apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the encoded path already */ + search = r->args; + } else { path = ap_proxy_canonenc(r->pool, url, (int)strlen(url), enc_path, 0, r->proxyreq); diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 3c36f03991f..8cbc901cac0 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -969,6 +969,8 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent, } if (found) { + unsigned int encoded = ent->flags & PROXYPASS_MAP_ENCODED; + /* A proxy module is assigned this URL, check whether it's interested * in the request itself (e.g. proxy_wstunnel cares about Upgrade * requests only, and could hand over to proxy_http otherwise). @@ -988,6 +990,9 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent, if (ent->flags & PROXYPASS_NOQUERY) { apr_table_setn(r->notes, "proxy-noquery", "1"); } + if (encoded) { + apr_table_setn(r->notes, "proxy-noencode", "1"); + } if (servlet_uri) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10248) @@ -1001,13 +1006,13 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent, */ AP_DEBUG_ASSERT(strlen(r->uri) >= strlen(servlet_uri)); strcpy(r->uri, servlet_uri); - return DONE; } - - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464) - "URI path '%s' matches proxy handler '%s'", r->uri, - found); - return OK; + else { + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464) + "URI path '%s' matches proxy handler '%s'", r->uri, + found); + } + return (encoded) ? DONE : OK; } return HTTP_CONTINUE; diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index 07f37392d88..4ca436188e4 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -65,6 +65,10 @@ static int proxy_ajp_canon(request_rec *r, char *url) if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } + else if (apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the encoded path already */ + search = r->args; + } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 8db7e93f39c..c5f60f673c6 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -102,6 +102,10 @@ static int proxy_balancer_canon(request_rec *r, char *url) if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } + else if (apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the encoded path already */ + search = r->args; + } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index 3382b9bfd5c..a89b9a9c7b6 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -92,8 +92,9 @@ static int proxy_fcgi_canon(request_rec *r, char *url) host = apr_pstrcat(r->pool, "[", host, "]", NULL); } - if (apr_table_get(r->notes, "proxy-nocanon")) { - path = url; /* this is the raw path */ + if (apr_table_get(r->notes, "proxy-nocanon") + || apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the raw/encoded path */ } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index c3c9adaec68..8789dcae29e 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -118,6 +118,10 @@ static int proxy_http_canon(request_rec *r, char *url) if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } + else if (apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the encoded path already */ + search = r->args; + } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c index 0037bfc5773..8a7d21c8676 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -195,6 +195,10 @@ static int proxy_wstunnel_canon(request_rec *r, char *url) if (apr_table_get(r->notes, "proxy-nocanon")) { path = url; /* this is the raw path */ } + else if (apr_table_get(r->notes, "proxy-noencode")) { + path = url; /* this is the encoded path already */ + search = r->args; + } else { path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq);