I'm using vhost_alias
for to do mass virtual hosting and have several sites using mod_rewrite
to manage their front controllers.
I don't think this is a specific Symfony issue, but I'm using Symfony.
Now most requests that match any rewrite rule end up in an infnite redirect loop that causes an HTTP error 500.
I checked the log files and this is what I found:
(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'
As you can see, after the internal redirect line, the absolute path becomes part of the URI being matched, this URI of course does not match any files and is processed again as a completely new URI, this results in a new absolute path appended at the URI. This process repeats itself until reaching the configured limit.
I tried this without the virtual hosts configuration (which works fine) and noticed that before the internal redirect there is a new line:
(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]
After this redirect the actual file is matched and there is no problem.
Shouldn't the virtual document_root
be stripped in the virtual configuration as well as in the regular configuration?
I don't understand why the virtual document root is considered part of the URI in the internal redirect. This seems to be plain wrong.
Am I missing some configuration option?
Here is my .htaccess
file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^$ web/ [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ web/$1 [QSA,L]
</IfModule>
Here is my apache config file:
# 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>
Below the VirtualDocumentRoot
declaration there are some commented out rewrite rules.
That was an attempt at replacing the VirtualDocumentRoot
with rewrite rules, but it had a similar problem: the document_root being striped was /home/user/www
, leaving the hostname as part of the URL, so I end up having the same recursive problem.
So I would like to know if someone has ever made mod_vhost_alias
work with mod_rewrite
. I really tried to search everywhere (even google!) but could not find much information about this.
There target of a rewrite rule (the 2nd parameter) can either be a file-path or a URL-path. When it's not clear what it is, mod_rewrite guesses, and it looks like it may be guessing that it's a file-path. A few things you can try:
/
/web/
For 1 and 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>
possibly 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>