Пункт 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
- Выбирает соответствующий документ на основе предпочтений клиента, таких как язык или сжатие содержимого.