php mod rewrite как включить

Настройка mod_rewrite

Что такое mod_rewrite?

Вспомните последнее посещение интернет-магазина. Найдя нужный товар, вы, вероятно, увидели примерно такой URL:

Это происходит не потому, что разработчики этого сайта потратили уйму времени, чтобы настроить отдельные директории для разных категорий товара, а благодаря удобному модулю по имени mod_rewrite. Данный модуль позволяет создавать пользовательские и упрощенные URL-адреса. На самом деле URL выглядит примерно так:

Требования

Для выполнения данного руководства понадобятся привилегии root (чтобы получить более подробную информацию, читайте статью «Начальная настройка сервера Ubuntu»).

Кроме того, нужно предварительно установить apache. Для быстрой установки этого веб-сервера в Ubuntu используйте команду:

sudo apt-get install apache2

1: Включение mod_rewrite

Для начала нужно включить mod_rewrite, это очень просто:

sudo a2enmod rewrite

Данная команда включит модуль или же выведет сообщение «Module rewrite already enabled» в случае если модуль уже включен.

sudo nano /var/www/example.com/.htaccess

Примечание: для этого понадобятся расширенные привилегии sudo.

sudo nano /etc/apache2/sites-available/default

В этом файле найдите следующий раздел и измените значение строки AllowOverride (замените None на All). В результате раздел будет иметь такой вид:

Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all

sudo service apache2 restart

Теперь все готово для переписывания URL-адресов сайта.

3: Переписывание URL-адресов

RewriteRule Pattern Substitution [OptionalFlags]

Опции, использованные в данной команде:

Примеры перезаписи URL-адреса

Пример 1: открываете страницу А – попадаете на страницу Б

Это наиболее простой пример перезаписи URL: посетитель сайта вводит в браузер один URL, но перенаправляется на другой. Чтобы настроить такое поведение, следуйте инструкциям этого раздела.

Источник

mod_rewrite — просто о сложном

Что это такое?

Hello world

Первая директива включает механизм mod_rewrite в текущей папке и во всех ее подпапках. Вторая указывает модулю mod_rewrite, что текущая папка в файловой системе соответствует корню сайта. Третья — непосредственно правило преобразования URL.

Прочесть его можно так:
Если сразу после начала строки («^») идет произвольное количество любых символов ( «(.*)» ), причем мы хотим запомнить, что именно это за символы, окружая их скобками, затем идет точка («\.») (экранируем точку, потому что одиночная точка — это просто любой символ), затем символы «msl» и на этом строка заканчивается («$»), то заменим исходный URL на следующий: возьмем первую запомненную подстроку в скобках из правила, прибавим к ней «.php», добавим все дополнительные параметры адреса, которые могли быть «[QSA]» и на этом закончим, не будем применять дальнейшие преобразования, если они есть «[L]»

Все, теперь Вы можете смело менять все ссылки, заканчивающиеся на «.php» на «.msl» и писать в своем блоге, что изобрели новый скриптовый язык. Apache, встретив ссылку на «index.msl» с помощью mod_rewrite на лету преобразует ее в «index.php» и вызовет нужный скрипт.

А что еще умеет mod_rewrite?

О, этот модуль умеет многое. Лично я жду, когда же кто-нибудь достаточно продвинутый в магии и PCRE напишет «Морской бой» на mod_rewrite.

Но пока этого не случилось, покажу еще несколько вариантов использования этого замечательного модуля.

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

Первичная фильтрация данных

В квадратных скобках, в соответствии с синтаксисом PCRE, мы задаем класс символов, включая в него цифры, буквы латинского алфавита, минус и знак подчеркивания. Все адреса, в которых будут какие-то другие символы, не пройдут проверку этим правилом и приведут к ошибке 404. Флаг [L] необходим, чтобы движок mod_rewrite, успешно сделав преобразование, не пошел далее, на второе правило. Этот флаг аналогичен оператору break внутри цикла.

Второе правило не задает напрямую преобразование адреса (символ «-«), а запрещает прямой доступ к скрипту viewblog.php (флаг «[F]»), тем самым закрывая злодеям возможность передать в параметрах что-то вредоносное.

Использование для кэширования в ФС

Предположим, что Ваш проект растет. Хостинг перестает справляться с нагрузками — сотни блоггеров, десятки тысяч просмотров их блогов, да еще и комментарии…

И тут mod_rewrite может придти на помощь, если по каким-то причинам Вы не хотите переходить на свой сервер.

Во-первых, модифицируйте свой скрипт viewblog.php таким образом, чтобы при обращении к нему он не только выдавал сформированную страницу в браузер, но и записывал ее в файловую систему по адресу /blogs/ABC.html

Проще всего это сделать, использовав функции управления буферизацией. Предположим, что исходный код скрипта viewblog.php выглядит у Вас примерно так:

Применим буферизацию вывода и запишем вывод в файл.

RewriteRule blogs\/([a-z0-9_-]+)([\/]<0,1>)$ blogs\/$1\.html

RewriteCond % blogs\/([a-z0-9_-]+)\.html$
RewriteCond % !-s
RewriteRule (.*) viewblog.php?blogname=%1

В первой строке мы преобразуем URL вида blogs/ABC/ в blogs/ABC.html, таким образом перенаправляя Apache на сгенерированный нами файл кэша страницы.
Следующие три строки представляют собой одно большое правило. Если идет запрос на blogs/ABC.html и при этом в файловой системе нет такого файла — запрос перенаправляется на скрипт viewblog.php

Таким образом нам остается только предусмотреть систему своевременной очистки кэша и задача решена.

Другие применения

Лично я использую модуль mod_rewrite аналогично последнему примеру для генерации и хранения в ФС превью изображений.

Очень легко с помощью mod_rewrite делается отображение поддоменов на папки, например forum.localhost.localdomain физически будет находиться в localhost.localdomain/forum, что часто бывает проще для разработчика приложения.

Незаменим mod_rewrite для ограничения скачивания файлов на файловом хостинге или в магазине цифровых товаров (придется задействовать механизм символических ссылок) или для запрета хотлинкинга (через проверку реферера).

А вообще — это Вуду 🙂
Чертовски интересное Вуду, позволяющее каждый день открывать новые стороны и применения.

Источник

HackWare.ru

Этичный хакинг и тестирование на проникновение, информационная безопасность

Полное руководство по mod_rewrite (часть 1): Как включить и как работает mod_rewrite

Оглавление. Полное руководство по mod_rewrite

8. Директива RewriteOptions, технические подробности, когда НЕ использовать mod_rewrite

Что такое mod_rewrite

mod_rewrite является одним из самых часто используемых модулей веб-сервера Apache. При этом он является и самым непонятным: очень многие ищут подходящие под свои нужды примеры выражений mod_rewrite и копируют их без полного понимания, как именно это работает и что именно происходит при обработке адресов.

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

mod_rewrite предоставляет возможность динамически изменять входящие URL-запросы, основываясь на правилах, использующих регулярные выражения. Это позволяет вам сопоставлять произвольные URL-адреса к вашей внутренней структуре URL любым способом. По умолчанию mod_rewrite сопоставляет URL-адрес пути к файловой системе. Однако он также может использоваться для перенаправления одного URL-адреса на другой URL-адрес или для вызова внутренней прокси передачи.

mod_rewrite предоставляет гибкий и мощный способ манипулирования URL-адресами, используя неограниченное количество правил. Каждое правило может иметь неограниченное количество прикреплённых условий правила, позволяя вам переписать URL на основе переменных сервера, переменных среды, заголовков HTTP, метки времени, запросы к внешним базам данных и различных других внутренних программ и обработчиков.

Правила перезаписи могут оперировать полными URL, включая path-info (информацию о пути) и строку запроса; отдельные правила можно настроить для использоваться в контексте всего сервера, отдельного для каждого виртуального хоста или для каждой директории (папки). Правила перезаписи могут вести к последующим правилам, внутренним подпроцессам, внешним перенаправлениям запросов или проксированию, в зависимости от флагов, которые вы добавили к правилам.

Поскольку mod_rewrite такой мощный, его изучение требует времени. Функциональность mod_rewrite пересекается с некоторыми другими модулями Apache и решение, что именно использовать, за вами. В этой инструкции дан подробный разбор всех возможностей mod_rewrite и показано много примеров, как использовать этот модуль, а когда лучше использовать другие альтернативы.

Для чего нужен mod_rewrite / Что умеет mod_rewrite

Слово «rewrite» в названии модуля буквально означает «перезапись». Эта «перезапись» относится к URL (адресу сайта, страницы, файла). Перезапись (преобразование) происходит между тем, что введено в строке браузера пользователя (фактически, отправлено на веб-сервер) и тем, что веб-сервер получит на самом деле.

Человекопонятные пути улучшают удобство использования, Кроме того, позволяют по названию ссылки заранее предполагать содержимое страницы по ней, и представлять структуру сайта.

Слеши (/) на веб-сервере разделяют вложенные подпапки. Но в случае с ЧПУ если в адресе страницы встречается строка /product/phone/Samsung/, то это не означает, что на веб-сайте действительно имеется папка product, в которой подпапка phone и в которой подпапка Samsung. Благодаря mod_rewrite строка вида /product/phone/Samsung/ перезаписывается в строку вида index.php?category=product&type=phone&brand=Samsung. Таким образом, пользователь набирает в веб-браузере, либо переходит по ссылке с удобным для его восприятия адресом, а веб-сервер получает данные в понятном для обработки виде, когда каждой переменной присваивается соответствующее значение и эти переменные передаются в скрипт веб-сервера для обработки, либо отображения информации.

Это очень популярное, но не единственное применение mod_rewrite. Этот модуль умеет делать перезапись на основе разных данных: к примеру, на основе типа браузера. Это позволяет показывать разные страницы в зависимости от типа браузера, IP адреса, языка пользователя, установленных кукиз и т.д.

mod_rewrite умеет делать редирект (перенаправление) на другой адрес. В результате, если ваш сайт переехал на другой домен или поменялась структура сайта, вы можете настроить автоматическую переадресацию со старых адресов страниц на новые.

mod_rewrite умеет запрещать доступ к определённым ресурсам, как по определённому условию, так и безусловно. Т.е. вы можете настроить контроль доступа, закрыв определённые страницы для всех пользователей, либо на основе их стран, языка, веб-браузера и т.д.

На самом деле – это не всё, что умеет mod_rewrite! И даже в этом мануале вы встретитесь с дополнительными примерами применения mod_rewrite.

Прежде чем мы перейдём к теории и практики использования mod_rewrite, нужно включить модуль mod_rewrite для веб-сервера, либо убедиться, что mod_rewrite уже включен. Если вы используетесь shared (совместным) хостингом, то у большинства хостеров этот модуль включен по умолчанию. Ниже показано, как включить этот модуль на своём собственном локальном (домашнем) сервере, либо веб-сервере на VPS.

Включение mod_rewrite

mod_rewrite – это опциональный (необязательный) модуль веб-сервера Apache, который по умолчанию отключён. Поэтому работу с mod_rewrite нужно начать с его включения в веб-сервере.

Начнём с небольшой теории. Правила mod_rewrite для преобразования URL можно описывать как в конфигурационном файле Apache apache2.conf (в некоторых системах называется httpd.conf), так и в файле .htaccess отдельно для каждой директории.

Если вы используете Debian, Ubuntu, Linux Mint, Kali Linux то mod_rewrite можно включить следующей командой:

В Debian, Ubuntu, Linux Mint, Kali Linux эта группа строк выглядит так:

В этой группе строк замените

После чего перезапустите веб-сервер (на некоторых дистрибутивах служба называется не apache2, а httpd):

Если вы используете Apache в Windows, то для включения mod_rewrite в файле httpd.conf (C:\Server\bin\Apache24\conf\httpd.conf) найдите и раскомментируйте строку:

php mod rewrite как включить. Смотреть фото php mod rewrite как включить. Смотреть картинку php mod rewrite как включить. Картинка про php mod rewrite как включить. Фото php mod rewrite как включить

В Windows она может выглядеть так:

В этой группе строк замените

php mod rewrite как включить. Смотреть фото php mod rewrite как включить. Смотреть картинку php mod rewrite как включить. Картинка про php mod rewrite как включить. Фото php mod rewrite как включить

Чтобы любые изменения, сделанные в конфигурационном файле Apache, вступили в силу, нужно перезапустить сервер.

Если вы решили для использования mod_rewrite вносить изменения в конфигурационный файл Apache, то не забывайте каждый раз после изменения правил перезапускать веб-сервер, чтобы эти изменения вступили в силу.

Также должна быть включена опция Options FollowSymLinks (по умолчанию она включена). Если FollowSymLinks отключено, то невозможно использовать движок перезаписи. Это ограничение продиктовано причинами безопасности.

Журнал (логи) преобразований mod_rewrite

Когда вы написали и тщательно проверили правила для mod_rewrite, журнал преобразований можно включить или отключить на своё усмотрение. Но на время обучения либо тестирования новых правил, рекомендуется, конечно, включить ведение журнала и в случае возникновения проблем изучать логи mod_rewrite.

Тема логов Apache сама по себе довольно объёмная, не будем на ней заострять внимание. Но необходимо упомянуть, что если вы работали с предыдущими версиями mod_rewrite и использовали директивы RewriteLog и RewriteLogLevel, то теперь их функциональность полностью заменена директивой LogLevel, которая настраивать логи всего веб-сервера и всех модулей.

По умолчанию LogLevel установлено показывать предупреждение, в конфигурационном файле Apache это строка:

Можно заменить эту строку на:

Она означает, что для всего веб-сервера и остальных модулей настроен уровень журнала «error», т.е. показывать только ошибки и более важные сообщения, а для модуля mod_rewrite установлен уровень трассировки trace2.

mod_rewrite предлагает детальную запись его действий с уровней ведения журнала от trace1 до trace8. Уровень trace8 означает запись практически всех действий. Использование высоких уровней логов трассировки для mod_rewrite драматически замедлит ваш Apache HTTP сервер! Используйте уровень выше чем trace2 только для отладки!

Сообщения о работе mod_rewrite будут записываться в файл ошибок Apache (например, error.log). Чтобы из этого файла отфильтровать только строки, относящиеся к mod_rewrite, можно использовать поиск по «[rewrite:». К примеру, в Linux это можно делать примерно следующей командой:

Директивы RewriteEngine и RewriteRule

Модуль mod_rewrite использует несколько директив, и в этом руководстве мы рассмотрим их все. Но в каждом примере мы неизменно будем использовать две главные директивы, это RewriteEngine и RewriteRule. Первая директива, в виде

просто включает использование mod_rewrite в файле .htaccess.

Значение директивы можно установить на off:

В этом случае правила, которые следуют после отключения RewriteEngine off, не будут задействованы. Отключение RewriteEngine можно использовать вместо удаления или комментирования строк с правилами RewriteRule.

Конфигурации перезаписи не наследуются виртуальными хостами. Это означает, что нужно иметь директиву RewriteEngine on для каждого виртуального хоста, на которым вы хотите использовать правила перезаписи.

А вторая директива RewriteRule является главной рабочей лошадкой этого модуля. Именно с её помощью мы будем устанавливать правила перезаписи.

Она используется следующим образом:

Шаблон – это то, что мы ищем в передаваемом URL.

Подстановка – это новая строка, которая передаётся веб-серверу в том случае, если в исходных данных найдено совпадение с Шаблоном.

[флаги] – это условные обозначения, задающие дополнительные действия или поведение при перезаписи. Они являются необязательными. Мы также рассмотрим флаги в этой инструкции.

Шаблон RewriteRule

В качестве Шаблона используется регулярное выражение, которое представляет собой способ описать текст, который считается подходящим (совпадающим с шаблоном). Шаблоны можно выразить словами, например, «все слова, которые начинаются с буквы A» или «каждый десятизначный телефонный номер» или «каждое предложение с двумя запятыми и без заглавных букв Q».

Польза регулярных выражений в том, что они позволяют, не перечисляя все возможные варианты (которых может быть бесконечно много), установить правила для каждого из этого возможного варианта, если исходный запрос удовлетворяет определённым требованиям.

Более подробно регулярным выражениемя (шаблонам) посвящена вся вторая часть данного руководства.

Какая часть запроса проверяется на совпадение с Шаблоном?

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

В контексте VirtualHost Шаблон первоначально проверяется на соответствие с частью URL после имени хоста (hostname) и номера порта и до строки запроса (т.е. к примеру «/app1/index.html»). Это (%-кодированный) URL-путь.

Путь до директории, где определено правило, отбрасывается из анализируемого запроса (вплоть до и включая конечный слэш). В конечном счёте, правилу для сравнения передаётся строка «ниже» папки, где определено правилов.

Подстановка RewriteRule

Подстановка правила перезаписи – это строка, которая заменяет оригинальный URL-путь, который совпал с Шаблоном. В качестве подстановки может быть:

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

Если указан абсолютный URL, mod_rewrite проверяет, совпадает ли имя хоста с текущим хостом. Если да, то схема и имя хоста отбрасываются и результирующий путь трактуется как URL-путь. В противном случае, выполняется внешний редирект (перенаправление) для заданного URL. Для принудительного внешнего редиректа на текущий хост (чтобы запрашиваемая страница поменяла адрес на другую страницу этого же хоста), смотрите флаг [R], описанный далее.

Чёрточка говорит о том, что не должна выполняться какая-либо подстановка (существующий путь должен быть пропущен нетронутым). Это используется когда нужно применить флаг (смотрите далее) без изменения пути.

В дополнении к простому тексту, строка Подстановки может включать:

Директива RewriteBase

Мы уже выяснили, что на совпадение проверяется только часть запроса – начиная от текущий папки и далее вложенные подпапки. Если Подстановкой, получившейся в результате перезаписи, является относительный путь, то чтобы найти этот ресурс, к полученному значению добавляется путь до текущей папки. Это является поведением по умолчанию, а директива RewriteBase позволяет изменить это поведение.

Директива RewriteBase определяет URL префикс, используемый для постановки перед относительным путём.

Обычно, эта директива не требуется. Но она нужна когда:

Логика работы mod_rewrite

Как вы уже начали понимать, модуль работает следующим образом: приходящий запрос сравнивается с каждым установленным веб-мастером правилом, если есть совпадение, то запрос меняется в соответствии со второй частью правила.

Это так, но это не всё. Если указано несколько правил RewriteRule и, допустим, в запросе найдено совпадение с первым правилом и исходная строка запроса изменена в соответствии с этим правилом. Второму правилу передаётся не исходная строка запроса, а новая строка, получившаяся в результате обработки всеми предыдущими правилами. И также происходит ниже по цепочке.

Проверку по всем правилам можно назвать проходом (раундом, циклом). Если в данном раунде случилось хотя бы одно совпадение (сработало правило), то после завершения прохода начинается ещё один круг проверки по этим же самым правилам! Это неочевидно и мало где об этом говориться – поэтому обратите на это особое внимание. Т.е. на новый раунд передаётся уже изменённая строка запроса и именно она проходит оценку по всем правилам. И вновь: если сработало хотя бы одно правило, идёт заход на новый круг и т.д.

Это является поведением по умолчанию для mod_rewrite. Это поведение можно изменить несколькими флагами, о которых будет рассказано далее.

Тестирование правил mod_rewrite

Для тестов, на вашем веб-сервере в папке сайтов создайте новую папку mr, к примеру, на Windows это может быть каталог C:\Server\data\htdocs\mr\, а на Linux это /var/www/html/mr/

Поскольку я работаю с локальным, сервером, то у меня теперь эта папка доступна по адресу http://localhost/mr

В этой папке создайте файл index.html следующего содержания:

И создайте пустой файл .htaccess

Источник

Как на самом деле работает mod_rewrite. Пособие для продолжающих

php mod rewrite как включить. Смотреть фото php mod rewrite как включить. Смотреть картинку php mod rewrite как включить. Картинка про php mod rewrite как включить. Фото php mod rewrite как включить
Эта статья выросла из идеи продвинутого обучения наших сотрудников технической поддержки работе с mod_rewrite. Практика показала, что после изучения имеющихся в большом количестве учебников на русском языке саппортам хорошо дается решение шаблонных задач, но вот самостоятельное составление правил происходит методом проб и большого количества ошибок. Проблема заключается в том, что для хорошего понимания работы mod_rewrite требуется изучение оригинальной англоязычной документации, после чего — либо дополнительные разъяснения, либо часы экспериментов с RewriteLog.

В статье изложен механизм работы mod_rewrite. Понимание принципов его работы позволяет четко осознавать действие каждой директивы и ясно представлять себе, что происходит в тот или иной момент внутри mod_rewrite при обработке директив.

Итак, вы изучили mod_rewrite, составили несколько RewriteRule и успели столкнуться с бесконечными перенаправлениями, со случаем, когда правило почему-то не ловит ваш запрос, а также с непредсказуемой работой группы правил, когда последующее правило неожиданно изменяет запрос, кропотливо подготовленный правилами предыдущими.

Почему так происходит?

С чем работает RewriteRule

php mod rewrite как включить. Смотреть фото php mod rewrite как включить. Смотреть картинку php mod rewrite как включить. Картинка про php mod rewrite как включить. Фото php mod rewrite как включить

С чем работает RewriteRule, мы разобрались. Теперь посмотрим, как он работает.

Как работает RewriteRule

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

# Запрос: http://mysite.com/info.html
# В первый RewriteRule попадет «info.html»

# Преобразовываем запрос в произвольную строку.
RewriteRule ^info.html$ «I saw a turtle in the hole. And it was dancing rock-n-roll. And it was smiling. All in all, it was a very funny doll.»

# Заменяем эту строку на внешнюю ссылку.
RewriteRule turtle https://example.com/information/index.html

# Заменяем протокол!
RewriteRule ^https:(.*)$ ftp:$1

Как видите, RewriteRule все равно, с чем работать — она просто преобразовывает строку в соответствии с заданными ей аргументами. Если хотите, можете в строке хранить любые массивы данных, при желании, настойчивости и хорошем знании регулярных выражений можете хоть крестики-нолики на RewriteRule написать.

Здесь нужно сделать замечание: хоть RewriteRule и работает с чистой строкой, она все-таки ориентирована на работу со ссылками. Поэтому она будет по-особому реагировать на строки, начинающиеся на «https://» или аналоги (запомнит, что мы хотели сделать внешний редирект) и на символ «?» (посчитает следующие символы аргументами, которые нужно будет подставить к запросу). Однако сейчас нас это не интересует — важно понять, что в RewriteRule нет никакой магии — она просто берет строку и изменяет ее так, как вы ей сказали. Внешние редиректы и аргументы мы рассмотрим позже в статье, там тоже есть, о чем поговорить.

После того как все преобразования произведены и выполнено последнее RewriteRule, вступает в силу RewriteBase.

Для чего нужен RewriteBase

RewriteBase выполняется после всех преобразований. Это значит, что он не будет изменять запрос между RewriteRule, а вступит в силу только когда все RewriteRule отработают.

php mod rewrite как включить. Смотреть фото php mod rewrite как включить. Смотреть картинку php mod rewrite как включить. Картинка про php mod rewrite как включить. Фото php mod rewrite как включить

# Получилось совсем не то, что имели в виду.

Итак, запрос прошел через все RewriteRule, после чего к нему, в случае необходимости, добавился RewriteBase. Должен ли теперь Apache отдать файл, на который показывает результирующий путь? Нет. Теперь получившийся запрос будет обрабатываться еще раз.

Как работает mod_rewrite. Флаг [L]

mod_rewrite запускает обработку запроса снова и снова, до тех пор, пока он не перестанет меняться. И флаг [L] не может это остановить.

— Постойте, но ведь есть флаг [L], который останавливает обработку запроса mod_rewrite’ом!

Не совсем так. Флаг [L] останавливает текущую итерацию обработки запроса. Однако если запрос был изменен теми RewriteRule, которые все-таки успели отработать, Apache запустит цикл обработки запроса заново с первого RewriteRule.

RewriteRule ^a.html$ b.html [L]
RewriteRule ^b.html$ a.html [L]

Пример выше приведет к бесконечному циклу перенаправлений и к «Internal Server Error» в итоге. В этом примере бесконечный цикл очевиден, однако в более сложных конфигурациях может потребоваться покопаться в правилах, чтобы определить, какие запросы зацикливаются между собой.

RewriteBase /
RewriteRule ^a.html$ b.html
RewriteRule ^b.html$ a.html

Как работает mod_rewrite. Флаг [R]

Флаг [R] не останавливает обработку запроса, возвращая сразу внешний редирект. Вместо этого он запоминает необходимость внешнего редиректа, и обработка запроса продолжается следующими RewriteRule. Рекомендуется всегда использовать с флагом [L].

Флаг [R] сообщает Apache, что нужно выполнить не внутренний, а внешний редирект. Чем отличается внешний редирект от внутреннего? Внутренний редирект просто изменяет путь до файла, который будет отдан пользователю, при этом пользователь считает, что получает тот файл, который он изначально запросил. При внешнем же редиректе Apache вместо содержимого файла возвращает пользователю статус ответа 301 или 302 и сообщает ссылку, по которой браузер должен обратиться для получения файла.

Казалось бы, при обработке флага [R] Apache должен сразу прекратить обработку RewriteRule и вернуть пользователю внешний редирект. Однако давайте вспомним фантастический пример из раздела «Как работает RewriteRule». В нем мы сначала указали флаг [R], обозначив необходимость внешнего редиректа, после чего продолжили изменять ссылку следующими RewriteRule.

Именно так и работает Apache при указании внешнего редиректа. Он просто «помечает» себе, что после выполнения всех правил необходимо вернуть статус 302 (по умолчанию), но при этом продолжает выполнение всех RewriteRule дальше по списку. Мы можем и дальше изменять запрос как нам нужно, единственное, что не получится — сделать редирект обратно внутренним.

Тем не менее, вряд ли вы хотите после отдачи внешнего редиректа каким-либо образом изменять его. Поэтому рекомендуется при употреблении флага [R] указывать его совместно с [L]:

# BlackJack переехал на красивое имя
RewriteRule ^bj/(.*) blackjack/$1 [R=301,L]

# Можно использовать просто внешнюю ссылку
RewriteRule ^bj/(.*) http://blackjack.example.com/$1 [L]

Как работает mod_rewrite. Указание параметров запроса и флаг [QSA]

Изменение параметров запроса в RewriteRule не изменяет строку, с которой работает следующий RewriteRule. Однако при изменении параметров изменяется переменная %, с которой может работать RewriteCond.

Используемая терминология: «параметры» — параметры запроса, «аргументы» — аргументы RewriteRule.

С помощью RewriteRule можно изменять не только путь до файла, который будет обрабатываться, но и параметры запроса GET, которые будут ему передаваться. Это часто используется для передачи обработки ЧПУ в общий скрипт-обработчик, например:

Мы добавили только флаг [QSA], и правило стало работать корректно.

— Конечно, изменяется, ведь запрос уходит на повторную обработку Apache’м!

Нет, % изменяется сразу же. Доказательство приводить не буду — про параметры и так уже написано больше, чем интересно читать 🙂

Что же делать, чтобы проверить в RewriteCond именно те параметры запроса, которые передал пользователь, а не модифицированные RewriteRule’ами? Смотрите советы в конце статьи.

RewriteCond и производительность

Сначала проверяется совпадение запроса с RewriteRule, а уже потом — дополнительные условия RewriteCond.

На самом деле все происходит наоборот. Сначала mod_rewrite проверяет, подходит ли текущее значение запроса под регулярное выражение RewriteRule, а уже потом будет проверять все условия, перечисленные в RewriteCond.

Так что если у вас в RewriteRule регулярное выражение на две страницы и вы, задумавшись о производительности, решили ограничить выполнение этого правила дополнительными RewriteCond, знайте — ничего не получится. В этом случае лучше использовать флаги RewriteRule [C] или [S], чтобы пропустить более сложное правило, если более простые проверки не сработали.

Переменные и флаги RewriteCond, остальные флаги RewriteRule и прочее

Мы познакомились с принципами работы RewriteRule, RewriteBase, флагов [L], [R] и [QSA], а также разобрали механизм обработки запросов внутри mod_rewrite. Из незатронутого остались: другие флаги RewriteRule, директивы RewriteCond и RewriteMap.

К счастью, эти директивы и флаги не таят в себе каких-либо загадок и работают именно так, как описано в большинстве учебников. Для их понимания достаточно почитать официальную документацию. В первую очередь рекомендую изучить список переменных, которые можно проверять в RewriteCond — %, %, %, %, % и т. д.)

В контексте mod_rewrite работает с точностью до наоборот.

Советы и решения

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

Составление регулярных выражений

Впрочем, о регулярных выражениях на одном известном сайте есть целый раздел.

Изменение внешних редиректов

Несмотря на то, что mod_rewrite позволяет изменять с помощью RewriteRule даже внешние редиректы, вплоть до протокола, я крайне не рекомендую делать это. В статье пример с изменением внешних редиректов используется только чтобы отвязаться от таких понятий как «ссылки» и «файлы» и более явно показать, что RewriteRule работает с простой строкой.

Не думаю, что разработчики mod_rewrite предполагали, что кто-то будет так делать, поэтому возможны всякие артефакты. Не делайте так, пожалуйста.

Как остановить бесконечный цикл

Иногда логика перенаправлений на сайте такова, что без специальных действий mod_rewrite воспринимает их как бесконечный цикл перенаправлений. Возьмем следующий пример.

На сайте была страница /info.html. Специалист по SEO решил, что поисковые системы будут лучше индексировать эту страницу, если она будет называться /information.html и попросил сделать внешний редирект с info.html на information.html. Однако разработчик сайта по каким-то своим соображениям не может просто переименовать info.html в information.html и сделать редирект — ему нужно, чтобы данные обязательно отдавались непосредственно из файла info.html. Он пишет следующее правило:

# сделать внешний редирект
RewriteRule ^info.html information.html [R,L]
# но по запросу /information.html все равно отдать info.html
RewriteRule ^information.html info.html

… и сталкивается с бесконечным циклом. Каждый запрос /information.html получает внешний редирект снова на /information.html.

Решить эту проблему можно как минимум двумя способами. На Хабре был уже описан один из них — нужно установить переменную окружения и на основании ее значения прекращать перенаправления. Код будет выглядеть следующим образом:

RewriteRule ^info.html$ information.html [R,L]
RewriteRule ^information.html$ info.html [E=FINISH:1]

Обратите внимание, что к имени переменной mod_rewrite добавляет ‘REDIRECT_’.

Второй способ — проверить в THE_REQUEST, что именно было запрошено пользователем:

RewriteRule ^information.html$ info.html

Анализ исходного запроса пользователя — борьба с раскрытием ссылок Apache

На хабре есть обсуждение одного из таких случаев, из него и был взят вышеприведенный пример.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *