Bug 60458 - ProxyPass in a Location block loops on local ErrorDocument
Summary: ProxyPass in a Location block loops on local ErrorDocument
Status: REOPENED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy (show other bugs)
Version: 2.4.23
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: FixedInTrunk
Depends on:
Blocks:
 
Reported: 2016-12-09 00:37 UTC by Alexandre Schaff
Modified: 2017-04-05 11:12 UTC (History)
1 user (show)



Attachments
potential fix (1.46 KB, patch)
2016-12-09 01:04 UTC, Eric Covener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexandre Schaff 2016-12-09 00:37:49 UTC
Hello,
(Finally :o) Upgrading from 2.2, I have either a regression or the same "behavior change" as commented in https://bz.apache.org/bugzilla/show_bug.cgi?id=54319.

Please update based on following details.

This conf is added to fresh 2.4.23 build with minimal set of modules ( mpm worker )
# =======BEGIN
ErrorDocument 400 /error/unavailable
ErrorDocument 401 /error/empty
ErrorDocument 403 /error/forbidden
ErrorDocument 404 /error/unavailable

ProxyErrorOverride On
Alias /error "/tmp/error"
ProxyPass /error !

<Directory "/tmp/error">
 AllowOverride None
 Require all granted
</Directory>

ProxyPass / http://127.0.0.1:1234/
ProxyPassReverse / http://127.0.0.1:1234/
# ========= END

"Server" on 127.0.0.1:1234 responds with status 403, no body.
The configuration above works as expected.

If ProxyPass(Reverse) directives are in a Location block : (rest of configuration unchanged)....
# =======BEGIN
 <Location />
     Require all granted
     ProxyPass http://127.0.0.1:1234/
     ProxyPassReverse http://127.0.0.1:1234/
 </Location>
# ========= END

... then an internal requests loop starts until LimitInternalRecursion (10) is reached. Client receives latest 403 response, a status 500 is recorded in access_log.

note : the same configuration (using Order+Allow instead of Require ) on a fresh minimal build of 2.2.31 works as expected.

++
N'Alex.
Comment 1 Eric Covener 2016-12-09 01:04:46 UTC
Created attachment 34509 [details]
potential fix

potential fix, untested. Iterates over server conf to check for ! entries.
Comment 2 Eric Covener 2016-12-09 01:05:02 UTC
Are you able to test a patch?
Comment 3 Alexandre Schaff 2016-12-09 08:55:49 UTC
(In reply to Eric Covener from comment #2)
> Are you able to test a patch?

Fix applied and tested 2.4.23.
On that single test, the behavior is consistent with 2.2 : no more internal loop.

Thanks Eric.

Note : component changed from core to mod_proxy.
Comment 4 Jim Jagielski 2016-12-09 13:33:00 UTC
If this affects trunk, we should fold in there and then propose a back port to 2.4
Comment 5 Eric Covener 2016-12-31 00:27:05 UTC
Fixed in 2.4.25
Comment 6 Eric Covener 2017-01-30 12:56:14 UTC
FYI this caused a regression, it may be reverted in the next 2.4 release. After re-reviewing the PR, a better answer may have been "don't put it in <Location> if you want to have an exception before it.

Bug in the fix aside, one of the points of ProxyPass in <Location> is that it's a single proxy rule for a location.  So the server-scoped rules, even exceptions, do not "come first".
Comment 7 Michael H 2017-04-05 11:12:32 UTC
Hello, we upgraded from 2.4.18 to 2.4.25 and now our configuration isn't working anymore.

   ProxyPreserveHost On

   <Proxy balancer://ppp>
      BalancerMember http://xxx.xx.xx.xx:8080 route=vm_0 ping=5
      BalancerMember http://xxx.xx.xx.xx:8080 route=vm_1 ping=5
   </Proxy>

   <Location "/service">
     ProxyPass balancer://ppp/system stickysession=JSESSIONID|jsessionid scolonpathdelim=On
     ProxyPassReverse balancer://ppp/system
     ProxyPassReverse http://ppp.local/system
     ProxyPassReverse https://ppp.local/system
     ProxyPassReverseCookiePath /system /service
   </Location>

   ProxyPass /error !
   ProxyPass /manager !
   ProxyPass / balancer://asp/ stickysession=JSESSIONID|jsessionid scolonpathdelim=On
   ProxyPassReverse / balancer://ppp/

With 2.4.25 all requests are routet through the last ProxyPass, the Location directive is ignored so the rewrite from the context is not happening.
Can this be due to this change?

If i put the last ProxyPass in a Location directive like <Location ~ "^/(?!service)"> it's also working.

Thanks in Advance 
Michael