Apache将URL映射到文件系统位置
本文将介绍Apache HTTP Server如何使用请求的URL来确定从中提供文件的文件系统位置。
DocumentRoot
在决定为给定请求提供什么文件时,httpd的默认行为是获取请求的URL-Path(主机名和端口后面的URL部分),并将其添加到配置文件中指定的DocumentRoot
的末尾。因此,DocumentRoot
下面的文件和目录构成了可从Web上看到的基本文档树。
例如,如果DocumentRoot
设置为/var/www/html
时,则对http://www.example.com/fish/guppies.html
的请求会将文件/var/www/html/fish/guppies.html
发送到请求客户。
如果请求目录(即以/结尾的路径),则从该目录提供的文件由DirectoryIndex
指令定义。例如,如果DocumentRoot
设置为/var/www/html/
,则要设置:
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之外的文件
通常情况下,必须允许Web访问文件系统中严格不在DocumentRoot
下的部分。httpd提供了几种不同的方法来实现这一目标。在Unix系统上,符号链接可以将文件系统的其他部分带到DocumentRoot
下。出于安全原因,仅当相关目录的Options
设置包括FollowSymLinks
或SymLinksIfOwnerMatch
时,httpd才会遵循符号链接。
或者,Alias指令将文件系统的任何部分映射到Web空间。例如,
Alias "/docs" "/var/web"
网址 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访问每个用户主目录下的文件,将此想法扩展到Web。
http://www.example.com/~user/file.html
出于安全原因,从Web直接访问用户的主目录是不合适的。因此,UserDir
指令指定用户主目录下Web目录所在的目录。使用Userdir public_html
的默认设置,上面的URL映射到/home/user/public_html/file.html
等目录中的文件,其中/home/user/
是/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
指令实现。例如,如果DocumentRoot
下目录/foo/
的内容被移动到新目录/bar/
,可以指示客户端在新位置请求内容,如下所示:
Redirect permanent "/foo/" "http://www.example.com/bar/"
这会将从/foo/
开始的任何URL-Path重定向到www.example.com
服务器上的相同URL路径,其中/bar/
替换为/foo/
。可以将客户端重定向到任何服务器,而不仅仅是原始服务器。
httpd还提供了RedirectMatch
指令,用于更复杂的重写问题。例如,要将站点主页的请求重定向到其他站点,但仅保留所有其他请求,请使用以下配置:
RedirectMatch permanent "^/$" "http://www.example.com/startpage.html"
或者,要临时将一个站点上的所有页面重定向到另一个站点上的特定页面,请使用以下命令:
RedirectMatch temp ".*" "http://othersite.example.com/startpage.html"
反向代理
httpd还允许将远程文档带入本地服务器的URL空间。此技术称为反向代理,因为Web服务器通过从远程服务器获取文档并将其返回到客户端来充当代理服务器。它与正常(转发)代理不同,因为对于客户端,文档似乎来自反向代理服务器。
在以下示例中,当客户端请求/foo/
目录下的页面文档时,服务器从internal.example.com
上的/bar/
目录中获取这些文档,并将它们返回给客户端,就像它们来自本地服务器一样。
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
在页面中修改这些链接(以及其他内容)。
Substitute "s/internal\.example\.com/www.example.com/i"
对于HTML和XHTML中链接的更复杂重写,mod_proxy_html
模块也可用。它允许创建需要重写的URL映射,以便可以处理复杂的代理方案。
重写引擎
当需要更强大的替换时,mod_rewrite
提供的重写引擎可能很有用。该模块提供的指令可以使用请求的特征(例如浏览器类型或源IP地址)来决定从哪里提供内容。此外,mod_rewrite
可以使用外部数据库文件或程序来确定如何处理请求。重写引擎能够执行上面讨论的所有三种类型的映射:内部重定向(别名),外部重定向和代理。
文件未找到
不可避免地请求有时也会在文件系统中找不到匹配文件的URL。这可能由于几个原因而发生。在某些情况下,它可能是将文档从一个位置移动到另一个位置的结果。在这种情况下,最好使用URL重定向来通知客户端资源的新位置。通过这种方式,即使资源位于新位置,您也可以确保旧书签和链接继续有效。
“找不到文件”错误的另一个常见原因是URL的直接错误输入,无论是直接在浏览器中还是在HTML链接中。httpd提供模块mod_speling(sic)
来帮助解决这个问题。激活此模块时,它将拦截“找不到文件”错误并查找具有类似文件名的资源。如果找到一个这样的文件,mod_speling
将向客户端发送HTTP重定向,通知它正确的位置。如果找到几个“关闭”文件,将向客户提供可用备选列表。
mod_speling
的一个特别有用的功能是,它将比较文件名而不考虑大小写。这可以帮助用户不了解URL和unix文件系统的区分大小写特性的系统。但是,除了偶尔的URL更正之外,使用mod_speling
可以在服务器上增加额外负载,因为每个“不正确”的请求后面都有URL重定向和来自客户端的新请求。
mod_dir
提供FallbackResource
,可用于将虚拟URI映射到真实资源,然后为其提供服务。在实现’前端控制器’时,这是对mod_rewrite
非常有用的替代品
如果查找内容的所有尝试都失败,httpd将返回一个错误页面,其中包含HTTP状态代码404(找不到文件)。此页面的外观由ErrorDocument
指令控制,可以按照自定义错误响应文档中的讨论以灵活的方式进行自定义。