Apache httpd 後面的 Tomcat - 忽略 RewriteRule?
我使用 mod_proxy 在 apache httpd 後面有一個相當常見的 tomcat 應用程序伺服器設置。我的虛擬主機如下所示:
<VirtualHost test.example.be:80> ServerName test.example.be RewriteEngine on RewriteRule ^/test/(.*)$ /$1 ProxyRequests Off ProxyPreserveHost On <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass / http://localhost:8181/test/ ProxyPassReverse / http://localhost:8181/test/ </VirtualHost>
部署在 tomcat 中的應用程序“test”使用上下文感知的框架(spring security),因此在重定向時會預先設置上下文根。因此,當它重定向到位於根目錄中的名為 foo.html 的頁面時,它會重定向到 bleh://test.example.com/test/foo.html。這個 url 不存在並給出 404。由於我無法控制上下文根的前置,我想我可以通過刪除上下文根來使用 mod_rewrite 解決這個問題。不幸的是,這不起作用:就好像 RewriteRule 被完全忽略了。
我確實注意到一件奇怪的事情:對 bleh://test.example.com/test/foo.html 的請求甚至不會被轉發到 tomcat:我從 apache httpd 獲得了熟悉的 404 頁面。如果我輸入任何其他虛假網址,例如 bleh://test.example.com/jfaklkfdjljfkl,我會從 tomcat 獲得 404 頁面。我希望 bleh://test.example.com/test/foo.html 產生對 bleh://localhost:8181/test/test/foo.html 的呼叫,但顯然我在這裡遺漏了一些東西。
我遠不是這些問題的專家,所以任何幫助將不勝感激。
更新
我在這個問題上取得了一些進展。有人告訴我可以從 mod_rewrite 記錄調試輸出,所以我就是這樣做的。以下是這些日誌的相關部分:
[12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) init rewrite engine with requested uri /test/notify [12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (3) applying pattern '^/test/(.*)$' to uri '/test/notify' [12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) rewrite '/test/notify' -> '/notify' [12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) local path result: /notify [12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (2) prefixed with document_root to /usr/local/apache/htdocs/notify [12/Oct/2011:10:57:09 +0200] [test.example.be/sid#7b1bc8][rid#820520/initial] (1) go-ahead with /usr/local/apache/htdocs/notify [OK]
所以這裡發生的事情是 mod_rewrite 正在做它應該做的事情,但是由於某種原因,apache 沒有將 url 傳遞給 mod_proxy,而是在 /usr/local/apache/htdocs 之前添加並嘗試解決這個問題。所以新的問題是:我如何讓 apache 不預先添加 /usr/local/apache/htdocs 而只是將 url 傳遞給 tomcat?
PS:我不得不在幾個地方用“bleh”替換“http”,因為顯然你可以發布的連結數量是有限的。
只需使用
[P]
flag 將請求傳遞給 mod_proxy:RewriteRule ^/test/(.*)$ http://localhost:8181/$1 [P]
不添加 DocumentRoot 的正確方法是使用 RewriteBase 指令,或者將 PT (PassThrough) 標誌添加到重寫規則中。見這裡 - httpd.apache.org/docs/current/rewrite/flags.html#flag_pt