编码urlwihthin URL – apache mod-proxy(ProxyPass)

我有一个ProxyPassconfiguration为达到以下目的:在我的服务器上,我启动一个服务,提供restAPI监听端口7777.从客户端,我希望能够调用这个API是这样的: http://example.org/servicename/PARAMETER

对这个API的完整调用应该如下所示:HTTP PUT @ http://example.org/servicename/PARAMETER (其中PARAMETER是一些string)。 内部这应该转化为以下url: http://server.ip:7777/servicename/PARAMETER

一切都按预期工作,只要PARAMETER不是(!)像这样: http://parameter.org : http%3A%2F%2Fparameter.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> 

如果我用例如testreplacehttp%3A%2F%2Fparameter.org ,那么一切正常。 不知何故http://在参数混淆了Apache。 有没有办法让Apache忽略它?

我这个虚拟主机的当前configuration如下所示:

 <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 yield

 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" 

在默认的Apacheconfiguration中, AllowEncodedSlashes指令被设置为off 。 这意味着:“ … AllowEncodedSlashes指令允许在path信息中使用包含编码path分隔符的URL。 使用默认值Off,这样的URL被404(未find)错误拒绝 … …

所以问题在于mod_proxy并没有代理你的基于URL的POST请求,因为在mod_proxy采取行动之前,Apache正在拒绝它(使用404)。

另一个可能的问题涉及到URL编码过程:你的apache(前端)肯定会收到一个正确的URL编码的string(你发送给它的那个: 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关键字抑制了这一点,并将URLpath”raw“传递给请注意,这个关键字可能会影响后端的安全性,因为它会消除代理服务器提供的基于URL的攻击的正常有限保护 “,因此您还应该评估”nocanon“选项的用法。

这个问题( AllowEncodedSlashesnocanon )已经在这个StackOverflow问题中提到过

我认为它有这种行为,因为在http:// /仍然被视为目录分隔符。 因此,你正在寻找资源paramater.org在文件夹下的http:通过文件夹,我不是真的意味着一个真正的文件夹,因为它可能只是一个访问path,但你可以得到的重点)。

我不认为你可以在URL中input/input资源,所以你必须使用%2F