用 Apache 提供以 http(s) 協定存取 SVN 檔案庫時,
我想應該很多人都看過範例會教人設定 <Location /svn/repos>、<Location /svn>、<Location /repos> 之類的路徑,
但是卻幾乎沒有教學是用 <Location />,
這其中其實是有一些原因存在的。
不單是因為範例為了簡化起見而忽略 virtual host 可能把 location 定在 / 下面的狀況,
而是這樣做可能會產生一些其它問題。
目前已知的問題是預設的 multi-language error document 設定開啟的話會產生問題。
它的內容大致上會是像這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
Alias /error/ "/usr/local/www/apache22/error/" <Directory "/usr/local/www/apache22/error"> AllowOverride None Options IncludesNoExec AddOutputFilter Includes html AddHandler type-map var Order allow,deny Allow from all LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr ForceLanguagePriority Prefer Fallback </Directory> ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var ErrorDocument 410 /error/HTTP_GONE.html.var ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var |
因為它會造一個 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 檔案庫):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<VirtualHost *:80> ... <Location /> ... ErrorDocument 400 default ErrorDocument 401 default ErrorDocument 403 default ErrorDocument 404 default ErrorDocument 405 default ErrorDocument 408 default ErrorDocument 410 default ErrorDocument 411 default ErrorDocument 412 default ErrorDocument 413 default ErrorDocument 414 default ErrorDocument 415 default ErrorDocument 500 default ErrorDocument 501 default ErrorDocument 502 default ErrorDocument 503 default ErrorDocument 506 default </Location> </VirtualHost> |
我的做法是用最後一種,
雖然設定檔會變得不是很好看,
但是反正我也不會開一大堆 virtual host 放不同的 SVN 檔案庫,
所以其實也還好。