【问题标题】:Retain original request URL on mod_proxy redirect在 mod_proxy 重定向上保留原始请求 URL
【发布时间】:2011-08-29 13:05:16
【问题描述】:

我在一个可以从互联网(外部)和公司内部(内部)访问的环境中的 Servlet 容器(端口 8080)上运行 WebApplication,例如

http://external.foo.bar/MyApplication
http://internal.foo.bar/MyApplication

传入的(外部/内部)请求使用带有 mod_proxy 的 apache http 服务器重定向到 servlet 容器。配置如下:

ProxyPass /MyApplication http://localhost:8080/MyApplication retry=1 acquire=3000 timeout=600 Keepalive=On
ProxyPassReverse /MyApplication http://localhost:8080/MyApplication

我现在面临一些 MyApplication 响应依赖于原始请求 URL 的问题。具体:一个 WSDL 文档将提供一个具有 schemaLocation="<RequestUrl>?xsd=MyApplication.xsd" 元素的元素。

以我当前的配置,它总是看起来像

<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 服务器及其模块配置方面的专家,如果有人可以提供一些(详细的)帮助,我会很高兴。

提前致谢!

【问题讨论】:

    标签: apache web-applications mod-rewrite redirect mod-proxy


    【解决方案1】:

    如果您运行的是 Apache >= 2.0.31,那么您可能会尝试按照 here 的描述设置 ProxyPreserveHost 指令。

    这应该通过 mod_proxy 将原始 Host 标头传递到您的应用程序中,并且通常请求 URL 将使用 Host 标头在那里重建(在您的 Servlet 容器中),因此应该使用来自的主机和路径信息来构建架构位置“在”代理之前。

    (为了完整起见,也在这里发布)

    【讨论】:

      【解决方案2】:

      如果您想同时保留原始主机名和代理主机名,这是另一种选择。

      如果您在 Apache 配置中使用 mod_proxy,请禁用 ProxyPreserveHost。对于大多数代理服务器,包括 mod_proxy,请阅读应用程序中的 X-Forwarded-Host 标头。这标识了 HTTP 请求提供的原始 Host 标头。

      您可以在此处阅读有关 mod_proxy(以及可能的其他标准代理服务器)设置的标头:

      http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

      【讨论】:

      • ProxyPreserveHost 非常适合我,无需更改我的应用程序(阅读 X-Forwarded-Host)。但仍然感谢这个可能的其他解决方案。
      • 是的。它也对我有用。但是,我遇到了一个需要原始主机名和代理传递的主机名的情况。因此,只需在此处添加此内容以供将来参考。
      【解决方案3】:

      您应该能够在 apache 中执行 mod_rewrite 以将完整的 URL 编码为查询参数,或者可能是片段的一部分。这可能有多容易取决于您是否可以使用其中一个作为传入查询的一部分。

      例如,http://external.foo.bar/MyApplication 可能会被重写为 http://external.foo.bar/MyApplication#rewritemagic=http://external.foo.bar/MyApplication,然后将其传递到 ProxyPass 中,然后被剥离。

      是的,有点小技巧,也许有点棘手,要让重写和代理以正确的顺序工作并且不相互干扰,但它似乎应该可以工作。

      【讨论】:

      • 感谢您解决我的问题并为可能的解决方法 +1。但是 MyApplication 是建立在Apache CXF 框架之上的,我怀疑查询参数是否会有所帮助。我想我必须使用原始请求访问它,我想知道这在我的场景中是否/如何实现。
      • @K. Claszen:我建议转储所有 apache 提供给您的环境、变量、标头和其他信息,以查看是否可能注入了某些东西。另外,请考虑您是否可以使用 ProxyPreserveHost 或 ProxyVia(Via 是可能设置并对您有用的标头之一的示例)。
      • 我将首先尝试我在serverfault 上获得的 ProxyPreserverHost 设置。如果这能解决我的问题,那将非常简单......不过,感谢您的支持!
      猜你喜欢
      • 2011-09-03
      • 2017-06-01
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 2020-08-25
      • 2012-04-15
      • 2022-10-13
      • 2013-09-05
      相关资源
      最近更新 更多