@@ -1826,18 +1826,41 @@ static int ap_proxy_strcmp_ematch(const char *str, const char *expected)
18261826 return 0 ;
18271827}
18281828
1829+ static int worker_matches (proxy_worker * worker ,
1830+ const char * url , apr_size_t url_len ,
1831+ apr_size_t min_match , apr_size_t * max_match ,
1832+ unsigned int mask )
1833+ {
1834+ apr_size_t name_len = strlen (worker -> s -> name_ex );
1835+ if (name_len <= url_len
1836+ && name_len > * max_match
1837+ /* min_match is the length of the scheme://host part only of url,
1838+ * so it's used as a fast path to avoid the match when url is too
1839+ * small, but it's irrelevant when the worker host contains globs
1840+ * (i.e. ->is_host_matchable).
1841+ */
1842+ && (worker -> s -> is_name_matchable
1843+ ? ((mask & AP_PROXY_WORKER_IS_MATCH )
1844+ && (worker -> s -> is_host_matchable || name_len >= min_match )
1845+ && !ap_proxy_strcmp_ematch (url , worker -> s -> name_ex ))
1846+ : ((mask & AP_PROXY_WORKER_IS_PREFIX )
1847+ && (name_len >= min_match )
1848+ && !strncmp (url , worker -> s -> name_ex , name_len )))) {
1849+ * max_match = name_len ;
1850+ return 1 ;
1851+ }
1852+ return 0 ;
1853+ }
1854+
18291855PROXY_DECLARE (proxy_worker * ) ap_proxy_get_worker_ex (apr_pool_t * p ,
18301856 proxy_balancer * balancer ,
18311857 proxy_server_conf * conf ,
18321858 const char * url ,
18331859 unsigned int mask )
18341860{
1835- proxy_worker * worker ;
18361861 proxy_worker * max_worker = NULL ;
1837- int max_match = 0 ;
1838- int url_length ;
1839- int min_match ;
1840- int worker_name_length ;
1862+ apr_size_t min_match , max_match = 0 ;
1863+ apr_size_t url_len ;
18411864 const char * c ;
18421865 char * url_copy ;
18431866 int i ;
@@ -1858,8 +1881,8 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
18581881 return NULL ;
18591882 }
18601883
1861- url_length = strlen (url );
1862- url_copy = apr_pstrmemdup (p , url , url_length );
1884+ url_len = strlen (url );
1885+ url_copy = apr_pstrmemdup (p , url , url_len );
18631886
18641887 /* Default to lookup for both _PREFIX and _MATCH workers */
18651888 if (!(mask & (AP_PROXY_WORKER_IS_PREFIX | AP_PROXY_WORKER_IS_MATCH ))) {
@@ -1885,48 +1908,28 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
18851908 ap_str_tolower (url_copy );
18861909 min_match = strlen (url_copy );
18871910 }
1911+
18881912 /*
18891913 * Do a "longest match" on the worker name to find the worker that
18901914 * fits best to the URL, but keep in mind that we must have at least
18911915 * a minimum matching of length min_match such that
18921916 * scheme://hostname[:port] matches between worker and url.
18931917 */
1894-
18951918 if (balancer ) {
1896- proxy_worker * * workers = (proxy_worker * * )balancer -> workers -> elts ;
1897- for (i = 0 ; i < balancer -> workers -> nelts ; i ++ , workers ++ ) {
1898- worker = * workers ;
1899- if ( ((worker_name_length = strlen (worker -> s -> name_ex )) <= url_length )
1900- && (worker_name_length >= min_match )
1901- && (worker_name_length > max_match )
1902- && (worker -> s -> is_name_matchable
1903- || ((mask & AP_PROXY_WORKER_IS_PREFIX )
1904- && strncmp (url_copy , worker -> s -> name_ex ,
1905- worker_name_length ) == 0 ))
1906- && (!worker -> s -> is_name_matchable
1907- || ((mask & AP_PROXY_WORKER_IS_MATCH )
1908- && ap_proxy_strcmp_ematch (url_copy ,
1909- worker -> s -> name_ex ) == 0 )) ) {
1910- max_worker = worker ;
1911- max_match = worker_name_length ;
1919+ proxy_worker * * worker = (proxy_worker * * )balancer -> workers -> elts ;
1920+ for (i = 0 ; i < balancer -> workers -> nelts ; i ++ , worker ++ ) {
1921+ if (worker_matches (* worker , url_copy , url_len ,
1922+ min_match , & max_match , mask )) {
1923+ max_worker = * worker ;
19121924 }
19131925 }
1914- } else {
1915- worker = (proxy_worker * )conf -> workers -> elts ;
1926+ }
1927+ else {
1928+ proxy_worker * worker = (proxy_worker * )conf -> workers -> elts ;
19161929 for (i = 0 ; i < conf -> workers -> nelts ; i ++ , worker ++ ) {
1917- if ( ((worker_name_length = strlen (worker -> s -> name_ex )) <= url_length )
1918- && (worker_name_length >= min_match )
1919- && (worker_name_length > max_match )
1920- && (worker -> s -> is_name_matchable
1921- || ((mask & AP_PROXY_WORKER_IS_PREFIX )
1922- && strncmp (url_copy , worker -> s -> name_ex ,
1923- worker_name_length ) == 0 ))
1924- && (!worker -> s -> is_name_matchable
1925- || ((mask & AP_PROXY_WORKER_IS_MATCH )
1926- && ap_proxy_strcmp_ematch (url_copy ,
1927- worker -> s -> name_ex ) == 0 )) ) {
1930+ if (worker_matches (worker , url_copy , url_len ,
1931+ min_match , & max_match , mask )) {
19281932 max_worker = worker ;
1929- max_match = worker_name_length ;
19301933 }
19311934 }
19321935 }
@@ -2132,6 +2135,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p,
21322135 wshared -> was_malloced = (mask & AP_PROXY_WORKER_IS_MALLOCED ) != 0 ;
21332136 if (mask & AP_PROXY_WORKER_IS_MATCH ) {
21342137 wshared -> is_name_matchable = 1 ;
2138+ wshared -> is_host_matchable = (address_not_reusable != 0 );
21352139
21362140 /* Before AP_PROXY_WORKER_IS_MATCH (< 2.4.47), a regex worker with
21372141 * dollar substitution was never matched against any actual URL, thus
0 commit comments