Пункт 14. Сопоставление URL-адресов с местоположениями файловой системы
В этом документе объясняется, как HTTP-сервер Apache использует URL-адрес запроса для определения местоположения в файловой системе, из которого следует обслуживать файл.
Связанные модули и директивы
DocumentRoot
При принятии решения о том, какой файл обслуживать для данного запроса, поведение httpd по умолчанию заключается в том, чтобы взять URL-путь для запроса (часть URL-адреса, следующая за именем хоста и портом) и добавить его в конец, указанный в ваших файлах конфигурации DocumentRoot . Таким образом, файлы и каталоги под ним DocumentRoot
составляют базовое дерево документов, которое будет видно из Интернета.
Например, если DocumentRoot
установлено значение , /var/www/html то запрос
http://www.example.com/fish/guppies.html приведет к тому, что файл /var/www/html/fish/guppies.html будет доставлен запрашивающему клиенту.
Если запрашивается каталог (т. е. путь, оканчивающийся на
/ ), файл, обслуживаемый из этого каталога, определяется директивой DirectoryIndex . Например, если DocumentRoot бы были установлены, как указано выше, и вы должны были установить:
DirectoryIndex index.html index.php
Затем запрос http://www.example.com/fish/ заставит httpd попытаться обслужить файл
/var/www/html/fish/index.html . Если этот файл не существует, в следующий раз он попытается обслужить файл
/var/www/html/fish/index.php .
Если ни один из этих файлов не существует, следующим шагом будет попытка предоставить индекс каталога, если
mod_autoindex он загружен и настроен для разрешения этого.
httpd также поддерживает виртуальный хостинг, когда сервер получает запросы для более чем одного хоста. В этом случае для каждого виртуального хоста может быть указано другое DocumentRoot , или, альтернативно, директивы, предоставляемые модулем, mod_vhost_alias могут использоваться для динамического определения подходящего места для обслуживания контента на основе запрошенного IP-адреса или имени хоста.
Директива DocumentRoot задается в файле конфигурации вашего основного сервера ( apache2.conf ) и, возможно, один раз для каждого дополнительного виртуального хоста, который вы создаете.
Файлы за пределами DocumentRoot
Часто бывают ситуации, когда необходимо разрешить веб-доступ к частям файловой системы, которые не находятся строго под расширением DocumentRoot . httpd предлагает несколько различных способов сделать это. В системах Unix символические ссылки могут помещать другие части файловой системы под расширение DocumentRoot . Из соображений безопасности httpd будет переходить по символическим ссылкам только в том случае, если Options параметр для соответствующего каталога включает FollowSymLinks или
SymLinksIfOwnerMatch .
В качестве альтернативы Alias директива отобразит любую часть файловой системы в веб-пространство. Например, с
Псевдоним "/docs" "/var/web"
URL-адрес http://www.example.com/docs/dir/file.html
будет обслуживаться из /var/web/dir/file.html . Директива
ScriptAlias работает таким же образом, с дополнительным эффектом, заключающимся в том, что все содержимое, расположенное по целевому пути, рассматривается как сценарии CGI .
В ситуациях, когда вам требуется дополнительная гибкость, вы можете использовать директивы AliasMatch
и ScriptAliasMatch
для выполнения мощного сопоставления и замены на основе регулярных выражений . Например,
ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)" "/home/$1/cgi-bin/$2"
сопоставит запрос с
http://example.com/~user/cgi-bin/script.cgi путем /home/user/cgi-bin/script.cgi и будет рассматривать полученный файл как сценарий CGI.
Каталоги пользователей
Традиционно в системах Unix домашний каталог конкретного пользователя может называться
~user/ . Модуль mod_userdir
распространяет эту идею на Интернет, позволяя получать доступ к файлам в домашнем каталоге каждого пользователя с помощью URL-адресов, таких как следующие.
http://www.example.com/~user/file.html
По соображениям безопасности нецелесообразно предоставлять прямой доступ к домашнему каталогу пользователя из Интернета. Следовательно,
UserDir директива указывает каталог под домашним каталогом пользователя, где расположены веб-файлы. Используя значение по умолчанию
Userdir public_html , приведенный выше URL-адрес сопоставляется с файлом в каталоге, например,
/home/user/public_html/file.html где
/home/user/ находится домашний каталог пользователя, как указано в /etc/passwd .
Есть также несколько других форм директивы
Userdir , которые вы можете использовать в системах, где /etc/passwd не указано местоположение домашнего каталога.
Некоторые люди считают символ «~» (который часто кодируется в Интернете как %7e ) неудобным и предпочитают использовать альтернативную строку для представления пользовательских каталогов. Эта функциональность не поддерживается mod_userdir. Однако если домашние каталоги пользователей структурированы обычным образом, то можно использовать директиву AliasMatch
для достижения желаемого эффекта. Например, чтобы создать
http://www.example.com/upages/user/file.html карту для
/home/user/public_html/file.html , используйте следующую
AliasMatch директиву:
AliasMatch "^/upages/([a-zA-Z0-9]+)(/(.*))?$" "/home/$1/public_html/$3"
URL-адрес перенаправления
Директивы конфигурации, рассмотренные в предыдущих разделах, сообщают httpd, что нужно получить содержимое из определенного места в файловой системе и вернуть его клиенту. Иногда вместо этого желательно сообщить клиенту, что запрошенный контент находится по другому URL-адресу, и указать клиенту сделать новый запрос с новым URL-адресом. Это называется перенаправлением и реализуется директивой Redirect . Например, если содержимое каталога /foo/ перемещается
DocumentRoot в новый каталог /bar/ , вы можете указать клиентам запрашивать содержимое в новом местоположении следующим образом:
Постоянная переадресация "/foo/" "http://www.example.com/bar/"
Это перенаправит любой URL-путь, начинающийся с
/foo/ того же URL-пути на
www.example.com сервере с /bar/
заменой /foo/ . Вы можете перенаправить клиентов на любой сервер, а не только на исходный сервер.
httpd также предоставляет RedirectMatch директиву для более сложных проблем перезаписи. Например, чтобы перенаправить запросы на домашнюю страницу сайта на другой сайт, но оставить все остальные запросы в покое, используйте следующую конфигурацию:
Постоянный RedirectMatch "^/$" "http://www.example.com/startpage.html"
В качестве альтернативы, чтобы временно перенаправить все страницы одного сайта на определенную страницу другого сайта, используйте следующее:
RedirectMatch temp ".*" "http://othersite.example.com/startpage.html"
Обратный прокси
httpd также позволяет переносить удаленные документы в пространство URL-адресов локального сервера. Этот метод называется обратным проксированием, поскольку веб-сервер действует как прокси-сервер, извлекая документы с удаленного сервера и возвращая их клиенту. Он отличается от обычного (прямого) проксирования тем, что клиенту кажется, что документы исходят от обратного прокси-сервера.
В следующем примере, когда клиенты запрашивают документы в каталоге
/foo/ , сервер извлекает эти документы из /bar/ каталога internal.example.com
и возвращает их клиенту, как если бы они были с локального сервера.
ProxyPass "/foo/" "http://internal.example.com/bar/"
ProxyPassReverse "/foo/" "http://internal.example.com/bar/"
ProxyPassReverseCookieDomain internal.example.com public.example.com
ProxyPassReverseCookiePath "/foo/" "/bar/"
Настраивает ProxyPass сервер для извлечения соответствующих документов, в то время как
ProxyPassReverse
директива переписывает исходящие перенаправления
internal.example.com таким образом, чтобы они были нацелены на соответствующий каталог на локальном сервере. Точно так же
ProxyPassReverseCookieDomain
и ProxyPassReverseCookiePath
переписать файлы cookie, установленные внутренним сервером.
Однако важно отметить, что ссылки внутри документов не будут перезаписаны. Таким образом, любые абсолютные ссылки internal.example.com приведут к тому, что клиент вырвется из прокси-сервера и запросит напрямую из
internal.example.com . Вы можете изменить эти ссылки (и другой контент) на странице, когда она передается клиенту с помощью
mod_substitute .
Замените "s/internal\.example\.com/www.example.com/i"
Для более сложной перезаписи ссылок в HTML и XHTML
mod_proxy_html также доступен модуль. Это позволяет вам создавать карты URL-адресов, которые необходимо переписать, чтобы можно было обрабатывать сложные сценарии проксирования.
Переписывая движок
mod_rewrite
Когда требуется еще более мощная замена, может быть полезен механизм перезаписи, предоставляемый . Директивы, предоставляемые этим модулем, могут использовать характеристики запроса, такие как тип браузера или исходный IP-адрес, при принятии решения о том, откуда обслуживать контент. Кроме того, mod_rewrite может использовать файлы или программы внешней базы данных, чтобы определить, как обрабатывать запрос. Механизм перезаписи способен выполнять все три типа отображений, описанных выше: внутренние перенаправления (псевдонимы), внешние перенаправления и проксирование. Многие практические примеры использования mod_rewrite обсуждаются в подробной документации по mod_rewrite.
Файл не найден
Неизбежно будут запрошены URL-адреса, для которых в файловой системе не может быть найден соответствующий файл. Это может произойти по нескольким причинам. В некоторых случаях это может быть результатом перемещения документов из одного места в другое. В этом случае лучше всего использовать перенаправление URL-адресов, чтобы информировать клиентов о новом местоположении ресурса. Таким образом, вы можете быть уверены, что старые закладки и ссылки будут продолжать работать, даже если ресурс находится в новом месте.
Другой распространенной причиной ошибки «Файл не найден» является случайный неверный ввод URL-адресов либо непосредственно в браузере, либо в ссылках HTML. httpd предоставляет модуль
mod_speling (sic), помогающий решить эту проблему. Когда этот модуль активирован, он будет перехватывать ошибки «Файл не найден» и искать ресурс с похожим именем файла. Если один такой файл будет найден, mod_speling отправит клиенту HTTP-перенаправление, информируя его о правильном местоположении. При обнаружении нескольких «закрытых» файлов клиенту будет представлен список доступных альтернатив.
Особенно полезной функцией mod_speling является то, что он сравнивает имена файлов без учета регистра. Это может помочь системам, в которых пользователи не знают о чувствительном к регистру характере URL-адресов и файловой системе unix. Но использование mod_speling для чего-то большего, чем случайное исправление URL-адреса, может создать дополнительную нагрузку на сервер, поскольку за каждым «неправильным» запросом следует перенаправление URL-адреса и новый запрос от клиента.
mod_dir Предоставляет FallbackResource , который можно использовать для сопоставления виртуальных URI с реальным ресурсом, который затем их обслуживает. Это очень полезная замена mod_rewrite при реализации «фронт-контроллера».
Если все попытки найти содержимое не увенчались успехом, httpd возвращает страницу ошибки с кодом состояния HTTP 404 (файл не найден). Внешний вид этой страницы управляется директивой
ErrorDocument и может гибко настраиваться, как описано в документе Пользовательские ответы на ошибки.
Другие модули сопоставления URL
Другие модули, доступные для сопоставления URL, включают:
-
mod_actions - Сопоставляет запрос со сценарием CGI на основе метода запроса или типа MIME ресурса.
-
mod_dir - Обеспечивает базовое отображение косой черты в конце индексного файла, такого как index.html .
-
mod_imagemap - Сопоставляет запрос с URL-адресом в зависимости от того, где пользователь щелкает изображение, встроенное в HTML-документ.
-
mod_negotiation - Выбирает соответствующий документ на основе предпочтений клиента, таких как язык или сжатие содержимого.