简体   繁体   English

如何通过从路径中提取主机将Apache配置为反向代理

[英]How to configure Apache as a reverse proxy by extracting the host from the path

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. 我想将Apache配置为反向代理,以通过解析所请求URL的路径来确定要动态代理的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 . 例如,URL http://proxy-server/app/your-app将被代理到http://your-app:8000/http://proxy-server/app/your-app/some/path将转到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. 我在以下配置中遇到的问题是http://proxy-server/app/your-app/可以正常工作,但是http://proxy-server/app/your-app/some/path可以重定向到http://proxy-server/some/path ,这会产生404错误。

I've tried using just mod_proxy like this 我试过像这样只使用mod_proxy

ProxyPassMatch "^/app/([^/]+)(?:/(.*))?$" "http://$1:8000/$2"

And I've tried it with mod_rewrite 我已经用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. 当我curl -D - http://proxy-server/app/your-app我得到HTTP/1.1 200 OK响应。 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/ . 当我curl -D - http://proxy-server/app/your-app/some/path我得到HTTP/1.1 301 Move Permanently响应, Location: /some/path/

I'm not sure where the 301 is coming from. 我不确定301的来源。 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. Apache或在该主机上运行的应用都不应该返回301,但是Location标头让我认为可能是反向代理未设置为正确地从其代理的远程重写URL。我在上面添加了ProxyPassReverse指令。 But I still can't get it working. 但是我仍然无法正常工作。

Any insight into how to set this up would be greatly appreciated. 对于如何设置此功能的任何见解将不胜感激。

By default, the mod_dir module redirects requests for a directory path that don't have a trailing slash to one that does. 默认情况下, mod_dir模块mod_dir不带斜杠的目录路径的请求重定向到具有斜杠的目录路径。 This is controlled by the DirectorySlash directive. 这由DirectorySlash指令控制。 Disabling DirectorySlash will turn off this behavior: 禁用DirectorySlash将关闭此行为:

DirectorySlash Off

It may be helpful to specify -v with curl to print verbose output. 使用curl指定-v以输出详细输出可能会有所帮助。

I did have the ProxyPassReverse directive configured incorrectly for this scenario. 对于这种情况,我确实没有正确配置ProxyPassReverse指令。

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. 我代理的远程服务器(Django应用程序)通过将Location标头设置为路径而不是完整URL来发布重定向。 So I had to configure Apache like this: 所以我必须像这样配置Apache:

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/ . 它告诉Apache如果获得Location: /some/path/标头,则应将其重写为Location: /app/your-app/some/path/ The first ProxyPassReverse directive would have triggered only if Apache had received Location: http://${CONTAINER}:8000/some/path/ . 仅当Apache收到Location: http://${CONTAINER}:8000/some/path/才会触发第一个ProxyPassReverse指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM