Я пытаюсь создать динамическую запись виртуального хоста с целью перенаправления всего трафика на .mydomain.com в / var / www / html / эта часть работает, но я также знаю условия перезаписи, которые проверяют, существует ли каталог, если он не существует, тогда я хочу перенаправить весь трафик в корень /var/www/html/index.php.
Эта часть не работает, потому что во время тестирования я заметил, что ни одна из переменных перезаписи не работает, они пусты, и я не могу понять, почему здесь моя конфигурация виртуального хоста
# get the server name from the Host: header
UseCanonicalName Off
# this log format can be split per-virtual-host based on the first field
# LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon
<VirtualHost *:80>
ServerName mydomain.com
ServerAlias www.mydomain.com
VirtualDocumentRoot /var/www/html
</VirtualHost>
<VirtualHost *:80>
ServerName vhosts.mydomain.com
ServerAlias *
VirtualDocumentRoot /var/www/html/%1
RewriteEngine on
LogLevel warn rewrite:trace4
# If the request is not for a valid directory
RewriteCond /var/www/html/%1 !-d
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid link
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* /var/www/html/index.php
</VirtualHost>
Вы заметите, что у меня есть несколько вариантов использования переменной, которую я могу использовать при тестировании и просмотре моего файла журнала.
[Wed Jul 29 16:56:56.015818 2015] [rewrite:trace2] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] init rewrite engine with requested uri /
[Wed Jul 29 16:56:56.016050 2015] [rewrite:trace3] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] applying pattern '.*' to uri '/'
[Wed Jul 29 16:56:56.018361 2015] [rewrite:trace4] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] RewriteCond: input='/var/www/html/' pattern='!-d' => not-matched
[Wed Jul 29 16:56:56.018411 2015] [rewrite:trace1] [pid 23898] mod_rewrite.c(475): [client xx.xx.xx.xx:4863] xx.xx.xx.xx - - [fake.mydomain.com/sid#7f5c89bcf570][rid#7f5c89ed5000/initial] pass through /
хотя% 1 отлично подходит для виртуального каталога, он не работает в правиле перезаписи мода. Все другие варианты использования переменных дают те же результаты, любая помощь будет принята с благодарностью.
Не уверен, что это имеет значение, но это работает в сборке AWS на Amazon Linux.
% 1 НЕ является своего рода глобальной переменной для всей конфигурации Apache.
В VirtualDocumentRoot он соответствует первой части имени хоста, а в RewriteCond
или RewriteRule
он представляет собой обратные ссылки на группы захвата в предшествующий RewriteCond
. См. Документ Apache для RewriteCond
Выбросьте эту часть:
RewriteCond /var/www/html/%1 !-d
Вы используете% 1 неправильно, у вас раньше не было RewriteCond, поэтому% 1 - пустая строка. Итак, в основном у вас есть условие, которое гласит: «Если / var / www / html / не является каталогом, сделайте ...»
Но очевидно /var/www/html
это каталог, поэтому в вашей строке журнала написано
RewriteCond: input='/var/www/html/' pattern='!-d' => not-matched
UPADTE как продолжение вашего комментария:
Следует понимать, что Apache состоит из множества различных частей, которые являются модулями. Каждый модуль имеет собственный синтаксис. Это делает все очень мощным, но может сбивать с толку, как в вашем вопросе. Каждый модуль может определять синтаксис с переменной с именем %1
представляющий что-то еще в каждом модуле.
Возможно, теперь я лучше понял, что вы хотите сделать:
/var/www/html/nosubdomain.php
/var/www/html/nofile.php
Шаг 1. Получите субдомен
Чтобы получить поддомен, вы можете использовать возможность mod_rewrite для определения и установки переменных среды (здесь %1
является результатом захвата в RewriteCond):
# Setting environment variable SUBDOMAIN = (subdomain).example.com
RewriteCond %{HTTP_HOST} ^([^\.]*)\.example\.com$
RewriteRule . - [E=SUBDOMAIN:%1]
Шаг 2: Теперь вы можете использовать переменную SUBDOMAIN в ваших правилах перезаписи / cond и проверить, существует ли каталог, соответствующий поддомену. Если нет, вы перенаправляете на определенную страницу
# Test if subdomain directory exists, if not, redirect to a
# standard page (/var/www/html/nosubdomain.php).
RewriteCond /var/www/html/%{ENV:SUBDOMAIN} !-d
RewriteRule .* /var/www/html/nosubdomain.php [L]
Шаг 3: проверьте, существует ли запрошенный файл, если нет, отправьте стандартную страницу (/var/www/html/nofile.php
). Для этого гораздо лучше полагаться на самопроверку Apache и использовать ErrorDocument. Нам нужен псевдоним, потому что вам нужен файл nofile.php
находиться за пределами VirtualDocumentRoot (/var/www/html/subdomain/
)
Alias /nofile.php /var/www/html/nofile.php
ErrorDocument 404 /nofile.php
Объединение всех этих шагов сразу после вашей директивы RewriteEngine On
должны поднять вас с рабочей настройкой, которую, конечно же, придется адаптировать к вашему конкретному варианту использования. Я протестировал эту установку, она работает так, как я хотел, но на Apache 2.2.
Вы также можете объединить шаги 1 и 2 вместе, если вы не используете SUBDOMAIN в другом месте:
RewriteCond %{HTTP_HOST} ^([^\.]*)\.example\.com$
RewriteCond /var/www/html/%1 !-d
RewriteRule .* /var/www/html/nosubdomain.php [L]