Apache將URL對映到檔案系統位置


本文將介紹Apache HTTP Server如何使用請求的URL來確定從中提供檔案的檔案系統位置。

DocumentRoot

在決定為給定請求提供什麼檔案時,httpd的預設行為是獲取請求的URL-Path(主機名和埠後面的URL部分),並將其新增到組態檔案中指定的DocumentRoot的末尾。因此,DocumentRoot下面的檔案和目錄構成了可從Web上看到的基本文件樹。

例如,如果DocumentRoot設定為/var/www/html時,則對http://www.example.com/fish/guppies.html的請求會將檔案/var/www/html/fish/guppies.html傳送到請求客戶。

如果請求目錄(即以/結尾的路徑),則從該目錄提供的檔案由DirectoryIndex指令定義。例如,如果DocumentRoot設定為/var/www/html/,則要設定:

DirectoryIndex index.html index.php

然後,對http://www.example.com/fish/的請求將導致httpd嘗試提供檔案/var/www/html/fish/index.html。如果該檔案不存在,它將接下來嘗試提供檔案/var/www/html/fish/index.php

如果這兩個檔案都不存在,則下一步是嘗試提供目錄索引,載入mod_autoindex並組態為允許該目錄索引。

httpd還具有虛擬主機功能,伺服器可以接收多個主機的請求。在這種情況下,可以為每個虛擬主機指定不同的DocumentRoot,或者,模組mod_vhost_alias提供的指令可用於根據請求的IP地址或主機名動態確定從中提供內容的適當位置。

DocumentRoot之外的檔案

通常情況下,必須允許Web存取檔案系統中嚴格不在DocumentRoot下的部分。httpd提供了幾種不同的方法來實現這一目標。在Unix系統上,符號連結可以將檔案系統的其他部分帶到DocumentRoot下。出於安全原因,僅當相關目錄的Options設定包括FollowSymLinksSymLinksIfOwnerMatch時,httpd才會遵循符號連結。

或者,Alias指令將檔案系統的任何部分對映到Web空間。例如,

Alias "/docs" "/var/web"

網址 http://www.example.com/docs/dir/file.html 將從/var/web/dir/file.html提供。ScriptAlias指令的工作方式相同,其附加效果是位於目標路徑的所有內容都被視為CGI指令碼。

對於需要額外靈活性的情況,可以使用AliasMatchScriptAliasMatch指令來執行基於正規表示式的強大匹配和替換。例如,

ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)"   "/home/$1/cgi-bin/$2"

將請求對映到http://example.com/~user/cgi-bin/script.cgi到路徑/home/user/cgi-bin/script.cgi,並將生成的檔案視為CGI指令碼。

使用者目錄

傳統上在Unix系統上,特定使用者的主目錄可以稱為~user/。模組mod_userdir通過允許使用以下URL存取每個使用者主目錄下的檔案,將此想法擴充套件到Web。

http://www.example.com/~user/file.html

出於安全原因,從Web直接存取使用者的主目錄是不合適的。因此,UserDir指令指定使用者主目錄下Web目錄所在的目錄。使用Userdir public_html的預設設定,上面的URL對映到/home/user/public_html/file.html等目錄中的檔案,其中/home/user//etc/passwd中指定的使用者主目錄。

有些人發現~符號(通常在網路上編碼為%7e)很尷尬,並且更喜歡使用替代字串來表示使用者目錄。mod_userdir不支援此功能。但是,如果使用者的主目錄以常規方式構造,則可以使用AliasMatch指令來實現所需的效果。例如,要將http://www.example.com/upages/user/file.html對映到/home/user/public_html/file.html,請使用以下AliasMatch指令:

AliasMatch "^/upages/([a-zA-Z0-9]+)(/(.*))?$"   "/home/$1/public_html/$3"

URL重定向

上面討論的組態指令告訴httpd從檔案系統中的特定位置獲取內容並將其返回給用戶端。有時,希望通知用戶端所請求的內容位於不同的URL,並指示用戶端使用新URL發出新請求。這稱為重定向,由Redirect指令實現。例如,如果DocumentRoot下目錄/foo/的內容被移動到新目錄/bar/,可以指示用戶端在新位置請求內容,如下所示:

Redirect permanent "/foo/"   "http://www.example.com/bar/"

這會將從/foo/開始的任何URL-Path重定向到www.example.com伺服器上的相同URL路徑,其中/bar/替換為/foo/。可以將用戶端重定向到任何伺服器,而不僅僅是原始伺服器。

httpd還提供了RedirectMatch指令,用於更複雜的重寫問題。例如,要將站點主頁的請求重定向到其他站點,但僅保留所有其他請求,請使用以下組態:

RedirectMatch permanent "^/$"    "http://www.example.com/startpage.html"

或者,要臨時將一個站點上的所有頁面重定向到另一個站點上的特定頁面,請使用以下命令:

RedirectMatch temp ".*"  "http://othersite.example.com/startpage.html"

反向代理

httpd還允許將遠端文件帶入本地伺服器的URL空間。此技術稱為反向代理,因為Web伺服器通過從遠端伺服器獲取文件並將其返回到用戶端來充當代理伺服器。它與正常(轉發)代理不同,因為對於用戶端,文件似乎來自反向代理伺服器。

在以下範例中,當用戶端請求/foo/目錄下的頁面文件時,伺服器從internal.example.com上的/bar/目錄中獲取這些文件,並將它們返回給用戶端,就像它們來自本地伺服器一樣。

ProxyPass "/foo/" "http://internal.example.com/bar/"
ProxyPassReverse "/foo/" "http://internal.example.com/bar/"
ProxyPassReverseCookieDomain internal.example.com public.example.com
ProxyPassReverseCookiePath "/foo/" "/bar/"

ProxyPass組態伺服器以獲取相應的文件,而ProxyPassReverse指令重寫源自internal.example.com的重定向,以便它們定位到本地伺服器上的相應目錄。同樣,ProxyPassReverseCookieDomainProxyPassReverseCookiePath重寫由後端伺服器設定的cookie。

但是,請務必注意,文件中的連結不會被重寫。因此,internal.example.com上的任何絕對連結都將導致用戶端突破代理伺服器並直接從internal.example.com請求。您可以使用mod_substitute在頁面中修改這些連結(以及其他內容)。

Substitute "s/internal\.example\.com/www.example.com/i"

對於HTML和XHTML中連結的更複雜重寫,mod_proxy_html模組也可用。它允許建立需要重寫的URL對映,以便可以處理複雜的代理方案。

重寫引擎

當需要更強大的替換時,mod_rewrite提供的重寫引擎可能很有用。該模組提供的指令可以使用請求的特徵(例如瀏覽器型別或源IP地址)來決定從哪裡提供內容。此外,mod_rewrite可以使用外部資料庫檔案或程式來確定如何處理請求。重寫引擎能夠執行上面討論的所有三種型別的對映:內部重定向(別名),外部重定向和代理。

檔案未找到

不可避免地請求有時也會在檔案系統中找不到匹配檔案的URL。這可能由於幾個原因而發生。在某些情況下,它可能是將文件從一個位置移動到另一個位置的結果。在這種情況下,最好使用URL重定向來通知用戶端資源的新位置。通過這種方式,即使資源位於新位置,您也可以確保舊書籤和連結繼續有效。

「找不到檔案」錯誤的另一個常見原因是URL的直接錯誤輸入,無論是直接在瀏覽器中還是在HTML連結中。httpd提供模組mod_speling(sic)來幫助解決這個問題。啟用此模組時,它將攔截「找不到檔案」錯誤並查詢具有類似檔案名的資源。如果找到一個這樣的檔案,mod_speling將向用戶端傳送HTTP重定向,通知它正確的位置。如果找到幾個「關閉」檔案,將向客戶提供可用備選列表。

mod_speling的一個特別有用的功能是,它將比較檔案名而不考慮大小寫。這可以幫助使用者不了解URL和unix檔案系統的區分大小寫特性的系統。但是,除了偶爾的URL更正之外,使用mod_speling可以在伺服器上增加額外負載,因為每個「不正確」的請求後面都有URL重定向和來自用戶端的新請求。

mod_dir提供FallbackResource,可用於將虛擬URI對映到真實資源,然後為其提供服務。在實現’前端控制器’時,這是對mod_rewrite非常有用的替代品

如果查詢內容的所有嘗試都失敗,httpd將返回一個錯誤頁面,其中包含HTTP狀態程式碼404(找不到檔案)。此頁面的外觀由ErrorDocument指令控制,可以按照自定義錯誤響應文件中的討論以靈活的方式進行自定義。