Wednesday, December 1, 2010

Manipulating the Query String in Apache Rewrite

The query string is the part of the URL that follows the question mark (?). It is often used to pass parameters to CGI scripts or other dynamic pages. It is typically available in the QUERY_STRING environment variable.

The typical URL-manipulation directives such as , Redirect, Alias, and RewriteRule cannot directly access the query string. But mod_rewrite can be used to add, remove, or modify the query string. The trick is to use a RewriteCond to match against the %{QUERY_STRING} variable and, if necessary, the [QSA] flag to append to an existing query string.

Some examples follow. These examples all assume that they are placed in the main server configuration file. If they are placed in a section or .htaccess file, the RewriteRule will need to be modified accordingly. Also, these examples can all be transformed from internal alias to external redirects by adding the [R] flag to the RewriteRule.

Be cautious when dealing with complex query strings, since the order of the variables is often arbitrary.

Access control by Query String

Deny access to http://example.com/page?var=val if var=val contains the string foo.

RewriteCond %{QUERY_STRING} foo
RewriteRule ^/page - [F]

Removing the Query String

Delete the query string entirely.

RewriteRule ^/page /page?

Adding to the Query String

Keep the existing query string using the Query String Append flag, but add var=val to the end.

RewriteRule ^/page /page?var=val [QSA]

Rewriting For Certain Query Strings

Rewrite URLs like http://example.com/page1?var=val to http://example.com/page2?var=val but don't rewrite if val isn't present.

RewriteCond %{QUERY_STRING} val
RewriteRule ^/page1 /page2

Note that you don't need to use the Query String Append flag if you won't modify the query string in the RewriteRule; it is left as-is in the URL by default.

Modifying the Query String

Change any single instance of val in the query string to other_val when accessing /path. Note that %1 and %2 are back-references to the matched part of the regular expression in the previous RewriteCond.

RewriteCond %{QUERY_STRING} ^(.*)val(.*)$
RewriteRule /path /path?%1other_val%2

Making the Query String Part of the Path

Take a URL of the form http://example.com/path?var=val and transform it into http://example.com/path/var/val. Note that this particular example will work only for a single var=val pair containing only letters, numbers, and the underscore character.

RewriteCond %{QUERY_STRING} ^(\w+)=(\w+)$
RewriteRule ^/path /path/%1/%2?

Making the Path Part of the Query String

Essentially the reverse of the above recipe. But this example, on the other hand, will work for any valid three level URL. http://example.com/path/var/val will be transformed into http://example.com/path?var=val.

RewriteRule ^/path/([^/]+)/([^/]+) /path?$1=$2
See also RewritePathInfo for more examples of this technique.

No comments:

Post a Comment