Apache:提供受限制文件中的内容

Apache:提供受限制文件中的内容

在我的 Apache 设置中,我有一个包含错误页面的目录(404 403)。但是,我不希望直接查看此目录 - 我希望访问它以返回 404。所以我做了以下事情:

# Use /hidden/404/ as the 404 page
ErrorDocument 404 /hidden/404/
# Use /hidden/403/ as the 403 page
ErrorDocument 403 /hidden/403/
<Directory /path/to/root/hidden/>
    # All requests return 404
    RedirectMatch 404 .*
</Directory>

问题是 Apache 似乎不愿意提供以下文件:全部在这种情况下,即使我明确告诉它(即处理 404 和 403 错误),它也会出错。事实上,当我访问 时/hidden,我收到以下消息:

The requested URL /hidden/404/ was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an 
ErrorDocument to handle the request.

有什么方法可以告诉 Apache 不允许访问该目录,但在必要时仍允许其提供这些文件?

答案1

好的,我找到一种方法来做到这一点。

我所做的是使用mod_rewrite,这是一个 Apache 模块(默认情况下随所有安装一起提供),用于动态重写请求的 URL。以下是代码:

# Custom error pages
ErrorDocument 404 /hidden/404/index.html
ErrorDocument 403 /hidden/403/index.html

# Pretend that /hidden doesn't exist
# (unless this is an internal redirect,
# such as rendering a 404 or 403)
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^/hidden/.* - [L,R=404]

让我们来看看这些代码。ErrorDocument指令没有改变 - 它们只是说明当发生给定错误时应该提供哪个页面。

真正的重点在于RewriteCondandRewriteRule指令。RewriteRule指令的内容如下:如果请求的 URL 路径与正则表达式匹配^/hidden/.*(本质上,任何路径都指向 /hidden/ 或其子树中的任何内容),则保留 URL 不变(这就是 的意思-),但不再解释任何RewriteRule指令(这就是 的意思L),并返回 404 错误代码(这就是 的意思R=404)。

这与ErrorDocument 404 /hidden/404/index.html指令相结合,似乎可以解决问题。但问题是,当 Apache 开始服务时/hidden/404/index.html,它会再次运行这些规则。这意味着RewriteRule指令被执行,指令又要求呈现 404,整个过程只是无限循环。

因此,我们使用RewriteCond指令来确保这种情况不会发生。RewriteCond指令是条件性的 -RewriteRule下面的指令只有在条件满足时才会执行。在这种情况下,条件是“环境变量REDIRECT_STATUS等于空字符串”。现在,REDIRECT_STATUS是一个由设置的环境变量ErrorDocument,并保存正在重定向的状态代码(因此,如果ErrorDocument 404 ...触发了指令,它将被设置为值“404”)。但是,如果没有ErrorDocument执行任何指令,则REDIRECT_STATUS不会设置,因此请求其值只会返回空字符串。因此,本质上说,“除非我们没有在提供错误页面,否则RewriteCond %{ENV:REDIRECT_STATUS} =""不要费心评估下面的指令。”RewriteRule


笔记:如果您查看了RewriteRule文档,您可能已经注意到该R参数应该执行显式重定向。它在本例中工作正常的原因是该R参数有一个未记录的功能,即它仅在 300 类代码上重定向。因此,R=404不执行显式重定向,只执行内部重定向。

相关内容