When performing URL rewrites with .htaccess files, if your resources are available from both an unsecured (http://) and a secured (https://) connection, your first instinct might be to write a rule for each. For example, this snippet will remove the leading "www." from the domain name over both HTTP and HTTPS:
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.+)$ http://%1/$1 [R=301]
RewriteCond %{HTTPS} =on
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.+)$ https://%1/$1 [R=301]
Here, each group of three lines is doing exactly the same thing (removing the 'www.' prefix), but the first group is only effective when serving pages over HTTP, and the second only over HTTPS. Clearly, if you have a lot of rewrites to perform in this fashion (external redirects, for example) then you're going to end up with a lot of otherwise redundant code.
Thanks to htaccess' ability to set environment variables, we can make this quite a bit cleaner. The following example first checks whether the connection is secure or not, sets a variable, then, in a single RewriteRule, uses this variable to do the original rewrite once.
RewriteCond %{HTTPS} !=on
RewriteRule ^(.+)$ – [env=prot:http]
RewriteCond %{HTTPS} =on
RewriteRule ^(.+)$ – [env=prot:https]
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.+)$ {ENV:prot}://%1/$1 [R=301]
The observant will note that this is still six lines of code, however, like I mentioned earlier, if you have a lot of external redirects, you don't need to test for the protocol each and every RewriteRule. Simply reference the variable, {ENV:prot}, instead of explicitly typing "http" or "https".
Finally, for the savvy webmaster, here is an even more compact (although also a bit more confusing) way to do the same:
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
RewriteRule ^(.+)$ – [env=s:%2]
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.+)$ http{ENV:s}://%1/$1 [R=301]
If you can follow, what’s happening here is that the first line is testing %{SERVER_PORT} to determine if it contains the string "443", and if so, setting the {ENV:s} variable to "s", and leaving it blank otherwise. This variable then gets appended to all instances of "http" effectively creating an automatic switch between secure and unsecured URLs.
Thanks to the posters in this thread at WebmasterWorld, for helping me clean up my code.