Rewrite HTTP to HTTPS using .htaccess
Posted: 2018-02-18
If your website is hosted using Apache and mod_rewrite is enabled for you to use, this is how you can use an .htaccess
file to redirect any http
visits to your site to the https
version of the same URL.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
</IfModule>
Analysis
Here’s a breakdown of what this all means:
<IfModule mod_rewrite.c>
<IfModule …> prevents Apache parsing configuration for mod_rewrite
if it isn’t enabled for us to use in .htaccess
. You’ll get an HTTP 500 error if Apache encounters configuration it doesn’t understand.
RewriteEngine On
RewriteEngine tells Apache to activate the Rewrite module for the directory our .htaccess
is in.
RewriteCond %{HTTPS} off
RewriteCond is a conditional that must evaluate to true or our subsequent RewriteRule
will not execute. It evaluates to true if the value of the %{HTTPS}
variable contains the string off
. The %{HTTPS}
variable (documented under RewriteCond) contains the text on
if the connection is using SSL/TLS or off
if it isn’t.
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Finally, the RewriteRule is the instruction that rewrites the incoming URL and sends an HTTP redirect back to the client. It breaks down as follows:
^(.*)$
is a regular expression that will be matched against the path portion of the URL (i.e. without the protocol and hostname portion). We want to match any request from the root to a specific page, so this matches everything.https://%{HTTP_HOST}%{REQUEST_URI}
is the substitution template used to rewrite the URL. We upgrade the protocol tohttps
then we interpolate the value of the%{HTTP_HOST}
server variable instead of hardcoding our domain. Then we interpolate the%{REQUEST_URI}
server variable, which contains all remaining parts of the request URL, including query strings (e.g./index.html?something=extra
.- The last part is the flags
[L,R=301,NE]
.L
means “last” and instructs the rewrite engine that this is a terminal rewrite rule. Rules and conditions are chainable, if we didn’t specifyL
the engine would continue looking for subsequent rules and apply them to the new URL output by our rule.R=301
forces an external HTTP redirect, with the HTTP status code 301 Moved Permanently.NE
means “no-escape” and prevents special characters such as?
and&
being hexcode escaped as our%{REQUEST_URI}
is interpolated into the new URL.