Skip to content

Commit

Permalink
*) mod_proxy: Honor parameters of ProxyPassMatch workers with substi…
Browse files Browse the repository at this point in the history
…tution

                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
  • Loading branch information
jimjag committed Jan 7, 2025
1 parent 3e28318 commit a2e4b0b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 48 deletions.
9 changes: 0 additions & 9 deletions STATUS
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]

*) mod_proxy: Honor parameters of ProxyPassMatch workers with substitution
in the host name or port. PR 69233.
trunk patch: https://svn.apache.org/r1912462
https://svn.apache.org/r1919617
https://svn.apache.org/r1919619
2.4.x patch: https://patch-diff.githubusercontent.com/raw/apache/httpd/pull/469.diff
PR: https://github.com/apache/httpd/pull/469
+1: ylavic, rpluem, jim

*) mod_proxy_fcgi: Fix proxy-fcgi-pathinfo=full
trunk patch: https://svn.apache.org/r1919547
https://svn.apache.org/r1921238
Expand Down
3 changes: 2 additions & 1 deletion include/ap_mmn.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,14 +607,15 @@
* and CONN_STATE_PROCESSING
* 20120211.136 (2.4.63-dev) Add wait_io field to struct process_score
* 20120211.137 (2.4.63-dev) Add AP_MPMQ_CAN_WAITIO
* 20120211.138 (2.4.63-dev) Add is_host_matchable to proxy_worker_shared
*/

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

#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
#define MODULE_MAGIC_NUMBER_MINOR 137 /* 0...n */
#define MODULE_MAGIC_NUMBER_MINOR 138 /* 0...n */

/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Expand Down
1 change: 1 addition & 0 deletions modules/proxy/mod_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ typedef struct {
unsigned int address_ttl_set:1;
apr_int32_t address_ttl; /* backend address' TTL (seconds) */
apr_uint32_t address_expiry; /* backend address' next expiry time */
unsigned int is_host_matchable:1;
} proxy_worker_shared;

#define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))
Expand Down
80 changes: 42 additions & 38 deletions modules/proxy/proxy_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1826,18 +1826,41 @@ static int ap_proxy_strcmp_ematch(const char *str, const char *expected)
return 0;
}

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_ex);
if (name_len <= url_len
&& name_len > *max_match
/* 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_ex))
: ((mask & AP_PROXY_WORKER_IS_PREFIX)
&& (name_len >= min_match)
&& !strncmp(url, worker->s->name_ex, name_len)))) {
*max_match = name_len;
return 1;
}
return 0;
}

PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
proxy_balancer *balancer,
proxy_server_conf *conf,
const char *url,
unsigned int mask)
{
proxy_worker *worker;
proxy_worker *max_worker = NULL;
int max_match = 0;
int url_length;
int min_match;
int worker_name_length;
apr_size_t min_match, max_match = 0;
apr_size_t url_len;
const char *c;
char *url_copy;
int i;
Expand All @@ -1858,8 +1881,8 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
return NULL;
}

url_length = strlen(url);
url_copy = apr_pstrmemdup(p, url, url_length);
url_len = strlen(url);
url_copy = apr_pstrmemdup(p, url, url_len);

/* Default to lookup for both _PREFIX and _MATCH workers */
if (!(mask & (AP_PROXY_WORKER_IS_PREFIX | AP_PROXY_WORKER_IS_MATCH))) {
Expand All @@ -1885,48 +1908,28 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p,
ap_str_tolower(url_copy);
min_match = strlen(url_copy);
}

/*
* Do a "longest match" on the worker name to find the worker that
* fits best to the URL, but keep in mind that we must have at least
* a minimum matching of length min_match such that
* scheme://hostname[:port] matches between worker and url.
*/

if (balancer) {
proxy_worker **workers = (proxy_worker **)balancer->workers->elts;
for (i = 0; i < balancer->workers->nelts; i++, workers++) {
worker = *workers;
if ( ((worker_name_length = strlen(worker->s->name_ex)) <= url_length)
&& (worker_name_length >= min_match)
&& (worker_name_length > max_match)
&& (worker->s->is_name_matchable
|| ((mask & AP_PROXY_WORKER_IS_PREFIX)
&& strncmp(url_copy, worker->s->name_ex,
worker_name_length) == 0))
&& (!worker->s->is_name_matchable
|| ((mask & AP_PROXY_WORKER_IS_MATCH)
&& ap_proxy_strcmp_ematch(url_copy,
worker->s->name_ex) == 0)) ) {
max_worker = worker;
max_match = worker_name_length;
proxy_worker **worker = (proxy_worker **)balancer->workers->elts;
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
if (worker_matches(*worker, url_copy, url_len,
min_match, &max_match, mask)) {
max_worker = *worker;
}
}
} else {
worker = (proxy_worker *)conf->workers->elts;
}
else {
proxy_worker *worker = (proxy_worker *)conf->workers->elts;
for (i = 0; i < conf->workers->nelts; i++, worker++) {
if ( ((worker_name_length = strlen(worker->s->name_ex)) <= url_length)
&& (worker_name_length >= min_match)
&& (worker_name_length > max_match)
&& (worker->s->is_name_matchable
|| ((mask & AP_PROXY_WORKER_IS_PREFIX)
&& strncmp(url_copy, worker->s->name_ex,
worker_name_length) == 0))
&& (!worker->s->is_name_matchable
|| ((mask & AP_PROXY_WORKER_IS_MATCH)
&& ap_proxy_strcmp_ematch(url_copy,
worker->s->name_ex) == 0)) ) {
if (worker_matches(worker, url_copy, url_len,
min_match, &max_match, mask)) {
max_worker = worker;
max_match = worker_name_length;
}
}
}
Expand Down Expand Up @@ -2132,6 +2135,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
Expand Down

0 comments on commit a2e4b0b

Please sign in to comment.