正如你所说的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;