Преобразование правил перезаписи htaccess в правила виртуального хоста Apache2

Я пытаюсь установить поддомен с подстановочными знаками RewriteRule , объединив некоторые правила .htaccess , которые я успешно реализовал ранее, полагая, что я могу использовать те же правила для моего файла vhosts Apache.

По сути, пример. com и www.example.com перейдите по корневому пути и найдите index.php . Все остальные (динамические) запросы субдоменов на корневом уровне, такие как abc.example.com , перезаписываются (невидимы для браузера) на example.com/process.php?p=abc .

Во-вторых, любые запросы файлов из субдомена за пределами базового / корневого уровня должны быть переписаны, чтобы их можно было получить из корневого пути стандартного домена без субдомена. Итак, abc.example.com/css/style.css должен происходить с example.com/css/style.css

Это моя попытка сделать это. Я получаю сообщение об ошибке Apache:

У вас нет разрешения на доступ к /index.php на этом сервере.

для любой попытки поддомена, кроме www, который работает должным образом, а также стандартного пример. com , который по-прежнему работает нормально.

<VirtualHost *:80>

        ServerAdmin webmaster@example.com
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com/public_html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

<VirtualHost *:80>
        ServerAdmin webmaster@example.com
        ServerName other.example.com
        ServerAlias *.example.com
        DocumentRoot /var/www/example.com/public_html/

        <Directory /var/www/example.com/public_html/>
        Options FollowSymLinks
        AllowOverride all
        Require all granted

        RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
                RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
                RewriteRule ^$ /process.php?p=%2 [QSA,NC]
                RewriteCond %{REQUEST_FILENAME} !^$ [NC]
                RewriteRule ^(.*) http://www.example.com/$1 [P]
        </Directory>
</VirtualHost>

Я основал это на успешном перенаправлении корневого каталога другого домена на example.com с помощью этого файла .htaccess , который включает process.php и отправляет все остальные запросы в корень example.com .

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

# Check the request isn't an existing file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$ http://www.example.com/process.php [P]
RewriteCond %{REQUEST_FILENAME} !^$ [NC]
RewriteRule ^(.*) http://www.example.com/$1 [P]

А также отключив этот тест .htaccess , я побежал перенаправить субдомен в качестве переменной для process.php успешно, хотя он не перехватил другие файловые запросы, такие как пример css выше:

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^$ /process.php?p=%2 [QSA,NC]


Обновление 1

У меня (по-видимому) некоторый успех с используя следующее вместо моей второй записи виртуального хоста. Страница process.php выводится, если я использую поддомен. Хотя сопоставление с образцом, кажется, работает в этом отношении, мой реальный процесс . php получает пустую переменную, а не ожидаемый субдомен в виде строки (для: process.php? p =% 2 ):

<VirtualHost *:80>
        ServerAdmin webmaster@example.com
        ServerName other.example.com
        ServerAlias *.example.com
        DocumentRoot /var/www/example.com/public_html

        <Directory /var/www/example.com/public_html>
        Options FollowSymLinks
        AllowOverride all
        Require all granted
        RewriteEngine on
        RewriteBase /

        RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
        RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
        RewriteCond %{REQUEST_URI} ^/$
        RewriteRule ^$ /process.php?p=%2 [NC,QSA]
        </Directory>
</VirtualHost>


Обновление 2

Я решил это в окольный путь, но я не уверен, что это самый элегантный способ.

Используя приведенный выше код update 1 , я увидел, что любая строка запроса все еще добавляется, но % 2 не получал GET на моей странице process.php . Возможно, я ошибочно предположил, что, хотя URL-адрес не отображает переменную p = abc в URL-адресе для браузера, в соответствии с инструкциями моего кода, внутренний URL-адрес все еще передает их. Тем не менее, я понял, что process.php все еще может определять субдомен как строку, используя $ _ SERVER [' HTTP_X_FORWARDED_HOST '] в PHP и использовать его в качестве переменной на странице аналогично моей первоначальной идее.

3
задан 23 March 2017 в 18:27
1 ответ
 RewriteCond% {HTTP_HOST}! ^ Www \ .example \ .com $ [NC]
RewriteCond% {HTTP_HOST} ^ (www \.)? ([^ \.] +) \. Example \ .com $ [NC]
RewriteCond% {REQUEST_URI} ^ / $
RewriteRule ^ $ /process.php?p=%2 [NC, QSA]
 

Обратная ссылка % 2 не была установлена, потому что это обратная ссылка на вторую захваченную группу из последнего сопоставленного CondPattern ( RewriteCond шаблона). Последний совпавший CondPattern - это ^ / $ , у которого нет захваченных групп, поэтому % 2 всегда пусто.

Эта 3-я директива RewriteCond выглядит в любом случае лишнее. Это уже проверяется шаблоном RewriteRule ^ $ (в контексте каталога каталог-префикс удален - значит, это правильно).

Первая директива RewriteCond тоже выглядит лишней. Любой запрос для www.example.com будет перехвачен первым VirtualHost, поэтому имя хоста внутри этого VirtualHost никогда не будет www.example.com в любом случае, поэтому эта директива всегда имеет значение true.

Я бы переписал это как:

RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.example\.com$ [NC]
RewriteRule ^$ process.php?p=%1 [QSA]

Я сделал первую группу не захватывающей, т.е. (?: www \.) - ?: делает его не захватывающим. Таким образом, мы всегда получаем % 1 для фактического поддомена. Кроме того, нет необходимости экранировать точку (чтобы соответствовать буквальной точке) в классе символов. Флаг NC в RewriteRule здесь лишний.

Я также удалил префикс косой черты в подстановке RewriteRule , поскольку вы указали URL-путь в директиве RewriteBase .

Это только перезаписывает abc.example.com/ , т.е. запрос на корень документа.

Во-вторых, любые запросы файлов из субдомена за пределами базового / корневого уровня должны быть переписаны, чтобы они были получены из корневого пути стандартного домена без субдомена. Итак, abc.example.com/css/style.css должен происходить с example.com/css/style.css .

Начиная с abc.example.com / и example.com/ указывают на то же место в файловой системе, которое я не вижу, поскольку вам здесь нужно что-то делать? example.com/css/style.css должен указывать на тот же файл, что и abc.example.com/css/style.css .

А как насчет других файлов в документе? корень? например. abc.example.com/file . На данный момент это просто проходит без изменений, что и для файлов CSS.

1
ответ дан 3 December 2019 в 07:23

Теги

Похожие вопросы