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

Статьи

Модуль mod_rewrite. Часть 2

В прошлой главе мы познакомились с основами модуля mod_rewrite. В примере, который был рассмотрен, мы использовали конструкцию, которая в буквальном смысле означает следующее: "Если кто-то пытается получить доступ к файлу .htaccess, выдается ошибка, сообщающая, что доступ к файлу запрещен".

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

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

Синтаксис: условие должно предшествовать правилу!

Возьмем еще один пример (запись в файле .htaccess):

RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon
RewriteRule ^.*$ - [F]

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

Последние две строки запрещают доступ поисковому роботу под кодовым названием "EmailSiphon"(имеется ввиду имя юзер-агента). Данный робот является сборщиком почтовых адресов с различных веб страниц.

Строка:

RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon

состоит из трех частей:

  • Директива (указание): RewriteCond
  • Проверочная строка: %{HTTP_USER_AGENT}
  • Образец условия: ^EmailSiphon

Проверочная строка — переменная сервера, которая может быть записана в общей форме: "%{ИМЯ_ПЕРЕМЕННОЙ}".

Образец условия — регулярное выражение. Для более полного понимания темы стоит рассмотреть регулярные выражения как класс.

Регулярные выражения

Регулярные выражения — это механизм, позволяющий задать шаблон для строки и осуществить поиск данных, соответствующих этому шаблону в заданном тексте. Кроме того, дополнительные функции по работе с такими выражениями позволяют получить найденные данные в виде массива строк, произвести замену в тексте по шаблону, разбиение строки по шаблону и т.п. Однако главной их функцией, на которой основаны все остальные, является именно функция поиска в тексте данных, соответствующих шаблону (образцу), описанному в синтаксисе регулярных выражений.

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

Например, регулярное выражение:

s/abc/xyz/g

заменит строку "abc", на строку "xyz" во всем тексте.

Вот краткий обзор наиболее важных элементов с некоторыми примерами:

  • . (точка) - текст (любой символ)
  • | - чередование (то есть/abc|def/)
  • * - квантификатор (разрешено любое число)
  • ^ $ - якоря строки
  • s - оператор (string1 заменить на string2)
  • g - модификатор (искать по всему тексту)

Регулярные выражения конструируются с помощью этих элементов и других "обычных" символов. Они не являются отдельным языком, а используются другими средствами, например языками программирования типа Perl или PHP, а также текстовыми редакторами (Emacs).

Если говорить о связи регулярных выражений и модуля mod_rewrite, то они используются в директивах RewriteRule и RewriteCond.

"^" обозначает начало строки. Из этого следует, что UserAgent должен начинаться со строки "EmailSiphon" и ни с чего другого ("NewEmailSiphon", например, не работал бы).

Но, поскольку данное регулярное выражение не содержит символ "$" (якорь конца строки), UserAgent мог бы быть, например, "EmailSiphon2".

Последняя строка нашего примера:

RewriteRule ^.*$ - [F]

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

Регулярное выражение "^.*$" означает: "Доступ ко всем файлам запрещен".

Точка "." в регулярном выражении – мета символ (подстановочный знак), означающий любой случайный символ.

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

"EmailSiphon", конечно, не единственный почтовый сборщик. Другой известный член этого семейства - "ExtractorPro". Допустим мы хотим запретить доступ и этому роботу. В таком случае нам необходимо еще одно условие.

Теперь файл .htaccess будет выглядеть так:

RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro
RewriteRule ^.*$ - [F]

Третий аргумент [OR] (в первой строке RewriteCond) называется "флагом". Существуют два возможных флага:

  • NC — не учитывать регистр букв.
  • OR — означает "или следующее условие".

Флажок NC позволяет игнорировать регистр букв в искомом образце. Например:

RewriteCond %{HTTP_USER_AGENT} ^emailsiphon [NC]

Эта строка определяет, что и "emailsiphon" и "EmailSiphon" будут признаны как идентичные выражения.

Вы можете использовать сразу несколько флажков, разделяя их запятыми.

RewriteCond % {HTTP_USER_AGENT} ^EmailSiphon [NC, OR] 
RewriteCond % {HTTP_USER_AGENT} ^ExtractorPro 

Нет никаких ограничений по числу условий. Таким образом, Вы можете блокировать 10, 100, 1000 или более известных почтовых сборщиков. Определение этих 1000 условий — просто вопрос загрузки сервера и прозрачности файла .htaccess.

В вышеупомянутом примере используется глобальная переменная HTTP_USER_AGENT. Существуют также другие переменные:

REMOTE_HOST
REMOTE_ADDR

Например, если Вы хотите заблокировать паука пришедшего с www.site.ru, Вы можете использовать глобальную переменную REMOTE_HOST таким образом:

RewriteCond % {REMOTE_HOST} ^www.site.ru$ 
RewriteRule ^.*$ - [F]

Если Вы хотите заблокировать определенный IP адрес, условие будет выглядеть так:

RewriteCond % {REMOTE_ADDR} ^212.37.64.10$ 
RewriteRule ^.*$ - [F]

В регулярном выражении по проверке точного и полного IP адреса нужно использовать начальные и конечные якоря.

Также можно исключить целый диапазон:

RewriteCond %{REMOTE_ADDR} ^212.37.64.
RewriteRule ^.*$ - [F]

Этот пример показывает, как можно заблокировать диапазон IP адресов с 212.37.64.0 по 212.37.64.255.

А вот маленькая задачка для проверки приобретенных знаний (решение будет дано в следующей части):

RewriteCond %{REMOTE_ADDR} ^212.37.64
RewriteRule ^.*$ - [F]

Внимание, вопрос!

Если мы пишем в регулярном выражении "^212.37.64" вместо "^212.37.64." (с точкой в конце), то даст ли это тот же самый эффект, и будут ли исключены те же самые IP адреса?

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