tags:

views:

129

answers:

3

I asked this question earlier:

http://stackoverflow.com/questions/1500981/modrewrite-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):

 RewriteCond: 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?

A: 

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.

Gumbo
I appreciate you offering an answer to this question, especially since you provided the answer to the original question =D. As with the last question, I hesitate at any solution that involves requiring a flag on every rule, because they're easy to forget/miss; I'm not the only one working on this set of rewrite rules; and we're pretty much all rewrite newbs -- so error is inevitable.
Frank Farmer
A: 

You can test the [NE] flag at the end of the RewriteRule.

DrDol
`[NE]` doesn't appear to be a valid flag for `RewriteCond`. I'm not having issues with the `RewriteRule` itself.
Frank Farmer
A: 

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]
Frank Farmer