Назад | Перейти на главную страницу

Переписать правило из .htaccess в Apache VirtualHost

У меня есть следующие .htaccess файл:

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On
</IfModule>

RewriteBase /
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /API/index.php [L]

Можно ли преобразовать приведенные выше правила в пригодные для использования VirtualHost блок?

<VirtualHost *:80>
    ServerAdmin webmaster@web-api
    DocumentRoot "/Users/shot/git/web-api"
    ServerName web-api
    ServerAlias web-api
    ErrorLog "/private/var/log/apache2/web-api-error_log"
    CustomLog "/private/var/log/apache2/web-api-access_log" common
    
    RewriteEngine on

    <Directory "/Users/shot/git/web-api">
        Options FollowSymLinks
        Order allow,deny
        Allow from all
        Require all granted
        RewriteBase /
        RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /API/index.php [L]
    </Directory>
</VirtualHost>

Но в журнале ошибок apache я получаю следующий вывод [core:error] [pid 2520] [client 127.0.0.1:52625] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

Если вы хотите поместить эти директивы прямо в VirtualHost (т.е. не внутри <Directory> контейнер), то вы можете переписать их так:

Options +FollowSymlinks
RewriteEngine On

RewriteRule ^ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteCond %{LA-U:REQUEST_FILENAME} !-f
RewriteCond %{LA-U:REQUEST_FILENAME} !-d
RewriteRule ^/. /API/index.php [L]

Необходимые изменения:

  • Когда директивы vhost обрабатываются, запрос еще не сопоставлен с файловой системой, поэтому необходимо использовать опережающий просмотр (LA-U:REQUEST_FILENANE), чтобы получить имя файла.

  • В контексте виртуального хоста URL-путь, соответствующий RewriteRule шаблон является относительным корнем, начиная с косой черты. Итак, вместо . в .htacces, тебе нужно /. (или ^/.) в конфиге vhost.

  • В RewriteBase Директива не применяется в контексте виртуального хоста, поэтому ее необходимо удалить. (Хотя вы все равно не использовали это в существующем .htaccess файл.)

Дополнительно:

  • В директиве, устанавливающей HTTP_AUTHORIZATION переменная среды, шаблон .* менее эффективен. Лучше использовать ^ (или подобное - что-то, что не должно проходить через весь URL-путь)

  • Ваш начальный <IfModule> обертка бессмысленна.