Smart HTTP and HTTPS .htaccess Rewrite
« SEO Secrets of AskApache.comAdding Akismet Anti-Spam Protection Anywhere »
This is a really cool idea I had to make my Apache .htaccess mod_rewrite code much shorter and easier to manage multiple Redirections when using sites with both HTTP and HTTPS. Basically instead of having to check for HTTPS using a RewriteCond for every redirect that can be HTTP or HTTPS, I found out I can set an environment variable 1 time to determine if HTTP or HTTPS is being used for that request, and by giving the variable a value of “https” for HTTPS or “http” for HTTP I can remove all duplicate rewriterule blocks. This is sweet I’m telling you!
This is the old way I would have to use to redirect /index.html to / and urls with // to /.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} !=on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.html\ HTTP/ [NC]
RewriteRule ^.*$ http://%{SERVER_NAME}/%1 [R=301,L]
RewriteCond %{HTTPS} =on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.html\ HTTP/ [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}/%1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)//(.*)\ HTTP/ [NC]
RewriteRule ^.*$ http://%{SERVER_NAME}/%1/%2 [R=301,L]
RewriteCond %{HTTPS} =on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)//(.*)\ HTTP/ [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}/%1/%2 [R=301,L]
First I set the environment variable ps to have the value “http” for HTTP requests, or “https” for HTTPS requests. Once that is accomplished, I can use %{ENV:ps} in all of my rewriterules and it will result in https for SSL requests and http for non-ssl requests!
RewriteCond %{HTTPS} =on
RewriteRule ^(.+)$ - [env=ps:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.+)$ - [env=ps:http]
# redirect urls with index.html to folder
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.html\ HTTP/ [NC]
RewriteRule ^.*$ %{ENV:ps}://%{SERVER_NAME}/%1 [R=301,L]
# change // to /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)//(.*)\ HTTP/ [NC]
RewriteRule ^.*$ %{ENV:ps}://%{SERVER_NAME}/%1/%2 [R=301,L]
The top guru I have ever seen in my lengthy .htaccess related web travels is a moderator on the WebmasterWorld.com Apache Forum, jdMorgan. Upon seeing the above solution that I came up with, jdMorgan instantly provided an improvement, resulting in being able to set the environment variable in 1 rewrite block instead of 2. This is truly Sweet.
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
RewriteRule ^(.+)$ - [env=askapache:%2]
# redirect urls with index.html to folder
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.html\ HTTP/
RewriteRule ^(([^/]+/)*)index\.html$ http%{ENV:askapache}://%{HTTP_HOST}/$1 [R=301,L]
# change // to /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)//(.*)\ HTTP/ [NC]
RewriteRule ^.*$ http%{ENV:askapache}://%{HTTP_HOST}/%1/%2 [R=301,L]
« SEO Secrets of AskApache.com
Adding Akismet Anti-Spam Protection Anywhere »
Tags: htaccess, htaccess rewrite, HTTPS, mod_rewrite, ssl
Please consider donating to support active development of the free software and articles here.![]()
The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect. Tim Berners-Lee
i am not a htacess expert, but i would be checking all your frames, images and includes and making sure they are coming from a secure server.
then again you might have google ads which do not have the option of coming from a secure server in which case you are stuffed. other ad providers may have the option of sourcing ads from a secure server, not just an ordinary server.
What I am trying to do is this: If the request is coming through https, I’d like all the internal content to ensure that it has https in it… This is mainly to get rid of that stupid IE 8 security warning about site containing non secure items which is bs…
Any ideas?
Thanks for posting this. It helped me out a great deal with having non-secure domains pointing to sub domains on my secure domain.
However, I started to have problems logging in from certain pages (there was no apparent pattern) and i discovered my form post requests were being lost. I tried for hours trying to see why the form would not process until i realized that it was probably something in htaccess.
Although i really don’t know exactly what the syntax means, (i am no htaccess expert) the following code looked suspicious
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.php\ HTTP/
RewriteRule ^(([^/]+/)*)index\.php$ http%{ENV:smartspace}://%{HTTP_HOST}/$1 [R=301,L]
Sure enough, I removed the code and it worked! It must have been stripping the post variables out as well as the index name in redirecting the page. Now it all seems to be working well (obviously it is not redirecting to the plain directory, but that’s ok). I will keep you posted if I have stuffed something else up but have not yet discovered it.
Someone might like to tell me exactly why the post variables are disappearing because it worked when I switched the method to GET.
cheers
I dont understand this line, i dont know how to interpret it. Can you please explain how to read this?
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
OK! My fault is the .htaccess rules work on the wrong scope.
And the solution is as follows:
Put the following rules inside of httpd-ssl.conf
RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^/repos$ /repos/ [R]
Then browsing https://hostname/repos will be directed to https://hostname/repos/
Where is the global area that rewrite rules will take effect on http and https both ?
Hello,
My goal is to redirect ‘https://hostname/repos’ to ‘https://hostname/repos/’ on Apache 2.2
I try a lot of methods, but I can’t do it.
RewriteEngine on
# rewrite '/repos' to '/repos/'
# These two rules both work with http only, not with https.
#RewriteRule ^(/repos)$ $1/ [R] #(/repos) means group, $1 = /repos
#RewriteRule ^/repos$ /repos/ [R]
# redirect 'http://hostname/repos[/...]' to https
RewriteCond %{HTTPS} !=on
RewriteRule ^/repos$ https://%{SERVER_NAME}%{REQUEST_URI}/ [L,R]
RewriteRule ^/repos/.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
# Notice: 'https://hostname/repos/' is our goal
# (1)Redirecting 'http://hostname/repos' to 'http://hostname/repos/' is skip
# (2)Redirecting 'http://hostname/repos' to 'https://hostname/repos/' is OK (done)
# (3)Redirecting 'http://hostname/repos/' to 'https://hostname/repos/' is OK (done)
# (4)Redirecting 'http://hostname/repos/...' to 'https://hostname/repos/...' is OK (done)
# (5)Redirecting 'https://hostname/repos' to 'https://hostname/repos/' is fail
# it can't add a slash at last
#RewriteCond %{HTTPS} =on
#RewriteRule ^/repos$ https://%{SERVER_NAME}%{REQUEST_URI}/ [L,R]
# (5)Redirecting 'https://hostname/repos' to 'https://hostname/repos/' is fail
# it can't add a slash at last
#RewriteCond %{HTTPS} =on #and
#RewriteCond %{THE_REQUEST} ^GET\ /repos\ HTTP/
#RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}/ [L,R=301]
# So browsing 'https://hostname/repos' will return '404 Not Found'
DO you have any good idea? Thank you!
I want to redirect ‘https://hostname/mypath’ to ‘https://hostname/mypath/’ (add a slash)
on Apache 2.2
But the following rule works with http only, not https.
RewriteEngine on RewriteRule ^/mypath$ /mypath/ [R]
Any idea?
Hello, I have migrated a moodle https site to a new moodle http site and I need to change/rewrite all the links to
https:// to http://
How can i do it?
Hello,
I have multiple domain on my single shared account (monsterhost). It works fine but I am having small issue. Lets say my main domain is mydomain.com. Each domain is pointing to separated subfolder (example: myseconddomain.com is pointing to mydomain.com/myseconddomain/). It is all working well but I wish to block all access for requests like this: mydomain.com/myseconddomain/.
Please, advise.
Thank you.
I was looking for a way to write a RewriteRule that would work for both HTTP and HTTPS requests — i.e., allowing either SSL and non-SSL access to the same site without having to write the RewriteRules twice. Your HTTP/HTTPS rewrite code was a great tip, but couldn’t it be simpler? Here’s what’s working for me:
RewriteCond %{HTTPS} on
RewriteRule .* - [env=https:s]
# redirect urls with index.html to folder
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.html\ HTTP/ [NC]
RewriteRule ^(.*/)index\.html$ http%{ENV:https}://%{SERVER_NAME}$1 [R=301,L]
Hey there! I just installed an ssl certificate on my site and:
thanks for posting the http to https rewrite.. I was also informed of this two liner:
RewriteCond %{SERVER_PORT} =80
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI}
but I really don’t know which to use or why i should use either.
Also, does using the rewrite to go from http to https mess up anything with google searches? sitemaps? etc.?
Thanks in advance,
ACE
It's very simple - you read the protocol and write the code. -Bill Joy
HTML | DCMI | GRDDL | XOXO | XDMP | XFN | DOM | XML | XHTML 1.1 Strict | CSS 2.1 | W3C | TLDP | WAI | DISA | ICSI | GIAC | SANS RR | GHOST | DEFCON | NIST | DHS CYBER | NIST | .:: Phrack Magazine ::.
↑ TOPExcept where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. HTTPD based on NCSA HTTPd
Nice. Thanks :)