在 URL 内对 URL 进行编码 - apache mod-proxy (ProxyPass)

在 URL 内对 URL 进行编码 - apache mod-proxy (ProxyPass)

我有一个 ProxyPass 配置来实现以下功能:在我的服务器上,我启动了一个服务,该服务提供一个在端口 7777 上监听的 Rest-API。从客户端,我希望能够像这样调用此 API:http://example.org/servicename/PARAMETER

此 API 的完整调用应如下所示:HTTP PUT @ http://example.org/servicename/PARAMETER(其中PARAMETER是某个字符串)。在内部,这应转换为以下 URL:http://server.ip:7777/servicename/PARAMETER

只要参数不是这样的(!),一切都会按预期工作:(http://parameter.org实际上我需要对其进行 URL 编码:)http%3A%2F%2Fparameter.org。总而言之,调用是http://example.org/servicename/http%3A%2F%2Fparameter.org

参数中的http://使 apache 感到困惑,导致在调用的回复中出现以下错误消息:

!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /servicename/http://parameter.org was not found on this server.</p>
<hr>
<address>Apache/2.2.22 (Debian) Server at example.org Port 80</address>
</body></html>

http%3A%2F%2Fparameter.org例如,如果我用 替换,test则一切正常。不知何故,http://参数中的 会让 apache 感到困惑。有没有办法让 apache 忽略它?

我当前对此虚拟主机的配置如下:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/example
        ServerName example.org
        ErrorLog /var/log/apache2/example_error.log
        LogLevel warn
        CustomLog /var/log/apache2/example_access.log combined

    <IfModule mod_proxy.c>
        ProxyRequests Off

        ProxyPass / http://localhost:7777/
        ProxyPassReverse / http://localhost:7777/
    </IfModule>
</VirtualHost>

先决条件:

  • 我无法改变 API 的行为。它是第三方的。
  • 我需要能够提供 URL 作为参数。

编辑1:

tail -f /var/log/apache2/example_access.log产量

128.xxx.xxx.xxx - - [19/Aug/2015:16:53:17 +0200] "PUT /servicename/http%3A%2F%2Fparameter.org HTTP/1.1" 404 521 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36"

答案1

在默认的 Apache 配置中,允许编码斜杠指令设置为离开。 这意味着: ”...AllowEncodedSlashes 指令允许在路径信息中使用包含编码路径分隔符 [...] 的 URL。使用默认值 Off,此类 URL 将被拒绝并出现 404(未找到)错误。 ...

所以问题是 mod_proxy不是代理基于 URL 的 POST 请求,因为在 mod_proxy 采取行动之前,Apache 拒绝了这些请求(出现 404)。

另一个可能的问题与 URL 编码过程有关:你的 apache(前端)肯定会收到一个正确的 URL 编码字符串(你发送给它的字符串:http://example.org/servicename/http%3A%2F%2Fparameter.org),我期望它 (apache) 将在内部处理相关 POST 请求时对其进行 URL 解码。因此,我期望 Apache 内部的 mod_proxy 将收到一个真实的 URL(未编码),我想知道在代理时它是否会执行 URL 编码循环。ProxyPass 官方文档我懂了: ”通常,mod_proxy 会规范化 ProxyPassed URL。但这可能与某些后端不兼容,尤其是那些使用 PATH_INFO 的后端。可选的 nocanon 关键字会抑制这种情况并将 URL 路径“原始”传递给后端。请注意,此关键字可能会影响后端的安全性,因为它会删除代理提供的针对基于 URL 的攻击的正常有限保护“,因此您还应该评估“nocanon”选项的使用情况。

这两个问题(允许编码斜杠诺卡农)已被提及这个 StackOverflow 问题

答案2

我认为它有这种行为是因为在 中http://仍然/被视为目录分隔符。因此,您正在寻找paramater.org文件夹下的资源http:(文件夹,我并不是指真正的文件夹,因为它可能只是一条访问路径,但您可以明白我的意思)。

我认为你不能/在 URL 中直接输入资源,所以你必须使用 %2F

相关内容