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

Как предотвратить перезапуск apache обработки перезаписи в «контексте каталога»

У меня на моем виртуальном хосте для SSL-соединений есть следующее (мой виртуальный хост без ssl выглядит так же, но без первого набора правил для перенаправления).

DocumentRoot /var/www/example.com/public/
<Directory "/var/www/example.com/public/">
  #only mod_rewrite configuration is shown here

  RewriteEngine on
  RewriteBase /

  RewriteCond $1 !=signup
  RewriteCond $1 !=login
  RewriteCond $1 !=welcome
  RewriteCond $1 !=thankyou
  RewriteRule ^(.*)$ http://example.com/$1 [L,R,QSA]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]
</Directory>

Я намерен сделать так, чтобы любой запрос страницы, не совпадающий (signup | login | welcome | thankyou), был перенаправлен на виртуальный хост, отличный от ssl, без дальнейшей обработки, в противном случае не перенаправлял, а обрабатывал запрос на виртуальном хосте SSL.

Первый набор RewriteRule заботится о перенаправлении, а второй набор RewriteRule заботится о нормальной обработке страницы.

Без первого набора правил все запросы корректно загружаются под виртуальным хостом SSL.

С первым набором правил перенаправления работают нормально, если они не соответствуют перечисленным ресурсам. например. запрос на

https://example.com/about

перенаправляет на

http://example.com/about

Но при запросе страниц регистрации, входа, приветствия и благодарности возникает проблема. Эти запросы также перенаправляются на сайт без SSL, но некорректно. Запрос на

https://example.com/signup

перенаправляет на

http://example.com/index.php?q=signup

Казалось бы, первый набор правил не соответствует (как и следовало ожидать), затем после обработки второго набора правил первый набор правил применяется снова (не ожидается).

Я не могу сопоставить это неожиданное поведение с какой-либо задокументированной функцией.

Любые идеи?

редактировать

Я нашел в документации несколько неясных ссылок на повторный запуск правил apache, когда соответствие правил происходит в «контексте каталога», однако ссылка была на .htaccess. Моя перезапись выполняется внутри тега <Directory> в моем теге <VirtualHost>. В настоящее время я тестирую перемещение перезаписи за пределы контекста <Directory> - это определенно меняет поведение, но я еще не заставил его работать так, как мне нужно.

Edit2

Проблема, безусловно, вызвана тем, что apache перезапускает обработку перезаписи, когда обработка правила существует в контексте каталога. Я переместил обработку правил за пределы тега <Directory>. Однако теперь строки RewriteCond не работают ... например.

RewriteCond %{REQUEST_FILENAME} -f

поскольку apache еще не разрешил запрошенный ресурс для сопоставления файлов с помощью DocumentRoot. Какой беспорядок.

Итак, я вручную добавляю значение, указанное в DocumentRoot, к RewriteCond. Однако это похоже на плохой взлом. например.

RewriteCond /var/www/example.com/public%{REQUEST_FILENAME} -f

Итак, теперь я ищу способ предотвратить перезапуск apache процесса перезаписи в контексте каталога или, что еще лучше, лучший способ указать необходимые RewriteConds на уровне <VirtualHost>.

Я предлагаю добавить в вашу конфигурацию следующее, что даст вам подробный журнал того, что делает mod_rewrite и почему. Это может помочь понять, почему у вас такое поведение:

RewriteLog /tmp/rewrite.log
RewriteLogLevel 9

Как только вы закончите анализировать это, не забудьте удалить эти строки, поскольку они влияют на производительность.

Я остановился на следующем решении, помещая перезаписи вне каких-либо разделов <Directory ...>. Это позволяет мне перенаправлять любой запрос, который не должен быть SSL, на сайт без SSL, и в то же время разрешать обслуживание любого статического контента через SSL (изображения, CSS, js и т. Д.).

<VirtualHost ...>
  ...
  RewriteEngine on

  RewriteCond $1 !=signup
  RewriteCond $1 !=login
  RewriteCond $1 !=welcome
  RewriteCond $1 !=thankyou
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  RewriteRule ^/(.*)$ http://example.com/$1 [R=303,QSA,L]

  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteCond %{REQUEST_URI} !=/robots.txt
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  RewriteRule ^/(.+)$ /index.php?q=$1 [QSA,L]
  ...
</VirtualHost>