使用 mod_rewrite 模拟 VirtualDocumentRoot

使用 mod_rewrite 模拟 VirtualDocumentRoot

在我的 apache 设置中,我希望有多个以域名命名的目录,这些目录将根据子域层次结构提供服务。

例如,给定现有的两个目录:

  1. company.com
  2. shop.company.com

Apache 将根据请求主机提供以下目录:

  1. www.company.com -> company.com
  2. us.company.com -> company.com
  3. shop.company.com -> shop.company.com
  4. foo.bar.shop.company.com -> shop.company.com

据我所知,mod_vhost_alias 无法测试目录的存在或操纵请求主机。因此它不适合这项任务。

然而,我通过以下 mod_rewrite 实现成功了:

<VirtualHost *:80>
    # Omitting this line produces strange behaviour, requesting company.com the
    # server will try to look up /var/www/test.localhost/var/www/test.localhost
    # Clarification on this issue is very welcome
    DocumentRoot /var/www

    RewriteEngine on

    # Full domain
    RewriteCond %{HTTP_HOST} ^(.*)$
    RewriteCond /var/www/%1 -d
    RewriteRule (.*) /var/www/%1/$1 [L]

    # -1 domain level
    RewriteCond %{HTTP_HOST} ^.+?\.(.*)$
    RewriteCond /var/www/%1 -d
    RewriteRule (.*) /var/www/%1/$1 [L]
</VirtualHost>

我想知道是否有更好的解决方案来完成这项任务,以及我的实施是否存在任何缺陷。

到目前为止,我只发现我需要为依赖于重写并且应该放在顶层的脚本指定“RewriteBase /”。

这不适用于生产,并且性能影响可以忽略不计。

答案1

我认为这是一个非常聪明的方法。但明显的缺陷是,它不适用于你的第四个示例 - 你只删除了第一个子域部分,因此foo.bar.shop.company.com将被翻译为bar.shop.company.com代替 shop.company.com

您可以使用外部程序(例如 perl 脚本)进行重写,通过使用 RewriteMap 指令来捕获更特殊的情况。但这会带来更多复杂性,并进一步降低性能。

相关内容