What is RewriteCond and how to use it ? Apache mod-rewite tutorial | amitoverflow blog

What is RewriteCond in mod-rewite

RewriteCond is an apache mod-rewite directive which is used for conditional URL rewriting on Apache server.
We use RewriteCond along with RewriteRule to test a server variable ie %{HTTP_HOST} , %{HTTPS} etc.

RewriteCond syntex

RewriteCond testString conditionPattern flags

  • RewriteCond : RewriteCond directive
  • TestString : A server variables like %{HTTP_HOST} or plain text string like hello
  • Condition Pattern : A regular expressions based pattern.
  • Flags : Mod rewrite flags like [NC] and [OR] .

Understanding how RewriteCond actually works in mod-rewite

RewriteCond directive sets a condition for the rule to run. With RewriteCond you can rewite your URLs conditionally or when the specific condition is met.
Let's see a basic example of how it actually works in RewriteRule.

RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
The RewriteCondion logic above can also be read as :
If http_host is www.example.com
or
If http_host ==www.example.com
To apply this logic to RewriteRule, you can use :
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^file\.php$ http://example.com/ [R]
The rule above will redirect /file.php to http://example.com/ if our condition is met or the host header is www.example.com .

RewriteCond directive takes three perameters Test string , Condition pattern and the third one is Flags . The first two are required perameters and the third one Flags is optional.
The two supported flags that can be used in RewriteCond are NC and OR .

Mod Rewrite pre-defined variables you can use in RewriteCond directive.

mod-rewite variables such as %{HTTP_HOST} are used as test string in RewriteCond to rewrite URLs conditionally. The following is a list of some commonly used variables:

  • %{HTTP_HOST} : The http_host header, your domain ie www.example.com .
  • %{REQUEST_FILENAME} : This variables contains the requested filename path relative to the server root.
  • %{REQUEST_URI} : The requested URI string ie. /path/file.php .
  • %{HTTPS} : contains the value off if requested scheme is http . If the scheme is https then this variables contains off value.
  • %{HTTP_REFERER} : http referer URL string ie. http://example.com .

Examples :

#1) Redirect all http URLs to https
To redirect all http URLs to https we will use the following logic :
"If https off" then redirect.

RewriteEngine on

RewriteCond %{HTTPS} off
RewriteRule (.*) https://example.com/$1 [R,L]
This will redirect all http URLs to https. The rule above RewriteRule (.*) https://example.com/$1 [R,L] executes if the condition RewriteCond %{HTTPS} off is met or the condition is true. If you request a non-secure URL starting with http the rule will then redirect it to the https version.
#2) Redirect non-www domain to www. The logic we will use here is :
"If host non-www then Redirect"
RewriteEngine on

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) http://www.example.com/$1 [R]
We use %{HTTP_HOST} variable to match against the current host header. The rule above will redirect your non-www domain to www. The regular expression !^www\. matches http host string that doesn't start with www. our Rewrite condition above checks if the host is not www. If the host string starts with www then the rule won't trigger. The rule triggers only if you request example.com.

Using a plain text string as test string in RewriteCond

For testing purposes, you can also use a plain text based string insted of mod-rewite variables in RewriteCond.

RewriteEngine on
RewriteCond hello ^hello$
RewriteRule (.*) http://example.com/ [R]
The rule above will redirect all your site URLs to http://example.com if the condition is met. The RewriteCond above RewriteCond hello ^hello$ is same as "if hello ==hello".

RewriteCond applies to a particular RewriteRule that immediately follows it

One of the most important things to notice about the behavior of RewriteCond is that it applies only to a single rule that immediately follows it . Your RewriteRule can have multiple RewriteConds but the only single rule that is placed bellow RewriteCond(s) is affected.
See the rule example bellow

RewriteEngine on

RewriteCond foo ^foo$
RewriteCond bar ^bar$
RewriteRule (.*) http://example.com/ [R]
RewriteRule (.*) http://google.com [R]
In the code above both conditions apply to the first rule. The second rule won't get affected by the conditions. The rule will redirect all your site URLs to http://example.com if the condition is met.

The use of [OR] flag in RewriteCond

By default , RewriteCond(s) directive uses AND logic when combined together in a Rule block.
Consider the following rule

RewriteCond %{HTTP_HOST} ^example.com$
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) http://www.example.com [R]
The RewriteCondions in the rule above use AND logic ie : "if host ==example.com" AND host==example.com" . Both conditions must met in order for the rule to run.

You can change the condition logic to OR using [OR] flag between two or more conditions .
RewriteCond %{HTTP_HOST} ^www.server1.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.server2.com$
RewriteRule (.*) http://example.com [R]
This rule uses OR based RewriteCondion logic ie: "if host ==www.server1.com" OR "host==www.server2.com" . Only one condition needes to be met in order to trigger the rule.

The use of [NC] flag in RewriteCond

NC (NoCase) flags is used to ignore the difference between upper case and lower case characters in the condition . You can check the test string in case insensitive manner using NC.

RewriteCond fooBar ^foobar
The condition above is "false" because the test string contains upper and lower case characters. You can sovle this using NC flag.
RewriteCond fooBar ^foobar$ [NC]
Now it's perfact. The condition is "true".
You can combine multiple RewriteConds using OR flag. Suppose you have two domains pointing to the same document root and you want to redirect www + non-www version of one of these two domains to a different location , instead of writing two separate rules for each domain you will use a single rule with RewriteConds combined with OR flag.
Here is an example:
RewriteEngine on


RewriteCond %{HTTP_HOST} ^www.server1.com$ [OR]
RewriteCond %{HTTP_HOST} ^server1.com$
RewriteRule (.*) http://diffrentServer.com/ [R]
The rule will redirect both www.server1.com and server1.com otherwise without the OR logic , we need to write two rule blocks for the redirection to work :
RewriteCond %{HTTP_HOST} ^www.server1.com$
RewriteRule (.*) http:diffrentServer.com/ [R]
RewriteCond %{HTTP_HOST} ^server1.com$
RewriteRule (.*) http:diffrentServer.com/ [R]
The rule above can also be shortened to one condition using Regex for example : RewriteCond %{HTTP_HOST} ^(www\.)?server1.com$ .

I hope you enjoyed reading this post. Thanks for reading!

Post a Comment

0 Comments