Carol Herbert
Carol Herbert

Reputation: 25

HTTP to HTTPS redirect not working with existing rules

I've been at this for 3 days now with no results!

I have an existing http site which has lots of redirect rules depending on URL friendly links which I now need to force load to https - Google will eventually drop them from the index but there are lots of links to the pages from 3rd party sites which I cannot physically change.

The .htaccess below handles http://example.com, but obviously not http://www.example.com

The problem is that if I add in a rewrite and get it to specifically change the url prefix to https it either doesn't work at all or will forward to https://www.example.com but then give an error message as too many redirects (depending on which version of http to https I've tried).

I've also tried splitting the code up to first check for https/redirect, and then non-www, but again when it does forward properly it either creates a loop or strips off the original query.

Help! lol

    Options +FollowSymLinks
    RewriteEngine On
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^example\.co\.uk [NC]
    RewriteRule ^(.*)$ https://www.example.co.uk/$1 [R=301,L]

    RewriteRule ^2/Home https://www.example.co.uk/  [QSA,L]
    RewriteRule ^([^/\.]+)/([^/\.]+)/?$ index.php?docid=$1&docname=$2 [QSA,L]
    RewriteRule ^item/([^/\.]+)/([^/\.]+)/?$ item.php?prodid=$1&prodname=$2 [QSA,L]
    RewriteRule ^search/ store.php [QSA,L]
    RewriteRule ^store/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ store.php?catid=$1&startPage=$2&limitPerPage=$3&searchTerm=$4 [QSA,L]
    RewriteRule ^store/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ store.php?catid=$1&startPage=$2&limitPerPage=$3 [QSA,L]
    RewriteRule ^store/([^/\.]+)/([^/\.]+)/?$ store.php?catid=$1&catname=$2 [QSA,L]
    RewriteRule ^sitemap\.xml/?$ sitemap.php

    ErrorDocument 404 /15/Error

    AddType application/x-font-woff2 .woff2

    SetEnvIfNoCase User-Agent "^libwww-perl*" block_bad_bots
    Deny from env=block_bad_bots

    #6 month for image files
    <filesMatch ".(jpg|jpeg|png|gif|ico)$">
    Header set Cache-Control "max-age=15552000, public"
    </filesMatch>
    ExpiresActive On
    ExpiresByType image/gif A2592000
    ExpiresByType image/png A2592000
    ExpiresByType image/jpg A2592000
    ExpiresByType image/jpeg A2592000

    # 6 month for css and js
    <filesMatch ".(css|js)$">
    Header set Cache-Control "max-age=15552000, public"
    </filesMatch>

    # long expire
    <filesMatch ".(woff2)$">
    Header set Cache-Control "max-age=102628000, public"
    </filesMatch>

    <IfModule mod_deflate.c>
    #Enable Gzip compression
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE application/x-font-opentype
    AddOutputFilterByType DEFLATE application/x-font-truetype
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE font/eot
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE image/vnd.microsoft.icon
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml

    # Remove browser bugs for legacy browsers
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    Header append Vary User-Agent
    </IfModule>

    <IfModule mod_expires.c>
    ExpiresActive On

    # Images
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"

    # Video
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType video/mpeg "access plus 1 year"

    # CSS, JavaScript
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"

    # Others
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType application/x-shockwave-flash "access plus 1 month"
    </IfModule>

Upvotes: 2

Views: 591

Answers (1)

MrWhite
MrWhite

Reputation: 45829

You don't currently have an HTTP to HTTPS redirect in the .htaccess code your posted, so it's anyone's guess why it was not working for you.

But you would need something like the following at the top of your .htaccess, immediately following the RewriteBase directive:

RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

This is a "standard" HTTP to HTTPS redirect. However, whether this works or not (and results in a redirect loop) can depend on how HTTPS is managed/implemented on your server. For example, whether you are using a front-end proxy (eg. Cloudflare FREE) that manages your SSL?

If you are using a front-end proxy then you may need to change it to something like:

RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

Or, some shared hosts use an HTTPS environment variable, instead of the HTTPS server variable, as used in the first example:

RewriteCond %{ENV:HTTPS} off
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

EDIT: This related question from 2017 suggests something similar to the above for use with the host "123-reg" (having heard back from 123-reg themselves). They've used the CondPattern !=on, which shouldn't really make any difference, unless 123-reg are doing something a bit odd?! The HTTPS environment (and similarly named server) variable(s) should contain either the string "off" or "on". So, it really shouldn't matter whether you check off or !on - the result should be the same.

NB: First test with a 302 (temporary) redirect to make sure it's working OK - this is to avoid any potential caching issues. You will need to clear your browser cache before testing.

UPDATE: The site is on shared hosting with 123-reg

This 123-reg support page states:

On our Linux shared hosting accounts, the environment variable SSL will be set when the connection is SSL-secured.

If this is the case, then you should be able to do the following instead:

RewriteCond %{ENV:SSL} ^$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

The above redirects to HTTPS if the SSL env var is empty (ie. not set).

Upvotes: 1

Related Questions