httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Micha Lenk <mi...@lenk.info>
Subject [PATCH 51489] ProxyPassReverse issue + patch
Date Fri, 08 Jul 2011 16:29:50 GMT
Hi Apache developers,

I'm using Apache as a reverse proxy in a simple load balancer setup.
I use ProxyPassReverse in order to re-write the backend server name in 
HTTP redirections (ie. in the Location header of the HTTP response).
My configuration for the virtual host essentially looks like this:

<Proxy balancer://196f045aca6adc82a0b6eea93ed286a1>
	BalancerMember http://server-1.local status=-SE
	BalancerMember http://server-2.local status=-SE
</Proxy>
<VirtualHost 10.8.16.33:80>
	ServerName frontend.local

	<Location />
		ProxyPass balancer://196f045aca6adc82a0b6eea93ed286a1/
		ProxyPassReverse balancer://196f045aca6adc82a0b6eea93ed286a1/
	</Location>
</VirtualHost>

Now, I was wondering why redirects get an additional slash between the 
server name and the path. Example:

1. The backend server redirects the URL http://server-1.local/foo to
    the URL http://server-1.local/foo/ because this is actually a
    directory (so far no issue)

2. With the configuration above the reverse proxy redirects the URL
    http://frontend.local/foo to http://frontend.local//foo/

What I bother about is the additional slash before '/foo/', so I digged 
into the source code and found the following lines in 
modules/proxy/proxy_util.c:

PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
                               proxy_dir_conf *conf, const char *url)
{
     [...]
     l1 = strlen(url);
     [...]
     for (i = 0; i < conf->raliases->nelts; i++) {
         if (ap_proxy_valid_balancer_name((char *)real, 0) &&
             (balancer = ap_proxy_get_balancer(r->pool, sconf, real))) {
             int n, l3 = 0;
             proxy_worker **worker = (proxy_worker 
**)balancer->workers->elts;
             const char *urlpart = ap_strchr_c(real, '/');
             if (urlpart) {
                 if (!urlpart[1])
                     urlpart = NULL;
                 else
                     l3 = strlen(urlpart);
             }
             for (n = 0; n < balancer->workers->nelts; n++) {
                 l2 = strlen((*worker)->s->name);
                 if (urlpart) {
                     /* urlpart (l3) assuredly starts with its own '/' */
                     if ((*worker)->s->name[l2 - 1] == '/')
                         --l2;
                     if (l1 >= l2 + l3
                             && strncasecmp((*worker)->s->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 if (l1 >= l2 && strncasecmp((*worker)->s->name, 
url, l2) == 0) {
                     u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
                     return ap_construct_url(r->pool, u, r);
                 }
                 worker++;
             }
             [...]

Right now I don't really understand the reason for the special casing of 
urlpart == "/" in modules/proxy/proxy_util.c, lines 1126 to 1129 (SVN 
rev. 1144374). If urlpart == "/", then the code in lines 1151 and 1152 
gets executed, which seems to add the slash.

I tried to remove the special casing (see submitted patch), and 
apparently the removal fixes the issue.

Does anybody know the reason for the special casing mentioned above?
If not I want to suggest to commit my patch.

Regards,
Micha

Mime
View raw message