除非请求实际上是子请求,否则拒绝所有人

时间:2015-02-10 21:12:43

标签: php .htaccess

我使用PHP的virtual()函数对Apache执行子请求,以便启动文件下载(文件可能很重,所以我无法使用readfile())。有问题的文件存储在非公共目录中,因为在允许下载之前需要检查用户的权限。

我的项目结构如下:

project/
    .htaccess     -----> rewrite everything to index.php
    index.php     -----> framework + application logic + permissions check
    private/
        .htaccess -----> deny from all
        ...       -----> private files

我遇到的第一个问题是virtual()生成的子请求被第一个.htaccess重写,因此下载永远不会开始。这很容易修复,因为有一个[NS] (no sub-request)重写标志,在这种情况下不允许重写URL:

...
RewriteRule ^ index.php [NS]
...

但我仍然无法使其工作,因为另一个.htaccess(拒绝所有人),它只是拒绝所有请求和子请求。

问题:有没有办法配置.htaccess拒绝来自所有人的访问,除非请求实际上是来自服务器本身的子请求?

1 个答案:

答案 0 :(得分:1)

首先,一个非常有趣的问题。不得不挖掘一下才弄明白。

您可以在此处使用 apache_setenv 功能。

virtual之前调用此PHP代码:

apache_setenv('internal', '1');  // sets an Apache var with name internal
virtual ( "/private/file.txt" ); // example sub request
exit;

现在/private/.htaccess里面有这个片段:

Order deny,allow
Deny from  all
Allow from env=internal

这将拒绝所有请求,除非env变量internal设置为1。该内部变量仅在您的PHP代码中设置,因此只允许子请求而所有其他请求都将被拒绝。