在 mod_proxy 重定向上保留原始请求 URL
我正在 Servlet 容器(端口 8080)上运行 Web 应用程序,环境可以从互联网(外部)和公司内部(内部)访问,例如
http://external.foo.bar/MyApplication
http://internal.foo.bar/MyApplication
传入的(外部/内部)请求使用重定向到 servlet 容器带有 mod_proxy 的 apache http 服务器。配置如下所示:
ProxyPass /MyApplication http://localhost:8080/MyApplication retry=1 acquire=3000 timeout=600 Keepalive=On
ProxyPassReverse /MyApplication http://localhost:8080/MyApplication
我现在面临一些 MyApplication 响应依赖于原始请求 URL 的问题。具体:WSDL 文档将提供一个具有 schemaLocation="
元素的元素。
根据我当前的配置,它看起来总是这样
<xs:import namespace="..." schemaLocation="http://localhost:8080/MyApplication?xsd=MyApplication.xsd"/>
,但应该是
External Request: <xs:import namespace="..." schemaLocation="http://external.foo.bar/MyApplication?xsd=MyApplication.xsd"/>
Internal Request: <xs:import namespace="..." schemaLocation="http://internal.foo.bar/MyApplication?xsd=MyApplication.xsd"/>
我认为这是一个常见的要求。但由于我不是 apache http 服务器及其模块配置方面的专家,如果有人可以提供一些(详细的)帮助,我会很高兴。
提前致谢!
I am running a WebApplication on a Servlet Container (port 8080) in an environment that can be accessed from the internet (external) and from company inside (intenal), e.g.
http://external.foo.bar/MyApplication
http://internal.foo.bar/MyApplication
The incomming (external/internal) requests are redirected to the servlet container using an apache http server with mod_proxy. The configuration looks like this:
ProxyPass /MyApplication http://localhost:8080/MyApplication retry=1 acquire=3000 timeout=600 Keepalive=On
ProxyPassReverse /MyApplication http://localhost:8080/MyApplication
I am now facing the problem that some MyApplication responses depend on the original request URL. Concrete: a WSDL document will be provided with a element that has a schemaLocation="<RequestUrl>?xsd=MyApplication.xsd"
element.
With my current configuration it always looks like
<xs:import namespace="..." schemaLocation="http://localhost:8080/MyApplication?xsd=MyApplication.xsd"/>
but it should be
External Request: <xs:import namespace="..." schemaLocation="http://external.foo.bar/MyApplication?xsd=MyApplication.xsd"/>
Internal Request: <xs:import namespace="..." schemaLocation="http://internal.foo.bar/MyApplication?xsd=MyApplication.xsd"/>
I suppose this is a common requirement. But as I am no expert in configuration of the apache http server and its modules I would be glad if someone could give some (detailed) help.
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您运行的 Apache >= 2.0.31 那么您可以尝试按照 此处。
这应该将原始 Host 标头通过 mod_proxy 传递到您的应用程序中,通常请求 URL 将使用 Host 标头在那里(在您的 Servlet 容器中)重建,因此架构位置应该使用“之前”的主机和路径信息来构建代理。
(为了完整起见,也发布在这里)
If you're running Apache >= 2.0.31 then you might try to set the
ProxyPreserveHost
directive as described here.This should pass the original Host header trough mod_proxy into your application, and normally the request URL will be rebuild there (in your Servlet container) using the Host header, so the schema location should be build using the host and path infos from "before" the proxy.
(Posted here too for the sake of completeness)
如果您想同时保留原始主机名和代理主机名,还有另一种选择。
如果您使用 mod_proxy,请在 Apache 配置中禁用 ProxyPreserveHost。对于大多数代理服务器(包括 mod_proxy),请阅读应用程序中的
X-Forwarded-Host
标头。这标识了 HTTP 请求提供的原始主机标头。您可以在此处阅读有关 mod_proxy 标头(以及可能的其他标准代理服务器)设置的信息:
http ://httpd.apache.org/docs/2.2/mod/mod_proxy.html
Here is another alternative if you would like to retain both the original host name and the proxied host name.
If you are using mod_proxy disable
ProxyPreserveHost
in the Apache configuration. For most proxy servers, including mod_proxy, read theX-Forwarded-Host
header in your application. This identifies the original Host header provided by the HTTP request.You can read about the headers mod_proxy (and possible other standard proxy servers) set here:
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
您应该能够在 apache 中执行 mod_rewrite 将完整 URL 编码为查询参数,或者可能是片段的一部分。这有多容易取决于您是否可以使用其中之一作为传入查询的一部分。
例如,
http://external.foo.bar/MyApplication
可能会被重写为http://external.foo.bar/MyApplication#rewritemagic=http://external.foo。 bar/MyApplication
然后被传递到 ProxyPass 中,然后被删除。是的,有点黑客,也许有点棘手,让重写和代理以正确的顺序工作并且不互相干扰,但看起来它应该可以工作。
You should be able to do a mod_rewrite in apache to encode the full URL as a query parameter, or perhaps part of the fragment. How easy this might be depends on whether you might use one or the other as part of your incoming queries.
For example,
http://external.foo.bar/MyApplication
might get rewritten tohttp://external.foo.bar/MyApplication#rewritemagic=http://external.foo.bar/MyApplication
which then gets passed into the ProxyPass and then stripped out.A bit of a hack, yes, and perhaps a little tricky to get rewrite and proxy to work in the right order and not interfere with each other, but it seems like it should work.