Issue
I'd like to configure Apache as a reverse proxy for that determines the URL to proxy to dynamically by parsing the path of the requested URL.
For example, the URL http://proxy-server/app/your-app would get proxied to http://your-app:8000/ and http://proxy-server/app/your-app/some/path would go to http://your-app:8000/some/path.
The problem I'm running into with the below configuration is that http://proxy-server/app/your-app/ works just fine, but http://proxy-server/app/your-app/some/path gets redirected to http://proxy-server/some/path, which gives a 404 error.
I've tried using just mod_proxy like this
ProxyPassMatch "^/app/([^/]+)(?:/(.*))?$" "http://$1:8000/$2"
And I've tried it with mod_rewrite
RewriteEngine On
RewriteBase "/app/"
RewriteRule "^([^/]+)/?$" "http://$1:8000/" [E=CONTAINER:$1,P]
RewriteRule "^([^/]+)/(.+)$" "http://$1:8000/$2" [E=CONTAINER:$1,P]
ProxyPassInterpolateEnv On
ProxyPassReverse "/app/" "http://${CONTAINER}:8000/" interpolate
When I curl -D - http://proxy-server/app/your-app I get an HTTP/1.1 200 OK response. When I curl -D - http://proxy-server/app/your-app/some/path I get a HTTP/1.1 301 Move Permanently response with Location: /some/path/.
I'm not sure where the 301 is coming from. Neither Apache nor the app running on that host should be returning a 301, but the Location header made me think it might be that the reverse proxy isn't set up to correctly rewrite URLs from the remote to which it is proxying, which is why I added the ProxyPassReverse directive above. But I still can't get it working.
Any insight into how to set this up would be greatly appreciated.
Solution
I did have the ProxyPassReverse directive configured incorrectly for this scenario.
The remote server to which I was proxying (a Django app) was issuing redirects by setting the Location header to a path, not a full URL. So I had to configure Apache like this:
RewriteEngine On
RewriteRule "^/app/([^/]+)(?:/.*)?$" - [E=CONTAINER:$1]
ProxyPassInterpolateEnv On
ProxyPass "/app/${CONTAINER}/" "http://${CONTAINER}:8000/" interpolate
ProxyPassReverse "/app/${CONTAINER}/" "http://${CONTAINER}:8000/" interpolate
# This guarantees that any Location headers that are just absolute paths
# get rewritten
ProxyPassReverse "/app/${CONTAINER}/" "/" interpolate
That last line is the key. It tells Apache that if it gets a Location: /some/path/ header, it should rewrite it as Location: /app/your-app/some/path/. The first ProxyPassReverse directive would have triggered only if Apache had received Location: http://${CONTAINER}:8000/some/path/.
Answered By - darth_mall Answer Checked By - Willingham (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.