0

I want to redirect requests for a exact specific location to proxy server but both solutions doesn't work:

<VirtualHost *:80>
  ServerName exmaple.com

<LocationMatch "^/test01$">
  ProxyPreserveHost On
  ProxyPass http://localhost:8000/
  ProxyPassReverse http://localhost:8000/
</LocationMatch>

<ProxyMatch "^/test02$">
  ProxyPreserveHost On
  ProxyPass http://localhost:8000/
  ProxyPassReverse http://localhost:8000/
</ProxyMatch>

</VirtualHost>

Test:

$ curl -I exmaple.com/test01
HTTP/1.1 404 Not Found
Date: Sun, 17 Jun 2018 15:37:10 GMT
Server: Apache
Content-Type: text/html; charset=iso-8859-1

$ curl -I exmaple.com/test02
HTTP/1.1 404 Not Found
Date: Sun, 17 Jun 2018 15:37:13 GMT
Server: Apache
Content-Type: text/html; charset=iso-8859-1

When I remove the RegEx part then it works but I want Apache to display the 404, not the Django development server:

<LocationMatch "/test01">
  ProxyPreserveHost On
  ProxyPass http://localhost:8000/
  ProxyPassReverse http://localhost:8000/
</LocationMatch>

$ curl -I exmaple.com/test01
HTTP/1.1 200 OK
Date: Sun, 17 Jun 2018 15:42:26 GMT
Server: WSGIServer/0.2 CPython/3.6.5
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 12767

$ curl -I exmaple.com/test01/none
HTTP/1.1 404 Not Found
Date: Sun, 17 Jun 2018 15:42:33 GMT
Server: WSGIServer/0.2 CPython/3.6.5
Content-Type: text/html; charset=UTF-8
X-Frame-Options: SAMEORIGIN
Content-Length: 2073

Update: Mon 18 Jun 14:40:59 UTC 2018

So I've done some further research and according to Apache docs:

When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same will occur inside a <LocationMatch> section; however, ProxyPass does not interpret the regexp as such, so it is necessary to use ProxyPassMatch in this situation instead.

So I tried ProxyPassMatch and it works however the RegEx matched is passed to Proxy http://localhost:8000/test01 and this is not what I want.

I can achieve this easily with Nginx:

server {
    listen 80;
    server_name exmaple.com;

    location = /test01/ {
        proxy_pass http://localhost:8000/;
        proxy_set_header Host $host;
    }
}

How I can do something similar with Apache?

Update: Sun 24 Jun 10:46:12 UTC 2018

<LocationMatch "^/test01$">
  Redirect / http://test.com/
</LocationMatch>

$ curl -I exmaple.com/test01
HTTP/1.1 302 Found
Date: Sun, 24 Jun 2018 10:47:04 GMT
Server: Apache
Location: http://test.com/test01
Content-Type: text/html; charset=iso-8859-1
  • I think you need to balance your slashes as explained in the ProxyPass manual: If the first argument ends with a trailing /, the second argument should also end with a trailing /, and vice versa. Otherwise, the resulting requests to the backend may miss some needed slashes and do not deliver the expected results. – HBruijn Jun 21 '18 at 8:17
  • ProxyPass|ProxyPassMatch can not have a path (first argument) when defined in a location. – HTF Jun 21 '18 at 15:06
  • Can you post the config for ProxyPassMatch. Are you adding $1 at the end back-end URL in ProxyPassMatch? – Tejas Sarade Jun 23 '18 at 1:01
  • No, I don't. The query matched is appended automatically, please see my latest update: Update: Sun 24 Jun 10:46:12 UTC 2018 – HTF Jun 24 '18 at 10:52
1
+50

The usual way with Apache of solving the problem of:

  • sending all sub-paths under a root to an upstream
  • hiding upstream-issued 4xx and 5xx errors with static pages

is to use a plain Location block with ProxyPass and ProxyPassReverse, along with ProxyErrorOverride and ErrorDocument. Untested example:

<VirtualHost *:80>
  ServerName exmaple.com
  ProxyErrorOverride On
  ProxyPreserveHost On
  ErrorDocument 404 "That resource was not found"

  <Location /test01>
    ProxyPass http://localhost:8000/
    ProxyPassReverse http://localhost:8000/
  </Location>

</VirtualHost>

See:

| improve this answer | |
  • Thanks, almost ideally, Nginx also process successful requests (2xx, 3xx etc.) with Apache I can see server headers from a proxy server. – HTF Jun 26 '18 at 11:28
  • Want to say more- are you trying to hide upstream headers? Feel free to edit the question. Nginx has several areas where it is more flexible, but Apache should be able to satisfy common cases. – Jonah Benton Jun 26 '18 at 11:45
  • I guess hiding server header can be done only with some rewrite rules? – HTF Jun 26 '18 at 12:22
  • 1
    Rewrite is more for URL transformation, rather than header transformation, but should be able to modify Server header in various ways with other directives. See the top voted non-accepted answer in: unix.stackexchange.com/questions/124137/…. Try adding directives "Header unset Server" "ServerSignature Off" "ServerTokens Prod". You might need to enable additional modules. – Jonah Benton Jun 26 '18 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.