]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mod_proxy: Fix selection of ProxyPassMatch workers with host/port substitution. PR...
authorYann Ylavic <ylavic@apache.org>
Thu, 1 Aug 2024 11:35:26 +0000 (11:35 +0000)
committerYann Ylavic <ylavic@apache.org>
Thu, 1 Aug 2024 11:35:26 +0000 (11:35 +0000)
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

changes-entries/bz69233.txt [new file with mode: 0644]
include/ap_mmn.h
modules/proxy/mod_proxy.h
modules/proxy/proxy_util.c

diff --git a/changes-entries/bz69233.txt b/changes-entries/bz69233.txt
new file mode 100644 (file)
index 0000000..9e1e43b
--- /dev/null
@@ -0,0 +1,2 @@
+  *) mod_proxy: Fix selection of ProxyPassMatch workers with substitution
+     in the host name or port. PR 69233. [Yann Ylavic]
\ No newline at end of file
index ad4b77bd33a01f4c93251a96773939e71804ef04..c9ae4c157c7d43309da47c2b3cebde0e420dde22 100644 (file)
  *                         and AP_REQUEST_TRUSTED_CT BNOTE.
  * 20211221.24 (2.5.1-dev) Add ap_proxy_fixup_uds_filename()
  * 20211221.25 (2.5.1-dev) AP_SLASHES and AP_IS_SLASH
+ * 20211221.26 (2.5.1-dev) Add is_host_matchable to proxy_worker_shared
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20211221
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 25             /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 26             /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index cf6d5057dfdc35b3b6e75366290f09e4c8c7ab5a..6594159e987b537a3f8b7867bf28fc53cedf1b82 100644 (file)
@@ -492,6 +492,7 @@ typedef struct {
     unsigned int     disablereuse_set:1;
     unsigned int     was_malloced:1;
     unsigned int     is_name_matchable:1;
+    unsigned int     is_host_matchable:1;
     unsigned int     response_field_size_set:1;
     unsigned int     address_ttl_set:1;
     apr_int32_t      address_ttl;    /* backend address' TTL (seconds) */
index 558af5cfab3609dcec76ab8661f5cfc324074ea8..1a11498f5d382e14e51dfd032ebb1350a8deb1e8 100644 (file)
@@ -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