Translate it to
<Proxy balancer://abcd>
BalancerMember https://mybackend.local
</Proxy>
...
<Location /path>
ProxyPass balancer://abcd/path
ProxyPassReverse https://mybackend.local:433/path
ProxyPassReverse https://mybackend.local/path
</Location>
And yes it doubles the amount ProxyPassReverse directives in case of such
backends.
Regards
Rüdiger
Von: Thomas Eckert [mailto:[email protected]]
Gesendet: Mittwoch, 27. November 2013 14:42
An: [email protected]
Betreff: Re: ap_proxy_location_reverse_map()
Indeed, with that example it works. Now how do I translate this into a
configuration like the extract I posted earlier
<Proxy balancer://abcd>
BalancerMember https://mybackend.local
</Proxy>
...
<Location /path>
ProxyPass balancer://abcd/path
ProxyPassReverse balancer://abcd/path
</Location>
As I said, according to the docs BalancerMember accepts an url as argument just
like ProxyPass and ProxyPassReverse do but the port seems to be ignored with
BalancerMember.
This solution requires the configuration to be repeated, does it not ? Instead
of doing
ProxyPassReverse /path server
you need to do
ProxyPassReverse /path https://backend.local:433/path
ProxyPassReverse /path https://backend.local/path
and also (if applicable)
ProxyPassReverse /path http://backend.local:80/path
ProxyPassReverse /path http://backend.local/path
so it effectively doubles the amount of required ProxyPassReverse to be on the
safe side. This is even though the ports are standard ports for the schemes and
could just as well be skipped.
On Wed, Nov 27, 2013 at 2:08 PM, Plüm, Rüdiger, Vodafone Group
<[email protected]<mailto:[email protected]>> wrote:
In this case your configuration is wrong.
Try either
ProxyPassReverse /path https://mybackend.local:443/path
ProxyPassReverse /path https://mybackend.local/path
Or
ProxyPassReverse / https://mybackend.local:443/
ProxyPassReverse / https://mybackend.local/
Regards
Rüdiger
Von: Thomas Eckert
[mailto:[email protected]<mailto:[email protected]>]
Gesendet: Mittwoch, 27. November 2013 13:44
An: [email protected]<mailto:[email protected]>
Betreff: Re: ap_proxy_location_reverse_map()
Reversing the order results in
Location https://myfrontend.local/path/path/file?query
My expectation is that
Location https://mybackend.local/path/file?query
Location https://mybackend.local:433/path/file?query
both be rewritten to
Location https://myfrontend.local/path/file?query
because I think this is the only plausible 'address' the reverse proxy can
deliver to the client. If stripping the port results in breaking some logic
with the backend then that's an internal issue most likely not fixable by
simple rewriting. I don't think we can assume the reverse proxy uses the same
ports facing the clients as does the backend facing the reverse proxy. Maybe a
mapping option like 'backend_port[n] => frontend_port[k]" for known n and k is
possible but I even doubt that.
In my test case, there is no 'fishy' stuff going on. The Location headers look
good, simply with an added port that - strictly speaking - is not necessary. I
can imagine the MS folks added the port there to get their URL parsing a little
less complex by standardizing their URL formats (in as out). That's just me
speculating however.
On Wed, Nov 27, 2013 at 12:27 PM, Plüm, Rüdiger, Vodafone Group
<[email protected]<mailto:[email protected]>> wrote:
Can you please reverse the order of your ProxyPassReverse directives in the
test (such that the one with the port comes first in the configuration).
Regards
Rüdiger
Von: Plüm, Rüdiger, Vodafone Group
Gesendet: Mittwoch, 27. November 2013 12:19
An: [email protected]<mailto:[email protected]>
Betreff: AW: ap_proxy_location_reverse_map()
What location would you expect? I agree that the result you see is not correct.
BTW: ProxyPassReverse does not change anything to your balancer setup.
Regards
Rüdiger
Von: Thomas Eckert [mailto:[email protected]]
Gesendet: Mittwoch, 27. November 2013 11:54
An: [email protected]<mailto:[email protected]>
Betreff: Re: ap_proxy_location_reverse_map()
Thanks but you ignored the config extract I mentioned.
> ProxyPassReverse / https://mybackend.local
> ProxyPassReverse / https://mybackend.local:443
does this not translate to
<Proxyy balancer://abcd>
BalancerMember https://mybackend.local status=-SE
BalancerMember https://mybackend.local:443 status=-SE
</Proxy>
? I'm not even sure whether this is correct in terms of configuration - the
docs speak of 'url' as argument to BalancerMember so I guess giving the port is
ok. However, when accessing /path this does not do anything different then
without adding the ':443' line.
The original problem was that Location headers like
Location:
https://mybackend.local:443/path/file?query<https://myserver:443/path/file?query>
are being rewritten to
Location: https://myfrontend.local/:443/path/file?query
which is nonsense. Based on your example I replaced the usage of the balancer
argument with
ProxyPass /path https://mybackend.local
ProxyPassReverse /path https://mybackend.local
ProxyPassReverse /path https://mybackend.local:443
and it will rewrite the above mentioned Location header to
https://myfrontend.local/path:443/path/file?query
which is just as wrong.
Did I misunderstand you somewhere ?
<https://mybackend.local:443>
On Wed, Nov 27, 2013 at 11:25 AM, Plüm, Rüdiger, Vodafone Group
<[email protected]<mailto:[email protected]>> wrote:
ProxyPass / http://backend:8080/
ProxyPassReverse / http://backend:8080/
There the port matters.
Fix for your issue:
ProxyPassReverse / https://mybackend.local
ProxyPassReverse / https://mybackend.local:443
Regards
Rüdiger
Von: Thomas Eckert
[mailto:[email protected]<mailto:[email protected]>]
Gesendet: Mittwoch, 27. November 2013 11:20
An: [email protected]<mailto:[email protected]>
Betreff: Re: ap_proxy_location_reverse_map()
Given a config extract like
<Proxyy balancer://abcd>
BalancerMember https://mybackend.local status=-SE
</Proxy>
...
<Location />
ProxyPass balancer://abcd/
ProxyPassReverse balancer://abcd/
</Location>
what exactly is your suggestion ? Also, can you give an example for a situation
where the port matters ?
On Tue, Nov 26, 2013 at 5:14 PM, Plüm, Rüdiger, Vodafone Group
<[email protected]<mailto:[email protected]>> wrote:
IMHO this should be fixed in the configuration with an additional mapping that
has the port in. In many cases the port matters.
Regards
Rüdiger
From: Thomas Eckert
[mailto:[email protected]<mailto:[email protected]>]
Sent: Dienstag, 26. November 2013 17:11
To: [email protected]<mailto:[email protected]>
Subject: ap_proxy_location_reverse_map()
I've been debugging some problems with incorrectly reverse mapped Location
headers and found some backend servers (e.g. OWA for Exchange 2013) to give
headers like
Location: https://myserver:443/path/file?query
which I think are perfectly fine. mod proxy fails to do the trick because
else {
const char *part = url;
l2 = strlen(real);
if (real[0] == '/') {
part = ap_strstr_c(url, "://");
if (part) {
part = ap_strchr_c(part+3, '/');
if (part) {
l1 = strlen(part);
}
else {
part = url;
}
}
else {
part = url;
}
}
> if (l1 >= l2 && strncasecmp(real, part, l2) == 0) {
u = apr_pstrcat(r->pool, ent[i].fake, &part[l2], NULL);
return ap_is_url(u) ? u : ap_construct_url(r->pool, u, r);
}
}
which does not take the port behind the domain name into consideration (note:
simple example setup, fake path is just '/' obviously). I looked over the code
and got the feeling the same problem applies to the whole section, not just
that one strncasecmp() call. Since the port given by the backend server is not
much use to the reverse proxy at that point, we can just drop it on the floor
and continue, e.g. like this
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -894,11 +894,17 @@ PROXY_DECLARE(const char *)
ap_proxy_location_reverse_map(request_rec *r,
}
}
else if (l1 >= l2 && strncasecmp((*worker)->s->name, url, l2)
== 0) {
+ const char* tmp_pchar = url + l2;
+ if (url[l2] == ':') {
+ tmp_pchar = ap_strchr_c(tmp_pchar, '/');
+ }
+
/* edge case where fake is just "/"... avoid double slash
*/
- if ((ent[i].fake[0] == '/') && (ent[i].fake[1] == 0) &&
(url[l2] == '/')) {
- u = apr_pstrdup(r->pool, &url[l2]);
+ if ((ent[i].fake[0] == '/') && (ent[i].fake[1] == 0) &&
+ (tmp_pchar != NULL) && (tmp_pchar[0] == '/')) {
+ u = apr_pstrdup(r->pool, tmp_pchar);
} else {
- u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
+ u = apr_pstrcat(r->pool, ent[i].fake, tmp_pchar + 1,
NULL);
}
return ap_is_url(u) ? u : ap_construct_url(r->pool, u, r);
As said above this most likely needs to be spread to the other cases in that
section as well. Anyone see problems with this ?