mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
As mentioned inline in comments, correctly handle more sophisticated
transformations which currently fail for balancer://foo targets, but work just fine with other ProxyReverse targets. The balancer comparison is a bit trickier. Given the context BalancerMember balancer://alias http://example.com/foo ProxyPassReverse /bash balancer://alias/bar translate url http://example.com/foo/bar/that to /bash/that E.g. there may be several different url-suffixes (1st order) of any particular BalancerMember set e.g. /app1, /app1 and /appbeta while there may be additional suffixes associated with the actual ProxyPassReverse directive. Neither were properly reversed, now both should be properly handled. One *critical* assumption; BalancerMember balancer://alias/foo http://example.com/bar should be documented as a meaningless construct, since one cannot have two members, balancer://alias/foo and balancer://alias/bar, and the balancer member structures discard this path. Note one more existing error case as an XXX comment due to invalid uri comparisons. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@771587 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -1052,6 +1052,7 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
|
|||||||
/*
|
/*
|
||||||
* XXX FIXME: Make sure this handled the ambiguous case of the :<PORT>
|
* XXX FIXME: Make sure this handled the ambiguous case of the :<PORT>
|
||||||
* after the hostname
|
* after the hostname
|
||||||
|
* XXX FIXME: Ensure the /uri component is a case sensitive match
|
||||||
*/
|
*/
|
||||||
if (r->proxyreq != PROXYREQ_REVERSE) {
|
if (r->proxyreq != PROXYREQ_REVERSE) {
|
||||||
return url;
|
return url;
|
||||||
@@ -1069,56 +1070,57 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
|
|||||||
proxy_server_conf *sconf = (proxy_server_conf *)
|
proxy_server_conf *sconf = (proxy_server_conf *)
|
||||||
ap_get_module_config(r->server->module_config, &proxy_module);
|
ap_get_module_config(r->server->module_config, &proxy_module);
|
||||||
proxy_balancer *balancer;
|
proxy_balancer *balancer;
|
||||||
const char *real;
|
const char *real = ent[i].real;
|
||||||
real = ent[i].real;
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
|
||||||
"ppr: real: %s", real);
|
|
||||||
/*
|
/*
|
||||||
* First check if mapping against a balancer and see
|
* First check if mapping against a balancer and see
|
||||||
* if we have such a entity. If so, then we need to
|
* if we have such a entity. If so, then we need to
|
||||||
* find the particulars of the actual worker which may
|
* find the particulars of the actual worker which may
|
||||||
* or may not be the right one... basically, we need
|
* or may not be the right one... basically, we need
|
||||||
* to find which member actually handled this request.
|
* to find which member actually handled this request.
|
||||||
*
|
|
||||||
* TODO: Recover the path from real and use that
|
|
||||||
* for more exact matching
|
|
||||||
*/
|
*/
|
||||||
if ((strncasecmp(real, "balancer:", 9) == 0) &&
|
if ((strncasecmp(real, "balancer://", 11) == 0) &&
|
||||||
(balancer = ap_proxy_get_balancer(r->pool, sconf, real))) {
|
(balancer = ap_proxy_get_balancer(r->pool, sconf, real))) {
|
||||||
int n;
|
int n, l3;
|
||||||
proxy_worker *worker;
|
proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
|
||||||
worker = (proxy_worker *)balancer->workers->elts;
|
const char *urlpart = ap_strchr_c(real + 11, '/');
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
if (urlpart) {
|
||||||
"ppr: checking balancer: %s",
|
if (!urlpart[1])
|
||||||
balancer->name);
|
urlpart = NULL;
|
||||||
|
else
|
||||||
|
l3 = strlen(urlpart);
|
||||||
|
}
|
||||||
|
/* The balancer comparison is a bit trickier. Given the context
|
||||||
|
* BalancerMember balancer://alias http://example.com/foo
|
||||||
|
* ProxyPassReverse /bash balancer://alias/bar
|
||||||
|
* translate url http://example.com/foo/bar/that to /bash/that
|
||||||
|
*/
|
||||||
for (n = 0; n < balancer->workers->nelts; n++) {
|
for (n = 0; n < balancer->workers->nelts; n++) {
|
||||||
if (worker->port) {
|
l2 = strlen(worker->name);
|
||||||
u = apr_psprintf(r->pool, "%s://%s:%d/", worker->scheme,
|
if (urlpart) {
|
||||||
worker->hostname, worker->port);
|
/* urlpart (l3) assuredly starts with its own '/' */
|
||||||
|
if (worker->name[l2 - 1] == '/')
|
||||||
|
--l2;
|
||||||
|
if (l1 >= l2 + l3
|
||||||
|
&& strncasecmp(worker->name, url, l2) == 0
|
||||||
|
&& strncmp(urlpart, url + l2, l3) == 0) {
|
||||||
|
u = apr_pstrcat(r->pool, ent[i].fake, &url[l2 + l3],
|
||||||
|
NULL);
|
||||||
|
return ap_construct_url(r->pool, u, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (l1 >= l2 && strncasecmp(worker->name, url, l2) == 0) {
|
||||||
u = apr_psprintf(r->pool, "%s://%s/", worker->scheme,
|
|
||||||
worker->hostname);
|
|
||||||
}
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
|
||||||
"ppr: matching member (%s) and URL (%s)",
|
|
||||||
u, url);
|
|
||||||
|
|
||||||
l2 = strlen(u);
|
|
||||||
if (l1 >= l2 && strncasecmp(u, url, l2) == 0) {
|
|
||||||
u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
|
u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
|
||||||
"ppr: matched member (%s)", u);
|
|
||||||
return ap_construct_url(r->pool, u, r);
|
return ap_construct_url(r->pool, u, r);
|
||||||
}
|
}
|
||||||
worker++;
|
worker++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
l2 = strlen(real);
|
l2 = strlen(real);
|
||||||
if (l1 >= l2 && strncasecmp(real, url, l2) == 0) {
|
if (l1 >= l2 && strncasecmp(real, url, l2) == 0) {
|
||||||
u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
|
u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
|
||||||
return ap_construct_url(r->pool, u, r);
|
return ap_construct_url(r->pool, u, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user