Apache mod_rewrite子域到子文件夹(通过内部重定向)

时间:2009-07-22 17:56:23

标签: apache mod-rewrite

我正在尝试编写一组mod_rewrite规则,允许我的用户使用单个文件夹在不同项目上进行开发,而不必为每个项目添加vhosts。

我实现这一目标的想法是为每个需要此功能的用户(仅3-4个)设置“全局VHost”,vhost将类似于:.my-domain.com。从那里,我想促进我的用户编写代码,就像它在域上,而不是在子文件夹中。例如,如果bob正在处理一个名为“gnome”的项目,我希望URL bob(以及我们内部网络上的其他任何人)加载到这个项目:http://gnome.bob.my-domain.com。但是,我想让Apache做的是,认识到“gnome”是一个“项目”,因此在内部将请求映射到bob.my-domain.com/gnome /.

我有我认为会起作用的东西,而且很简单,但是......它不起作用!请求进入无限循环,并将子域前缀保留在重写的请求URI上。

我的mod重写代码是:

RewriteEngine On

RewriteCond %{HTTP_HOST}    ^([^.]+)\.bob\.my-domain\.com
RewriteCond %{REQUEST_URI}  !^/%1.*
RewriteRule ^(.*)$      /%1/$1 [L]

我已经开始讨论这个问题,但我还没有找到任何有效的解决方案。有没有人试过这个 - 或许,有没有人有更好的主意?一个不涉及为每个项目制作虚拟主机(我有设计师......我想每个人都会同意设计师不应该制造虚拟主机......)

谢谢!

这是rewrite_log的一个片段:

[rid#838dc88/initial] (3) [perdir /home/bob/http/] strip per-dir prefix: /home/bob/http/index.html -> index.html
[rid#838dc88/initial] (3) [perdir /home/bob/http/] applying pattern '^(.*)$' to uri 'index.html'
[rid#838dc88/initial] (4) [perdir /home/bob/http/] RewriteCond: input='gnome.bob.my-domain.com' pattern='^([^.]+)\.bob\.my-domain\.com' => matched
[rid#838dc88/initial] (4) [perdir /home/bob/http/] RewriteCond: input='/index.html' pattern='!^/%1.*' => matched
[rid#838dc88/initial] (2) [perdir /home/bob/http/] rewrite 'index.html' -> '/gnome/index.html'
[rid#838dc88/initial] (1) [perdir /home/bob/http/] internal redirect with /gnome/index.html [INTERNAL REDIRECT]
[rid#8392f30/initial/redir#1] (3) [perdir /home/bob/http/] strip per-dir prefix: /home/bob/http/gnome/index.html -> gnome/index.html
[rid#8392f30/initial/redir#1] (3) [perdir /home/bob/http/] applying pattern '^(.*)$' to uri 'gnome/index.html'
[rid#8392f30/initial/redir#1] (4) [perdir /home/bob/http/] RewriteCond: input='gnome.bob.my-domain.com' pattern='^([^\.]+)\.bob\.my-domain\.com' => matched
[rid#8392f30/initial/redir#1] (4) [perdir /home/bob/http/] RewriteCond: input='/gnome/index.html' pattern='!^/%1.*' => matched
[rid#8392f30/initial/redir#1] (2) [perdir /home/bob/http/] rewrite 'gnome/index.html' -> '/gnome/gnome/index.html'
[rid#8392f30/initial/redir#1] (1) [perdir /home/bob/http/] internal redirect with /gnome/gnome/index.html [INTERNAL REDIRECT]
[rid#8397970/initial/redir#2] (3) [perdir /home/bob/http/] add path info postfix: /home/bob/http/gnome/gnome -> /home/bob/http/gnome/gnome/index.html

这只是一个片段,在apache遇到它之前,有几个10或100左右的apache基本上重写/gnome/index.html到/gnome/gnome/gnome/gnome/gnome/index.html等重写限制,放弃,并抛出错误500

4 个答案:

答案 0 :(得分:5)

经过几年忽略这个问题并在各个方面回到它之后,我终于找到了一个可行的解决方案。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^([^.]+)\.bob\.my-domain\.com
RewriteCond %1::%{REQUEST_URI} !^(.*?)::/\1/
RewriteRule ^(.*)$  /%1/$1 [L]

我发现以后的RewriteCond方向的反向引用在将来的RewriteConditions的ConditionPattern参数中不可用。如果要使用先前RewriteCond指令的反向引用,则只能在TestString参数中使用它。

上述指令将第1 RewriteCond指令中匹配的子域添加到RequestURI,由::分隔。然后我们在RewriteCond测试字符串(正则表达式)中执行的操作是重新捕获子域名,然后检查以确保我们的实际RequestURI不以该子域开头为使用后引用的文件夹在同一个正则表达式中。

这听起来比实际上更令人困惑,我不能因为发现答案而受到赞誉。我在这里找到了答案作为对另一个问题的回答%N backreference inside RewriteCond。感谢Jon Lin回答这个问题,而且他也不知道,我的问题也是如此!

答案 1 :(得分:1)

您可能想要检查

http://httpd.apache.org/docs/2.2/vhosts/mass.html

它处理您遇到的DocumentRoot问题。

规则是这样的

VirtualDocumentRoot /var/www/%1/

您可以更改适用于您的任何内容的%1(http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html

干杯

答案 2 :(得分:0)

有些问题:

你说“内部地图” - 你不想使用重定向吗?

您是否对gnome.bob.mysite.combob.mysite.com

使用相同的VirtualHost

您是否记得为*.bob.mysite.com创建了ServerAlias?

<小时/> 这是一个粗略的版本,你可以修改工作。它将捕获子域和请求的URL,并重定向到主域,子域作为路径的第一部分,后跟请求的路径,后跟查询字符串。

ServerName www.mysite.com
ServerAlias *.mysite.com

RewriteCond %{HTTP_HOST} ^([a-zA-Z0-9-]+)\\.mysite.com$
RewriteRule ^/(.*)       http://www.mysite.com/%1/$1        [R=301,L]',    

答案 3 :(得分:0)

您是否尝试过使用其他重写规则来处理之前的规则?

RewriteEngine On

RewriteCond %{HTTP_HOST}                       ^([^.]+)\.bob\.my-domain\.com
RewriteCond %{REQUEST_URI}                     !^/%1.*
RewriteRule ^(.*)$                             /%1/$1 [C]    
RewriteRule ^/(.*)\.bob\.my-domain\.com/(.*)   /$1/$2 [L]

但我认为您的更大问题是您的服务器不理解它是以不同的名称提供服务。

它认为它正在/ gnome /目录中运行,而浏览器正在/目录中运行。因此,您拥有的任何相对URL都会导致问题。

您需要的是一个过滤器,它将通过处理器运行您网页中的所有网址,并将其从/ gnome /更改为/。