将请求重新映射到不同的本地路径

时间:2016-09-07 13:16:00

标签: apache apache2.4

我想通过我的网络服务器提供多个子域名:

example.com
projects.example.com
blog.example.com
wiki.example.com
...

文档根目录设置如下:

ServerName   example.com
ServerAlias   *.example.com
VirtualDocumentRoot "/var/www/%0/public"

这可以自动将文档根目录设置为相应的子域。然而,我的下一个要求是它应该检测文档根目录中的public文件夹是否存在,如果不存在,则先检测一个目录中的文件。

我的大多数应用程序都是用Laravel编写的,因此它们带有public文件夹,但有时我只想快速创建一个没有public或部署外部的新脚本没有的软件。

因此,example.com(仅提供静态index.htmlstyle.css)的文档根目录应为/var/www/example.com/而不是/var/www/example.com/public。我通过重写规则尝试了这个:

<If "!-d '/var/www/' . %{HTTP_HOST} . '/public'">
    RewriteEngine on
    RewriteRule ^ "/var/www/%{HTTP_HOST}" [L,QSA]
</If>

这是重写错误日志的结果:

[rewrite:trace2] [pid 32153] mod_rewrite.c(475): [client 62.159.226.12:27139] 62.159.226.12 - - [example.com/sid#7f6588016340][rid#7f6587f810a0/initial] init rewrite engine with requested uri /
[rewrite:trace1] [pid 32153] mod_rewrite.c(475): [client 62.159.226.12:27139] 62.159.226.12 - - [example.com/sid#7f6588016340][rid#7f6587f810a0/initial] pass through /
[rewrite:trace3] [pid 32153] mod_rewrite.c(475): [client 62.159.226.12:27139] 62.159.226.12 - - [example.com/sid#7f6588016340][rid#7f6587f810a0/initial] [perdir *If/] add path info postfix: /var/www/example.com -> /var/www/example.com/public/
[rewrite:trace3] [pid 32153] mod_rewrite.c(475): [client 62.159.226.12:27139] 62.159.226.12 - - [example.com/sid#7f6588016340][rid#7f6587f810a0/initial] [perdir *If/] applying pattern '^' to uri '/var/www/example.com/public/'
[rewrite:trace2] [pid 32153] mod_rewrite.c(475): [client 62.159.226.12:27139] 62.159.226.12 - - [example.com/sid#7f6588016340][rid#7f6587f810a0/initial] [perdir *If/] rewrite '/var/www/example.com/public/' -> '/var/www/example.com'
[rewrite:trace1] [pid 32153] mod_rewrite.c(475): [client 62.159.226.12:27139] 62.159.226.12 - - [example.com/sid#7f6588016340][rid#7f6587f810a0/initial] [perdir *If/] initial URL equal rewritten URL: /var/www/example.com [IGNORING REWRITE]

正如您所看到的,它正确地映射了它,但由于某种原因不能从那里提供文件(我假设它是因为它不会附加index.html或任何东西之类的。)

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

这是因为核心看到不存在的public /并将其从当前文件名中分离出来并进入PATH_INFO。甚至[DPI]标志也不会有帮助,因为它会在最后一刻删除PATH_INFO作为重写的副作用。

不幸的是,在尝试抛弃PATH_INFO时,这种变化会在mod_rewrite的“循环检测”中被捕获,并且误认为文件名没有变化。

你应该反转你的逻辑,这样就不会注入杂散的PATH_INFO。然后重写将添加公共后缀而不是删除它。

这也允许你通过在RewriteCond中使用典型的-d测试来放弃否定和真正的整体。