正如你所说的B 在这种情况下需要标记。但这应该是[B,L], 不[BNC] 正如你多次引用的那样?
不知道你从哪里得到的[BNC] 来自,但这是完全无效的,并且会破坏Apache服务器(500内部服务器错误响应)。如果使用此无效标志未看到错误,那么您可能位于LiteSpeed服务器上,该服务器会悄悄忽略错误,并且指令不会运行,从而允许对文件进行无限制的访问(这似乎就是您在此处看到的)。
这个B 需要标记才能对& (作为%26) 在将其传递给查询字符串之前,从请求的解码URL捕获,以便传递整个;“文件名”;而不仅仅是&.
例如,如果您请求/wp-content/uploads/abc%26def.pdf 并且不要使用B 标志,则生成的请求将是:
checkloggedin.php?file=abc&def
这实际上是两个URL参数:
file=abc 和
def=使用B 标志,捕获的反向引用将重新编码,并变为:
checkloggedin.php?file=abc%26def
PHP/WordPress然后将其解码为
abc&def - 完整的文件名。
因此,完整的规则应该是:
RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*) checkloggedin.php?file=$1 [B,L]
The
QSA 标志不是必需的,除非您在初始文件请求中传递其他查询字符串参数?尾部
$ 在
RewriteRule 模式也不是必需的,因为默认情况下regex是贪婪的。如果这仍然不起作用,则问题在于checkloggedin.php 剧本但从您所说的来看,在使用BNC - 这就是为什么我认为您使用的是LiteSpeed服务器(不是Apache)。
<小时/>
UPDATE:
另一种方法是将文件名作为路径信息传递,而不是作为查询字符串中的URL参数传递。这样,您就不容易出现与& (这不是URL路径中的特殊字符)。因此,在.htaccess:
RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*) checkloggedin.php/$1 [L]
TheB 不需要标记。匹配的URL路径RewriteRule 模式已经%解码(因此原始请求是否包含& 或%26). “相同”;“文件”;值作为路径信息(其他路径名信息)传递,因此可通过$_SERVER[\'PATH_INFO\'] 超全局,而不是$_GET[\'file\'].
因此,在脚本中,您需要执行以下操作来填充$filename 变量:
$filename = isset($_SERVER[\'PATH_INFO\']) ? $_SERVER[\'PATH_INFO\'] : null;