Bug 38864

Summary: ProxyPassReverse fails in <Location>
Product: Apache httpd-2 Reporter: Douglas Acheson <douglas.acheson>
Component: mod_proxyAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED LATER    
Severity: enhancement CC: calestyo
Priority: P2 Keywords: FixedInTrunk, MassUpdate, PatchAvailable
Version: 2.2.0   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: patch

Description Douglas Acheson 2006-03-06 16:00:19 UTC
I want to proxy (loadbalance) all jsp and frm requests to tomcat through the
proxy and LB modules, and I cannot.

  I have the proxying/LBing working correctly for the following:

<LocationMatch "/myproject">
  ProxyPass balancer://myCluster/myproject stickysession=JSESSIONID
  ProxyPassReverse balancer://myCluster/bpsproject
  Order Deny,Allow
  Allow from all
</LocationMatch>

Now, when I try to use a regular expression to proxy .jsp and .frm requests,
there is no proxying done all.  This is what I use:

<LocationMatch "^/myproject/.+\.(jsp|frm)$">
  ProxyPass        balancer://myCluster/myproject stickysession=JSESSIONID
  ProxyPassReverse balancer://myCluster/bpsproject
  Order Deny,Allow
  Allow from all
</LocationMatch>

In the error log I get a 404 error:
[Mon Mar 06 10:45:41 2006] [error] [client 10.0.0.152] File does not exist:
C:/dwfa/runtime/apache/httpd/html/myproject/login.jsp

I have tried this with win32 (got binary) and linux (built) with the same results.
Comment 1 Astrid Ke├čler 2006-03-06 20:20:49 UTC
*** Bug 38865 has been marked as a duplicate of this bug. ***
Comment 2 Douglas Acheson 2006-03-06 20:49:37 UTC
The configuration snipit is really
<LocationMatch "^/myproject/.+\.(jsp|frm)$">
  ProxyPass        balancer://myCluster/myproject stickysession=JSESSIONID
  ProxyPassReverse balancer://myCluster/myproject
  Order Deny,Allow
  Allow from all
</LocationMatch>

I had a typo in the one originally posted.  Still have tht same issue
Comment 3 Ruediger Pluem 2006-03-06 21:24:32 UTC
ProxyPass does not work with regular expressions. Thus it does not work inside
LocationMatch. Apart from the discussion if this is a bug and if yes if it is a
bug in the documentation or in the code you can use mod_rewrite to solve your
problem:

RewriteEngine on
RewriteRule (^/myproject/.+\.(jsp|frm)$) balancer://myCluster$1

<Proxy balancer://myCluster>
BalancerMember http://127.0.0.1:8080
BalancerMember http://127.0.0.1:8081 
ProxySet stickysession=JSESSIONID
</Proxy>

ProxyPassReverse /myproject http://127.0.0.1:8080/myproject
ProxyPassReverse /myproject http://127.0.0.1:8081/myproject

Please keep in mind that you MUST use ProxySet AFTER the BalancerMember directives.

Comment 4 Douglas Acheson 2006-03-08 19:36:39 UTC
Thx your for your reply.  A couple of things:

1. I could not find, but does not mean it does not exist, documentation about
proxy and REs.  But, if it does not work, so be it.

2.  Not sure why LocationMatch and proxy work to tightly.  Here is my simple
view of how I thought it should work:
  if the incoming URL matches the grammar supplied by the RE in LocationMatch
    do the work (in this case proxy the request)
I do not understand why proxy needs to know about RE as, IMHO, only
LocationMatch needs to do the patching.

3. I really appreciate an alternate solution.  I have tried that and it does not
work (as I expect).  If I take what you supplied I get tomcat serving up
everything (jsp, gif, etc).  So I went and read up on RewriteRule and found out
that I should use the [p] token at the end of the "rule".  When I tried this,
nothing works.  So I am really confused now.

4.  I do not understand why the ProxyPassReverse is written in that manor.  Why
does it use http as the protocol and why must I specify every member?  Should I
not be able to use balancer as the protocol.

4.  Since my original defect report,t in all honestly has been resolved, I
understand if you want to close this ticket.

Here is my new snippet I used:

<IfDefine rewrite>
  RewriteEngine On
 
  <Proxy balancer://myCluster>
    BalancerMember ajp://10.0.0.152:8009 loadfactor=100 route=152
    BalancerMember ajp://10.0.0.153:8009 loadfactor=100 route=153
    ProxySet stickysession=JSESSIONID
    Order Deny,Allow
    Allow from all
  </Proxy>

  RewriteRule (^/myproject/.+\.(jsp|html|form))  balancer://myCluster$0
  #RewriteRule (^/myproject/.+\.(jsp|html|form)) balancer://myCluster$0 [p]

  ProxyPassReverse /myproject http://10.0.0.152:8080/myproject
  ProxyPassReverse /myproject http://10.0.0.153:8080/myproject

  <Location /balancer-manager>
    SetHandler balancer-manager
    Order Deny,Allow
    Allow from all
  </Location>

</IfDefine>
Comment 5 Ruediger Pluem 2006-03-08 20:37:00 UTC
(In reply to comment #4)

> 
> 2.  Not sure why LocationMatch and proxy work to tightly.  Here is my simple
> view of how I thought it should work:
>   if the incoming URL matches the grammar supplied by the RE in LocationMatch
>     do the work (in this case proxy the request)
> I do not understand why proxy needs to know about RE as, IMHO, only
> LocationMatch needs to do the patching.

That is due to how the internal processing works. I admit that this is not
logical from a users perspective view. Basicly a ProxyPass inside a Location or
LocationMatch container is transformed to ProxyPass <string of
Locationcontainer> <proxytarget> during the parsing of the configuration. So in
your example this gets transformed to
ProxyPass ^/myproject/.+\.(jsp|frm)$ balancer://myCluster/myproject
Stickysession=JSESSIONID

As ProxyPass does not know anything about RE it tries to match the URL plain
against ^/myproject/.+\.(jsp|frm)$ which cannot work for obvious reasons.

> 
> 3. I really appreciate an alternate solution.  I have tried that and it does not
> work (as I expect).  If I take what you supplied I get tomcat serving up
> everything (jsp, gif, etc).  So I went and read up on RewriteRule and found 
out
> that I should use the [p] token at the end of the "rule".  When I tried this,

Ah, sorry a copy and paste error from my side. It should have been

RewriteRule (^/myproject/.+\.(jsp|frm)$) balancer://myCluster$1 [P]

Astonishing that this worked at all without the [P] flag.

> nothing works.  So I am really confused now.

It should work. I tested it in my environment. You have an error in your config
(see below)

> 
> 4.  I do not understand why the ProxyPassReverse is written in that manor.  Why
> does it use http as the protocol and why must I specify every member?  Should I
> not be able to use balancer as the protocol.

No. ProxyPassReverse works like a lookup table. It checks possible Location
headers of the HTTP responses from the backend and transforms them into the
correct ones (by using the lookup table) to make redirects work. But the backend
servers do know nothing about the balancer scheme. So they put in their local
name (http://127.0.0.1:8080 and http://127.0.0.1:8081 in your case) in their
Location headers.


> 
>   RewriteRule (^/myproject/.+\.(jsp|html|form))  balancer://myCluster$0
>   #RewriteRule (^/myproject/.+\.(jsp|html|form)) balancer://myCluster$0 [p]

The error is $0 at the end. It must be $1. Please use the line with the [P] flag
at the end.

Comment 6 Douglas Acheson 2006-03-09 15:33:08 UTC
Thanks I got it working.  Appreciate all your help ...
Comment 7 Steve Madsen 2009-02-16 08:59:32 UTC
This bug is marked resolved and fixed, but it doesn't work in the current 2.2.11 release. ProxyPassReverse, in particular, still does not function inside LocationMatch as an end-user expects it to after reading the 2.2 documentation.

I'm trying to account for case sensitivity on a proxied prefix, e.g.:

<LocationMatch ^(?i)/foo/>
    ProxyPassReverse http://foo.backend.server/
</LocationMatch>

Per http://www.apachetutor.org/admin/reverseproxies, ProxyPassReverse should be set up like this to account for broken applications that issue a redirect using only the path instead of a full URL.

Mainly I'm interested in clarification on this bug. Should it work? If so, there is a regression in the current stable release.

If it is known not to work and there is no intention to fix it, I think the documentation should be updated to explicitly state that the directives do not work inside Location using the ~ syntax or in LocationMatch.
Comment 8 Nick Kew 2009-12-23 16:36:54 UTC
(In reply to comment #7)
> This bug is marked resolved and fixed, but it doesn't work in the current
> 2.2.11 release. ProxyPassReverse, in particular, still does not function inside
> LocationMatch as an end-user expects it to after reading the 2.2 documentation.

You have indeed found a rather serious regression.

It's actually in mod_proxy, and can be worked around by replacing your
ProxyPassReverse /
with
ProxyPassReverse balancer:///
(note three slashes are not a typo)!  It doesn't matter that you're not using the balancer - this is just a failure in the parsing of the URL in the response header.

Not sure when this happened, but it appears to go back quite some time.
Guess I need to fix both the code and the tutorial!
Comment 9 Nick Kew 2009-12-25 07:28:31 UTC
Just fixed in trunk in r893871
Will upload patch in a moment.
Comment 10 Nick Kew 2009-12-25 07:31:18 UTC
Created attachment 24757 [details]
patch

trunk patch, works with 2.2.x versions.
Comment 11 Nick Kew 2009-12-25 14:17:21 UTC
(In reply to comment #8)
> (In reply to comment #7)
> > This bug is marked resolved and fixed, but it doesn't work in the current
> > 2.2.11 release. ProxyPassReverse, in particular, still does not function inside
> > LocationMatch as an end-user expects it to after reading the 2.2 documentation.
> 
> You have indeed found a rather serious regression.

... which is not the problem you were asking about - sorry for the distraction, and thanks to rpluem for pointing it out.  I might look at that too, but supporting regexps is new code, and more likely to happen in 2.3/2.4 (which alreasy supports regexps in related areas like ProxyPass).
Comment 12 Christoph Anton Mitterer 2012-12-08 23:58:37 UTC
Quite some time old...

Could someone tell me whether this is still an issue?
Comment 13 alessandro natapin 2013-02-14 22:22:28 UTC
the directive ProxyPassReverse works correctly also in the form 
"ProxyPassReverse /" inside <Location>. Just tested with Location containing full URL. I couldn't reproduce the buggy case with just path in location header.
The Apache version used is 2.4.3

As regard the error got with ProxyPassReverse inside <LocationMatch>, it is not correct to set it as bug, because, as stated in the offcial documentation, the RE is not treated as such by ProxyPassReverse 

".... When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same occurs inside a <LocationMatch> section, but will probably not work as intended, as ProxyPassReverse will interpret the regexp literally as a path;...."

So I find correct to set this item as enhancement. It should be closed when a sort of ProxyPassReverseMatch will be implemented.
Comment 14 William A. Rowe Jr. 2018-11-07 21:09:44 UTC
Please help us to refine our list of open and current defects; this is a mass update of old and inactive Bugzilla reports which reflect user error, already resolved defects, and still-existing defects in httpd.

As repeatedly announced, the Apache HTTP Server Project has discontinued all development and patch review of the 2.2.x series of releases. The final release 2.2.34 was published in July 2017, and no further evaluation of bug reports or security risks will be considered or published for 2.2.x releases. All reports older than 2.4.x have been updated to status RESOLVED/LATER; no further action is expected unless the report still applies to a current version of httpd.

If your report represented a question or confusion about how to use an httpd feature, an unexpected server behavior, problems building or installing httpd, or working with an external component (a third party module, browser etc.) we ask you to start by bringing your question to the User Support and Discussion mailing list, see [https://httpd.apache.org/lists.html#http-users] for details. Include a link to this Bugzilla report for completeness with your question.

If your report was clearly a defect in httpd or a feature request, we ask that you retest using a modern httpd release (2.4.33 or later) released in the past year. If it can be reproduced, please reopen this bug and change the Version field above to the httpd version you have reconfirmed with.

Your help in identifying defects or enhancements still applicable to the current httpd server software release is greatly appreciated.