Apache HTTP Server 版本 2.4
此文件補充 mod_rewrite
參考文件。內容說明如何使用 mod_rewrite
建立動態設定的虛擬主機。
我們希望自動為在我們的網域中解析的每個主機名建立虛擬主機,而無需建立新的 VirtualHost 區段。
在此食譜中,我們假設我們會為每個使用者使用主機名 www.SITE.example.com
,並從 /home/SITE/www
提供其內容。
RewriteEngine on RewriteMap lowercase int:tolower RewriteCond "${lowercase:%{HTTP_HOST}}" "^www\.([^.]+)\.example\.com$" RewriteRule "^(.*)" "/home/%1/www$1"
內部的 tolower
RewriteMap 指令是用於確保所使用的主機名皆為小寫,這樣一來,在必須建立的目錄結構中便沒有歧義。
在 RewriteCond
中使用的括號擷取到反向引用 %1
、%2
等,而 RewriteRule
中使用的括號則擷取到反向引用 $1
、$2
等。
如同此文件討論的眾多技術,mod_rewrite 實際上並非達成此任務的最佳方式。您應該考慮改用 mod_vhost_alias
,因為它會更完善地處理超出提供靜態檔案的任何內容,例如動態內容和別名解析。
mod_rewrite
的動態虛擬主機httpd.conf
中的這個節錄執行了與 第一個範例 相同的功能。上半部與上方的對應部分非常類似,只有為了向後相容和讓 mod_rewrite
部分正確執行而做出的變更;下半部則配置 mod_rewrite
實際執行工作。
由於 mod_rewrite
會在其他 URI 轉譯模組(例如 mod_alias
)之前執行,因此必須告知 mod_rewrite
明確忽略由這些模組處理的任何 URL。而且由於這些規則否則會略過任何 ScriptAlias
指令,我們必須讓 mod_rewrite
明確制定那些映射。
# get the server name from the Host: header UseCanonicalName Off # splittable logs LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon CustomLog "logs/access_log" vcommon <Directory "/www/hosts"> # ExecCGI is needed here because we can't force # CGI execution in the way that ScriptAlias does Options FollowSymLinks ExecCGI </Directory> RewriteEngine On # a ServerName derived from a Host: header may be any case at all RewriteMap lowercase int:tolower ## deal with normal documents first: # allow Alias "/icons/" to work - repeat for other aliases RewriteCond "%{REQUEST_URI}" "!^/icons/" # allow CGIs to work RewriteCond "%{REQUEST_URI}" "!^/cgi-bin/" # do the magic RewriteRule "^/(.*)$" "/www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1" ## and now deal with CGIs - we have to force a handler RewriteCond "%{REQUEST_URI}" "^/cgi-bin/" RewriteRule "^/(.*)$" "/www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1" [H=cgi-script]
這種配置使用更進階的 mod_rewrite
功能,藉由個別的設定檔來找出虛擬主機轉譯文件的根目錄。這提供了更佳彈性,但是需要更複雜的設定。
vhost.map
檔案應如下所示
customer-1.example.com /www/customers/1
customer-2.example.com /www/customers/2
# ...
customer-N.example.com /www/customers/N
httpd.conf
應包含以下內容
RewriteEngine on RewriteMap lowercase int:tolower # define the map file RewriteMap vhost "txt:/www/conf/vhost.map" # deal with aliases as above RewriteCond "%{REQUEST_URI}" "!^/icons/" RewriteCond "%{REQUEST_URI}" "!^/cgi-bin/" RewriteCond "${lowercase:%{SERVER_NAME}}" "^(.+)$" # this does the file-based remap RewriteCond "${vhost:%1}" "^(/.*)$" RewriteRule "^/(.*)$" "%1/docs/$1" RewriteCond "%{REQUEST_URI}" "^/cgi-bin/" RewriteCond "${lowercase:%{SERVER_NAME}}" "^(.+)$" RewriteCond "${vhost:%1}" "^(/.*)$" RewriteRule "^/cgi-bin/(.*)$" "%1/cgi-bin/$1" [H=cgi-script]