Apache: алиасинг и редирект






Типичная ситуация: HTTP-клиент запрашивает с сервера контент, который либо не существует на данном сервере, либо располагается по другому URL.  Причин такому стечению обстоятельств может быть несколько. Вы, например, могли переместить контент в пределах сервера (а то и вообще за его пределы) или же вам понадобилось реорганизовать логическую структуру адресов вашего проекта. При обычных условиях запрос несуществующего контента приведёт к тому, что сервер сообщит об ошибке, однако в Apache имеется полезный модуль mod_alias, предоставляющий возможность создавать синонимы URL (aliasing — алиасинг), а также выполнять перенаправление клиентов на другой URL (redirect — редирект).

Aliasing and Redirection


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

При помощи алиасов вы также можете организовать доступ к файлам, находящимся за пределами Document Root сервера, таким образом предоставив прямой доступ к любой части ФС сервера, не прибегая к использованию CGI-сценариев. Используя редирект, вы получаете возможность физически перенаправлять клиентов на нужные URL.

Директива Alias

Директива Alias позволяет незаметно для клиентов связывать запрашиваемые URL с любой частью файловой системы сервера. Например:

Директива в примере выше приведёт к тому, что Apache перед тем, как выполнять поиск контента в файловой системе, в строке запроса заменит /images/ на /ftp/public/images/. Таким образом запрос URL http://www.example-domain.com/images/example-image.jpg заставит искать Apache файл example-image.jpg в физическом каталоге /ftp/public/images/ вместо каталога DOCUMENT_ROOT/images.

Обратите внимание на то, что завершающий слеш имеет значение. Приведённый выше пример не сработал бы, если б мы опустили завершающий слеш в первом параметре Alias. Также, алиасинг не сработал бы в случае, если бы клиент запросил URL, в котором после /images отсутствовал завершающий слеш.

Директива AliasMatch

Директива AliasMatch работает так же, как и Alias, при этом позволяя использовать регулярные выражения для определения исходных URL:

В этом примере показано, как мы можете легко связать относительную часть запрашиваемого URL с частью физической файловой системы. Переменная $1 связана с первым соответствием, обнаруженным в скобках регулярного выражения, $2 — со вторым, и так далее. Таким образом, в примере выше, запрос URL http://www.example-site.com/some_dir/images/img1.jpg приведёт к получению файла /ftp/public/images/img1.jpg. Используя эту директиву вы можете, например, хранить все изображения в одном дереве каталогов, независимо от относительного положения подстроки /images/  в строке запроса.

Существенной разницей между Alias и AliasMatch является их поведение. Разница заключается в том, что Alias копирует оставшуюся часть строки запроса после вычитания из неё первого параметра директивы, в то время как AliasMatch — нет. То есть:

совершенно не эквивалентна

поскольку вторая будет транслировать все запросы, содержащие подстроку /images/ к каталогу /ftp/public/images/, не добавляя при перезаписи имён файлов. Чтобы получить то, что нужно, вам понадобится следующая инструкция:

Директива ScriptAlias

Назначение этой директивы такое же, как и Alias, однако при этом Apache считает конечный каталог таким, который хранит исполняемые CGI-сценарии. То есть после трансляции запроса и определения конечного пути запрашиваемого файла, Apache попытается выполнить последний, как CGI-сценарий.

В приведённом примере запрос http://www.example-site.com/cgi-bin/some_cgi_script приведёт к выполнению сценария, расположенного в файле /usr/local/apache2/cgi-bin/some_cgi_script. Альтернативный вариант такой конфигурации можно можно описать следующим набором инструкций:

Директива ScriptAliasMatch

Данная директива аналогична предыдущей, однако умеет работать с регулярными выражениями, как и AliasMatch.

Директива Redirect

mod_alias ко всему прочему позволяет явно сообщать клиентам о том, что запрошенный ими URL является некорректным, сообщая другой URL, по которому можно отыскать требуемый контент. Для управления такими перенаправлениями используется директива Redirect.

Эта директива работает подобно Alias, только вместо того, чтобы выполнять перенаправление внутри сервера, она отправляет команду перенаправления клиенту. Опциональным параметром директивы является тип перенаправления, сообщаемый клиенту кодом HTTP-статуса ответа (об этом чуть ниже).

В приведённом примере запрос URL http://www.example-site.com/images/img1.gif приведёт к перенапрвлению на http://www.another-example-site.com/images/img1.gif.

Если запрашиваемый URL содержит query string, то она будет оставлена без изменений, только если это явно не определно последним параметром директивы Redirect.

Например, правило, рассмотренное выше, запрос URL http://www.example-site.com/images?img-name=1.gif перенаправит к http://www.another-example-site.com/images?img-name=1.gif. Однако, если мы перепишем правило следующим образом:

то тот же запрос будет перенаправлен на http://www.another-example-site.com/images?q=new-value.

Теперь о типах перенаправления. Для того, чтобы сообщить клиенту о необходимости перенаправления на другой URL, сервер использует HTTP статус-коды. При помощи директивы Redirect можно определить один из четырёх HTTP-кодов перенаправления (в скобках указано символическое имя, которое можно использовать вместо номера кода).

301 (permanent). Ресурс переехал на новый адрес. Клиенты и прокси-серверы должны обновить информацию в своих кешах (только если HTTP-заголовки Cache-Control и Expires не препятствуют этому) и в будущем всегда использовать новый адрес ресурса.

302 (temp). Адрес ресурса временно изменён. Клиенты и прокси-серверы НЕ должны обновлять информацию в своём кеше и в будущем всегда проверять предыдущий адрес ресурса, прежде чем выполнять перенаправление (только если HTTP-заголовки Cache-Control и Expires не препятствуют этому).

303 (seeother). Ресурс был замещён другим ресурсом и клиент должен выполнить перенаправление, используя метод GET, независимо от того, какой метод использовался для запроса оригинального ресурса.

410 (gone). Ресурс был удалён и более недоступен.

Если статус-аргумент будет опущен, то по умолчанию будет использоваться 302-редирект. На самом деле вы можете использовать любой HTTP-статус, а не только четыре из представленных выше. Помните только, что если вы используете HTTP-статус, не попадающий в диапазон 300-399, последний аргумент директивы должен быть опущен.

Директива RedirectMatch

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

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

Так же, как и предыдущая директва, RedirectMatch принимает опциональный параметр HTTP статус-кода. В примере выше он не указан, и поэтому будет использоваться код 302.

Также, в семействе Redirect* есть ещё две директивы: RedirectPermanent и RedirectTemp, которые семантически эквиваленты выражениям Redirect permanent и Redirect temp соответственно.

Порядок обработки директив

Если вы не хотите получить неожиданного поведения сервера при работе с редиректом и алиасингом, вы должны знать о том, что инструкции редиректа обрабатываются перед инструкциями алиасинга, если они были одновременно обнаружены в одном и том же контексте (например в пределах оного и того же контейнера <Directory> или <Location>).

Когда сервер получает запрос, подходящий под условие Redirect или RedirectMatch, то инструкции этих директив будут обработаны прежде, чем инструкции директив Alias и AliasMatch. Это означает то, что в подобных ситуациях директивы Alias* никогда не будут срабатывать, поскольку будет выпоняться редирект.

Второй момент, о котором всегда всегда помнить, это то, что директивы Alias* и Redirect* применяются в том порядке, в котором они появляются. По этой причине зачастую более разумно определять более общие правила в последнюю очередь. Например инструкции:

НЕ будут работать так же, как и:

поскольку Alias /sub-dir1 /dir4 будет срабатывать всегда до того, как дойдёт очередь до Alias /sub-dir1/sub-dir2 /dir3.

Источник




Apache: алиасинг и редирект: 4 комментария

  1. Полезная и хорошо разжеванная статья. Помню когда пытался настроить апач и читал документацию не всегда понятны были смысл директив или их различия. Спасибо!

Комментарии запрещены.