用 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
是一些字元串)。在內部,這應該轉換為以下網址: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 會混淆 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://
in 參數混淆了 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"
在預設的 Apache 配置中,AllowEncodedSlashes指令設置為off。這意味著:“ … AllowEncodedSlashes 指令允許包含編碼路徑分隔符的 URL$$ … $$在路徑資訊中使用。使用預設值 Off 時,此類 URL 將被拒絕並顯示 404 (Not found) 錯誤。…… ”
所以問題是 mod_proxy沒有代理基於 URL 的 POST 請求,因為 Apache 在 mod_proxy 採取行動之前拒絕了它們(使用 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 問題中提到了這兩個問題(AllowEncodedSlashes和nocanon )