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

Переменные Apache (httpd) VirtualHost RewriteCond не работают

Я пытаюсь создать динамическую запись виртуального хоста с целью перенаправления всего трафика на .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 представляющий что-то еще в каждом модуле.

Возможно, теперь я лучше понял, что вы хотите сделать:

  1. Проверьте, есть ли у запроса каталог, соответствующий его поддомену, если нет, отправьте в /var/www/html/nosubdomain.php
  2. В противном случае проверьте, соответствует ли запрос файлу / каталогу / ссылке, если нет, отправьте /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]