I updated the Apache URL rewriting mechanism since my last post on the topic. As I mentioned, passing values that contain URL encoded characters presents a problem, especially when the value contains slashes. When Apache passes REQUEST_URI to mod_rewrite, it has already been URL decoded. Slashes blow the whole name/value pair scheme, but there is a way to make it work.
The first requirement is that the web server allows encoded slashes (%2F or %5C), using the AllowEncodedSlashes directive. Without encoded slashes enabled, any paths inside the parameter values will immediately trigger a 404 response before the rewrite rules are considered. The trick to getting at encoded characters is to use the special THE_REQUEST variable, like so: # Root document, redirect to login RewriteRule ^/$ /go/login [R] # Request for static file RewriteCond %{QUERY_STRING} ^$ RewriteRule !^/go/.* - [NC,L] # Single name/value pair, the most typical case RewriteRule ^/(go)/([^/]+)/?$ /index.cfm?$1=$2 [NC,B,PT,L] # If PAIRS is empty grab them from the original URI, then loop RewriteCond %{ENV:PAIRS} ^$ RewriteCond %{THE_REQUEST} ^([A-Z]+\s)/(go)/([^/]+)/?([^\s]+)(\s.+)?$ [NC] RewriteRule .* /?%2=%3 [N,NE,E=PAIRS:%4] # Another round of parsing, add to the query string RewriteCond %{ENV:PAIRS} ^([^/]+)/([^/]+)/?(.*) RewriteRule .* /?%1=%2 [QSA,B,E=PAIRS:%3] # If PAIRS is empty, we're done RewriteCond %{ENV:PAIRS} !^$ RewriteRule .* - [N] RewriteRule .* /index.cfm [PT,L]
The comments should explain what's going on. The major difference from the method I used previously is that an environment variable holds the original URL encoded name/value pairs. A pair is pulled from the variable on each loop, until it's empty. It works correctly in my testing. I am pleased.
Of course, you might want to parse the PATH_INFO in a more powerful environment than mod_rewrite, in which case none of this is neccessary.