mod_rewrite 突然不起作用,僅適用於來自 Foursquare API 的傳入 POST 請求
我的網站上有一個端點,我可以在其中接收來自 FourSquare API 的推送通知。終點是:
https://www.example.com/auth/foursquare/
在伺服器本身上,源文件是:
/home/myusername/public_html/www.example.com/auth/foursquare/index.php
通常,該站點的文件位於:
/home/myusername/public_html/
但我使用 mod_rewrite 將它們放在通常的 webroot 的子目錄中:
/home/myusername/public_html/www.example.com/
這些是 mod_rewrite 規則:
RewriteCond %{HTTP_HOST} ^(www.)?example.com$ [NC] RewriteRule ^(.*)$ /www.example.com/$1 [L]
到現在為止還挺好。一切都是這樣工作的,並且多年來一直沒有問題。直到幾個月前,FourSquare 的推送突然停止了。對伺服器錯誤日誌的調查表明,由於某種原因,它現在正試圖從原始(非重寫)路徑提供文件:
2019-12-30 00:26:31.383141 [INFO] [34.231.230.177:15669] File not found [/home/myusername/public_html/auth/foursquare/] 2019-12-30 00:26:31.383256 [INFO] [34.231.230.177:15669] File not found [/home/myusername/public_html/404.shtml]
真正奇怪的是,這只發生在傳入請求來自foursquare API本身時:
- 我可以在瀏覽器中訪問 https://www.example.com/auth/foursquare/,它提供了正確的文件。
- 我可以使用 Postman 或 Insomnia 或任何其他 API 測試工具發佈到https://www.example.com/auth/foursquare/,它會提供正確的文件。即使我精確地複制了 FourSquare 的標頭和 POST 數據(我通過更改 FourSquare 應用程序以推送到 hookbin 端點來確定,這樣我就可以檢查它們發送的確切數據)。
我能想到的唯一共同點就是源IP;當 POST 來自 FourSquare 的 IP 時,mod_rewrite 不提供來自子目錄的預期文件 - 但來自所有其他 IP。雖然顯然我沒有任何特定於 IP 的規則會導致這種情況,所以這沒有任何意義。
因為在很長一段時間內我沒有更改任何程式碼或 htaccess 規則(即早在這自發開始發生之前),因此我的(共享)虛擬主機必須更改了一些破壞它的伺服器配置。但我已經與他們交換了 20 多條消息,他們只是不斷地回复“我們不知道為什麼會發生這種情況,只需從原始路徑創建一個符號連結就可以了。” 確實,從 /home/myusername/public_html/auth/ 到 /home/myusername/public_html/www.example.com/auth/ 的符號連結有效。然而,這並不能解釋為什麼它會突然壞掉,而且 IMO 的盲目創可貼解決方案很少是一個好主意。如果這件事發生的任何事情也影響了其他事情,我還沒有幸運地註意到呢?一世’正確修復它。可悲的是,很明顯,網路主機 - 這似乎是最有可能的罪魁禍首 - 將無濟於事。
如果有人有任何想法,我將不勝感激。
Reqhost 設置為:“www.example.com:443”
這似乎肯定是問題的原因。儘管為什麼埠(正在發送請求)現在出現在
Host
標頭中是另一回事。443
是 HTTPS 的預設埠。但是,由於它是預設埠,因此它不需要出現在Host
標頭中。如果您從非標準埠提供內容,則只需要指定的埠。FourSquare 可能已經開始偷偷包含埠號作為請求的一部分(假設這沒有被錯誤地設置在 FourSquare 的配置中?) - 儘管這可能是不正確的(儘管嚴格來說不違反規範)因為它將限制您的伺服器使用預設埠(您應該能夠使用您想要的任何埠)。
另一種可能性是您有一個(新的)前端代理,它可能會將埠號附加到轉發到您的應用程序伺服器的請求中。但這不太可能,因為它可能會影響所有請求,並且從您的測試中,情況並非如此。
“修復”似乎是允許請求中的埠號(假設只有埠 443 而不是埠 80 - 純 HTTP)。
例如:
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com(:443)?$ [NC] RewriteRule (.*) /www.example.com/$1 [L]
(:443)?
使埠號在標頭中可選Host
(如果情況相反)。不要忘記在正則表達式(CondPattern)中轉義文字點。
^(.*)$
可以簡化為,(.*)
因為正則表達式預設是貪婪的。