diff options
author | Yann Ylavic <ylavic@apache.org> | 2024-08-01 13:35:26 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2024-08-01 13:35:26 +0200 |
commit | 2f1f9c5df027e86bf4c3dbdb96c9e52748421c20 (patch) | |
tree | e186b3c9ffbb791eb7091d003f03f5b8d5a276fc /modules/proxy/proxy_util.c | |
parent | Follow-up to r1919587: CMake: Fix type in variable name (MODULES_SYNMBOLS -> ... (diff) | |
download | apache2-2f1f9c5df027e86bf4c3dbdb96c9e52748421c20.tar.xz apache2-2f1f9c5df027e86bf4c3dbdb96c9e52748421c20.zip |
mod_proxy: Fix selection of ProxyPassMatch workers with host/port substitution. PR 69233.
With "ProxyPassMatch ^/([^/]+)/(.*)$ https://$1/$2", ap_proxy_get_worker_ex()
should not consider the length of scheme://host part of the given URL because
of the globbing match on the host part.
Fix it by setting worker->s>is_host_matchable when creating a worker with host
substitution and avoiding the min_match check in worker_matches() in this case.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1919617 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | modules/proxy/proxy_util.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 558af5cfab..1a11498f5d 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1832,23 +1832,26 @@ static int ap_proxy_strcmp_ematch(const char *str, const char *expected) return 0; } -static APR_INLINE -int worker_matches(proxy_worker *worker, - const char *url, apr_size_t url_len, - apr_size_t min_match, apr_size_t *max_match, - unsigned int mask) +static int worker_matches(proxy_worker *worker, + const char *url, apr_size_t url_len, + apr_size_t min_match, apr_size_t *max_match, + unsigned int mask) { apr_size_t name_len = strlen(worker->s->name); - int name_match = worker->s->is_name_matchable; if (name_len <= url_len - && name_len >= min_match && name_len > *max_match - && ((name_match - && (mask & AP_PROXY_WORKER_IS_MATCH) - && !ap_proxy_strcmp_ematch(url, worker->s->name)) - || (!name_match - && (mask & AP_PROXY_WORKER_IS_PREFIX) - && !strncmp(url, worker->s->name, name_len)))) { + /* min_match is the length of the scheme://host part only of url, + * so it's used as a fast path to avoid the match when url is too + * small, but it's irrelevant when the worker host contains globs + * (i.e. ->is_host_matchable). + */ + && (worker->s->is_name_matchable + ? ((mask & AP_PROXY_WORKER_IS_MATCH) + && (worker->s->is_host_matchable || name_len >= min_match) + && !ap_proxy_strcmp_ematch(url, worker->s->name)) + : ((mask & AP_PROXY_WORKER_IS_PREFIX) + && (name_len >= min_match) + && !strncmp(url, worker->s->name, name_len)))) { *max_match = name_len; return 1; } @@ -2139,6 +2142,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p, wshared->was_malloced = (mask & AP_PROXY_WORKER_IS_MALLOCED) != 0; if (mask & AP_PROXY_WORKER_IS_MATCH) { wshared->is_name_matchable = 1; + wshared->is_host_matchable = (address_not_reusable != 0); /* Before AP_PROXY_WORKER_IS_MATCH (< 2.4.47), a regex worker with * dollar substitution was never matched against any actual URL, thus |