Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserve HTTP/HTTPS protocol in .htaccess redirects

I have to redirect port 80 to 2368 in htaccess but I'd like to keep the requested protocol intact so that SSL doesn't break.

I currently have this:

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC] RewriteRule ^ http://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L] 

which works correctly but I'd like the protocol to be taken from the %{HTTP_HOST} condition if possible.

Is there a way to get this to be more dynamic without hard coding domains and protocols?

It seems very slow as is.

like image 865
Vince Kronlein Avatar asked Oct 15 '13 03:10

Vince Kronlein


People also ask

Should I redirect HTTP to HTTPS?

It's a perfectly acceptable "bootstrap" method - 301 redirect from HTTP to HTTPS then on the HTTPS side return a Strict-Transport-Security header in order to lock the browser into HTTPS.


1 Answers

The trick provided by Jon is a nice hack, but I am afraid it could break if you want to use more [OR] conditions, and if you use more backreferences you have to be careful which number to use (%1 or %2 or ..).

I think the most elegant, robust and clean solution for smart HTTP/HTTPS handling is to set a variable:

# initialization code - put only once at the beginning of .htaccess RewriteCond %{HTTPS} =on RewriteRule ^(.*)$ - [env=proto:https] RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ - [env=proto:http]  # simply use %{ENV:proto} in your rules: RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC] RewriteRule ^            %{ENV:proto}://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L] 

The advantage also is that the initialization code needs to be run only once, so if you have more rewrite rules then the resultant code is much shorter and more elegant.

Note a common setup is https provided with cloudflare, in which case HTTPS is not 'on' on the server itself. In that case you need extra rules like (note order):

RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"' [OR] RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ - [env=proto:http] RewriteCond %{HTTP:CF-Visitor} '"scheme":"https"' [OR] RewriteCond %{HTTPS} =on RewriteRule ^(.*)$ - [env=proto:https] 
like image 199
Tomas Avatar answered Sep 21 '22 16:09

Tomas