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.
2
Answers
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:That last line is the key. It tells Apache that if it gets a
Location: /some/path/
header, it should rewrite it asLocation: /app/your-app/some/path/
. The firstProxyPassReverse
directive would have triggered only if Apache had receivedLocation: http://${CONTAINER}:8000/some/path/
.By default, the
mod_dir
module redirects requests for a directory path that don’t have a trailing slash to one that does. This is controlled by theDirectorySlash
directive. DisablingDirectorySlash
will turn off this behavior:It may be helpful to specify
-v
withcurl
to print verbose output.