Skip to content

mod_rewrite

James Hopper edited this page Sep 13, 2018 · 16 revisions

MustardBlack supports a subset of mod_rewrite syntax, providing an easy and familiar DSL for writing redirect rules, typically for legacy/moved paths.

Usage

Differences between mod_rewrite, isapi_rewrite and this

This implementation is a subset of functionality provided by mod_rewrite and isapi_rewrite, with some different defaults:

  • The RewriteRule L flag is always on, if a RewriteRule matches, the response is issued and no more rules are evaluated for that request. This makes Chanining, Skipping and Nexting unavailable.
  • The RewriteRule NE flag is always on, special characters are not especially escaped
  • RewriteEngine on this is implicit, and RewriteEngine off is not supported
  • RewriteOptions supports additional options

RewriteOptions

RewriteOptions option1 option2

options can take any of the following values

  • nc and/or nocase - makes all the rules and conditions case insensitive
  • R=301 and/or permanent - Sets the default response statuscode to 301 Moved Permanently
  • R=303 and/or seeother - Sets the default response statuscode to 303 see Other
  • R=307 and/or temporary - Sets the default response statuscode to 307 Temporarily Moved

RewriteOptions apply to all rules below them in the .htaccess, and replace all previously set options, so in this example

RewriteOptions nc
RewriteOptions R=301

Case insensitivity has been turned back on, because its not present in the 2nd RewriteOptions

RewriteCond

RewriteCond <test-string> <pattern> [flag1,flag2]

test-string can take any of the following values:

  • %{http_host} and/or %{http:host} - the hostname from the requested url, e.g. www.mydomain.com
  • %{request_uri} the path from the requested url, e.g. path/to/thing - Note there is no leading slash
  • %{query_string} the querystring from the requested url, e.g. ?foo=bar

<pattern> is a .NET regex to match against the test-string

Valid values for [flags] are

  • nc and/or nocase - makes the <pattern> case insensitive

You can prefix the pattern string with a ! character (exclamation mark) to negate the result of the condition

RewriteRule

RewriteRule <pattern> <output> [flag1,flag2]

<pattern> is a .NET regex to match against the request_uri/path from the requested url <output> depends on the flags used, usually for a redirect this is the path or full url to redirect to. If output is only a path/querystring, e.g. /some/path?foo=bar then the redirect will include the Scheme, Host and Port from the original request.

Output can reference capture groups from its own pattern and preceeding RewriteConds. Use %1, %2, %3... to reference RewriteCond capture groups. Use $1, $2, $3... to reference RewriteRule pattern capture groups

Valid values for [flags] are

  • F and/or forbidden - Respond with 403 Forbidden
  • G and/or gone - Respond with 410 Gone
  • NC and/or nocase - Make the pattern regex case insensitive
  • QSA and/or qsappend - Merge the request querystring with the response/redirect querystring. Request parameters will overwrite response ones.
  • R=301 and/or permanent - Redirect to the <output> with a 301 Moved Permanently
  • R=303 and/or seeother - Redirect to the <output> with a 303 see Other
  • R=307 and/or temporary - Redirect to the <output> with a 307 Temporarily Moved
  • Not specifying F, G, or any of the R flags will result in a 302 Found

Tips: Querystrings

By default, request querystrings are appended to response urls. This doesn't happen if the response url already has a querystring on it. To merge the request querstring with the response querystring, use the QSA flag. To prevent the default appending, add a QSD flag

Examples

RewriteCond %{HTTP_HOST} ^www\.mydomain\.(com|co\.uk)$
RewriteRule some/path www.myotherdomain.%1

RewriteCond %{REQUEST_URI} !^.*/foo/.*$ 
RewriteRule ^([^\/]+\.html)$ /foo/$1 [R=301]

TODO

Clone this wiki locally