2

我正在使用vhost_aliasfor 进行大规模虚拟主机,并有几个站点mod_rewrite用于管理它们的前端控制器。

我不认为这是一个特定的 Symfony 问题,但我正在使用 Symfony。

现在,大多数匹配任何重写规则的请求都会进入无限重定向循环,从而导致 HTTP 错误 500。

我检查了日志文件,这就是我发现的:

(3) [perdir /home/user/www/mysite/] strip per-dir prefix: /home/user/www/mysite/app_dev.php -> app_dev.php
(3) [perdir /home/user/www/mysite/] applying pattern '^$' to uri 'app_dev.php'
(3) [perdir /home/user/www/mysite/] strip per-dir prefix: /home/user/www/mysite/app_dev.php -> app_dev.php
(3) [perdir /home/user/www/mysite/] applying pattern '^(.*)$' to uri 'app_dev.php'
(2) [perdir /home/user/www/mysite/] rewrite 'app_dev.php' -> 'web/app_dev.php'
(3) [perdir /home/user/www/mysite/] add per-dir prefix: web/app_dev.php -> /home/user/www/mysite/web/app_dev.php
(1) [perdir /home/user/www/mysite/] internal redirect with /home/user/www/mysite/web/app_dev.php [INTERNAL REDIRECT]
(3) [perdir /home/user/www/mysite/] add path info postfix: /home/user/www/mysite/home -> /home/user/www/mysite/home/user/www/mysite/web/app_dev.php
(3) [perdir /home/user/www/mysite/] strip per-dir prefix: /home/user/www/mysite/home/user/www/mysite/web/app_dev.php -> home/user/www/mysite/web/app_dev.php
(3) [perdir /home/user/www/mysite/] applying pattern '^$' to uri 'home/user/www/mysite/web/app_dev.php'

如您所见,在内部重定向行之后,绝对路径成为被匹配 URI 的一部分,这个 URI 当然不匹配任何文件并作为全新的 URI 再次处理,这导致新的绝对路径附加在URI。这个过程会不断重复,直到达到配置的限制。

我在没有虚拟主机配置(工作正常)的情况下尝试了这个,并注意到在内部重定向之前有一个新行:

(2) [perdir /home/user/www/mysite/] strip document_root prefix: /home/user/www/mysite/web/app_dev.php -> /web/app_dev.php
(1) [perdir /home/user/www/mysite/] internal redirect with /web/app_dev.php [INTERNAL REDIRECT]

在此重定向之后,实际文件匹配并且没有问题。

虚拟配置不应该document_root像常规配置一样被剥离吗?

我不明白为什么虚拟文档根被认为是内部重定向中 URI 的一部分。这似乎是完全错误的。

我错过了一些配置选项吗?

这是我的.htaccess文件:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ web/ [QSA,L]    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ web/$1 [QSA,L]
</IfModule>

这是我的 apache 配置文件:

# get the server name from the Host: header
UseCanonicalName Off

<VirtualHost *:80>
    LogLevel debug
    RewriteLogLevel 3
    RewriteLog "/var/log/apache2/rewrite.log"

    VirtualDocumentRoot /home/user/www/%1

#DocumentRoot /home/user/www
#RewriteEngine on
#RewriteCond %{HTTP_HOST} ^(.*)\.dev$ [NC]
#RewriteRule ^/(.+)$ /home/user/www/%1/$1 [QSA,L]

    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    <Directory /home/user/www>
        Options Indexes FollowSymLinks -MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

在声明下方VirtualDocumentRoot有一些注释掉的重写规则。

这是用重写规则替换的尝试VirtualDocumentRoot,但它有一个类似的问题:被条带化的 document_root 是/home/user/www,将主机名作为 URL 的一部分,所以我最终遇到了同样的递归问题。

所以我想知道是否有人曾经mod_vhost_aliasmod_rewrite. 我真的试图到处搜索(甚至是谷歌!)但找不到太多关于此的信息。

4

2 回答 2

2

重写规则的目标(第二个参数)可以是文件路径或 URL 路径。当不清楚它是什么时,mod_rewrite 会猜测,看起来它可能会猜测它是一个文件路径。您可以尝试几件事:

  1. 添加重写基础或通过添加前导使目标成为绝对 URL 路径/
  2. 添加额外条件以检查 URI 是否以/web/
  3. 也许,添加另一个条件来检查目标是否存在

对于 1 和 2:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ /web/ [QSA,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/web/
    RewriteRule ^(.*)$ /web/$1 [QSA,L]
</IfModule>

可能3:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ /web/ [QSA,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{DOCUMENT_ROOT}/web%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}/web%{REQUEST_URI} -d
    RewriteRule ^(.*)$ /web/$1 [QSA,L]
</IfModule>
于 2013-09-12T02:17:43.963 回答
0

要启用它的重写模块,请运行“apache2 enable module rewrite”:

sudo a2enmod rewrite

您需要重新启动网络服务器以应用更改:

sudo service apache2 restart

VirtualHost 应该是这样 ServerName localhost.myproject.dev ServerAdmin webmaster@localhost

DocumentRoot /var/www/project_path
<Directory /var/www/project_path>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ /app.php [QSA,L]
    </IfModule>
</Directory>

于 2013-09-12T03:20:41.947 回答