Skip to content

Commit a2e4b0b

Browse files
committed
*) mod_proxy: Honor parameters of ProxyPassMatch workers with substitution
in the host name or port. PR 69233. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1922958 13f79535-47bb-0310-9956-ffa450edef68
1 parent 3e28318 commit a2e4b0b

File tree

4 files changed

+45
-48
lines changed

4 files changed

+45
-48
lines changed

STATUS

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,6 @@ RELEASE SHOWSTOPPERS:
157157
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
158158
[ start all new proposals below, under PATCHES PROPOSED. ]
159159

160-
*) mod_proxy: Honor parameters of ProxyPassMatch workers with substitution
161-
in the host name or port. PR 69233.
162-
trunk patch: https://svn.apache.org/r1912462
163-
https://svn.apache.org/r1919617
164-
https://svn.apache.org/r1919619
165-
2.4.x patch: https://patch-diff.githubusercontent.com/raw/apache/httpd/pull/469.diff
166-
PR: https://github.com/apache/httpd/pull/469
167-
+1: ylavic, rpluem, jim
168-
169160
*) mod_proxy_fcgi: Fix proxy-fcgi-pathinfo=full
170161
trunk patch: https://svn.apache.org/r1919547
171162
https://svn.apache.org/r1921238

include/ap_mmn.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,14 +607,15 @@
607607
* and CONN_STATE_PROCESSING
608608
* 20120211.136 (2.4.63-dev) Add wait_io field to struct process_score
609609
* 20120211.137 (2.4.63-dev) Add AP_MPMQ_CAN_WAITIO
610+
* 20120211.138 (2.4.63-dev) Add is_host_matchable to proxy_worker_shared
610611
*/
611612

612613
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
613614

614615
#ifndef MODULE_MAGIC_NUMBER_MAJOR
615616
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
616617
#endif
617-
#define MODULE_MAGIC_NUMBER_MINOR 137 /* 0...n */
618+
#define MODULE_MAGIC_NUMBER_MINOR 138 /* 0...n */
618619

619620
/**
620621
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a

modules/proxy/mod_proxy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ typedef struct {
493493
unsigned int address_ttl_set:1;
494494
apr_int32_t address_ttl; /* backend address' TTL (seconds) */
495495
apr_uint32_t address_expiry; /* backend address' next expiry time */
496+
unsigned int is_host_matchable:1;
496497
} proxy_worker_shared;
497498

498499
#define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))

modules/proxy/proxy_util.c

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
18291855
PROXY_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

Comments
 (0)