Rewrite rule fails to match single quote chars
I asked this question earlier:
mod_rewrite: match only if no previous rules have matched?
And have been using the suggested solution with success for a while now:
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]
However, we've since discovered that this rule fails for URLs containing single quote chars, e.g. http://example.com/don't_do_it
(which is actually requested as http://example.com/don%27t_do_it
)
Specifically, this is the line that's failing to match:
RewriteCond %{REQUEST_URI}?%{QUERY_STRING}<%1?%2 ^([^<]*)<\1$
commenting it out causes the rule to match as expected, but breaks the "match only if no previous rules have matched" behavior. This is presumably related to the fact that '
is urlencoded to %27
.
Here's the relevant RewriteLog entry (for the url /asdf'asdf
aka /asdf%27asdf
):
Re开发者_JAVA百科writeCond: input='/asdf'asdf?</asdf%27asdf?' pattern='^([^<]*)<\1$' => not-matched
What I'm seeing here is that %{REQUEST_URI} is unescaped while %{QUERY_STRING} is escaped, hence the mismatch. Is there an alternative to either one of those I should be using?
Any ideas how to rewrite the above line so that it will also match lines that contain '
chars?
Try the C flag and chain the sequence of rules of which you just want one to be applied. So actually chain all of your rules.
You can test the [NE] flag at the end of the RewriteRule.
After beating on it for quite some time, things are looking good with:
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]
精彩评论