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

时间:2014-08-07 08:47:53

标签: apache configuration http-status-code-404 http-status-code-403 access-control

在我的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似乎不愿意在 all 中提供文件,即使我明确告诉它(即处理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 个答案:

答案 0 :(得分:0)

好的,我想出了办法。

我所做的是使用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指令没有改变 - 它们只是说出发生给定错误时应该提供哪个页面。

真正的肉类在RewriteCondRewriteRule指令中。 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指令只有在条件满足时才会执行。在这种情况下的条件是&#34;环境变量REDIRECT_STATUS等于空字符串。&#34;现在,REDIRECT_STATUS是由ErrorDocument设置的环境变量,并保存正在重定向的状态代码(因此,如果ErrorDocument 404 ...指令已被触发,则将其设置为价值&#34; 404&#34;)。但是,如果没有执行ErrorDocument指令,则不会设置REDIRECT_STATUS,因此询问其值只会返回空字符串。因此,RewriteCond %{ENV:REDIRECT_STATUS} =""基本上表示,&#34;不要在下面评估RewriteRule指令,除非我们不在提供错误页面。&#34; < / p>


注意:如果查看了RewriteRule文档,您可能已经注意到R参数应该执行显式重定向。它在这种情况下正常工作的原因是R参数的未记录特征是它只重定向300类代码。因此,R=404不会执行显式重定向,只会执行内部重定向。