重写规则无法匹配单引号字符

时间:2010-01-19 21:37:27

标签: mod-rewrite

我之前问了这个问题:

mod_rewrite: match only if no previous rules have matched?

现在已成功使用建议的解决方案一段时间了:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^.+\ (/[^?\s]*)\??([^\s]*)
RewriteCond %{REQUEST_URI}?%{QUERY_STRING}<%1?%2 ^([^<]*)<\1$
RewriteRule .* /pub/dispatch.php [L]

但是,我们发现此规则对包含单引号字符的网址失败,例如http://example.com/don't_do_it(实际上请求为http://example.com/don%27t_do_it

具体来说,这是无法匹配的行:

RewriteCond %{REQUEST_URI}?%{QUERY_STRING}<%1?%2 ^([^<]*)<\1$

将其注释掉会导致规则按预期匹配,但只有在没有先前规则匹配的情况下才会中断“匹配”行为。这可能与'被urlencoded到%27的事实有关。

这是相关的RewriteLog条目(对于网址/asdf'asdf又名/asdf%27asdf):

 RewriteCond: input='/asdf'asdf?</asdf%27asdf?' pattern='^([^<]*)<\1$' => not-matched

我在这里看到的是%{REQUEST_URI}未转义而%{QUERY_STRING}被转义,因此不匹配。是否有其他任何一种我应该使用的替代方案?

有关如何重写上述行的任何想法,以便它也会匹配包含'个字符的行吗?

3 个答案:

答案 0 :(得分:0)

尝试C flag并链接您想要应用的规则序列。所以实际上链接了所有规则。

答案 1 :(得分:0)

您可以在RewriteRule的末尾测试[NE]标志。

答案 2 :(得分:0)

经过一段时间的打击后,事情看起来很不错:

RewriteMap unescape int:unescape

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^.+\ (/[^?\s]*)\??([^\s]*)
RewriteCond %{REQUEST_URI}?%{QUERY_STRING}<${unescape:%1}?%2 ^([^<]*)<\1$
RewriteRule .* /pub/dispatch.php [L]