本文档是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]