把 SVN 檔案庫的 Location 設在 / 下的時候要小心

用 Apache 提供以 http(s) 協定存取 SVN 檔案庫時,
我想應該很多人都看過範例會教人設定 <Location /svn/repos>、<Location /svn>、<Location /repos> 之類的路徑,
但是卻幾乎沒有教學是用 <Location />,
這其中其實是有一些原因存在的。

不單是因為範例為了簡化起見而忽略 virtual host 可能把 location 定在 / 下面的狀況,
而是這樣做可能會產生一些其它問題。

目前已知的問題是預設的 multi-language error document 設定開啟的話會產生問題。
它的內容大致上會是像這樣:

因為它會造一個 Alias 把你的 /error 指向某個目錄,
裡面有一些用來產生錯誤訊息頁面用的 .var 檔案;
但是這時你的 / 已經整個交給 mod_dav_svn 去管理了,
原本應該讀得到的檔案就變成讀不到了。

有些 SVN client 在新增或匯入檔案時會先確認檔案的存在性,
也就是在檔案庫裡讀取同名的檔案來做測試,
並藉由 server 回應 404 Not Found 來確定要新增的檔案是不存在的。
如果 Apache 因為讀不到需要的檔案來產生錯誤訊息,
這會引發 500 Internal Server Error,
並在 Apache 的 log 裡看到這行:
Could not open the requested SVN filesystem [500, #13]
而 SVN client 也會看到相同的訊息。

解決方法有很多種,
一種是乾脆就不要開 multi-language error document 的功能,
一種是每個 virtual host 分別決定要開或不開 (但是麻煩),
另一種就是在 SVN 的 virtual host 單獨 disable 它 (反正通常只會設 1 個 virtual host 放 SVN 檔案庫):

我的做法是用最後一種,
雖然設定檔會變得不是很好看,
但是反正我也不會開一大堆 virtual host 放不同的 SVN 檔案庫,
所以其實也還好。