I inherited support for an Opencart 1.5 site which needs to have SSL enabled.

I've edited the config.php files in / and admin/ and adding https:// to the URL is working in the browser and links are being generated with HTTPS.

However, whatever method of an .htaccess redirect I try seems to result in the site not loading.

The following is in the .htaccess file and I suspect the problem is related to the last line here with route which I've not seen before.

RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Any suggestions on how I can add HTTPS to this RewriteRule?

Added info...

I've tried various additions in the .htaccess file, for example

RewriteCond %{HTTPS} off
RewriteRule  ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L,NE]

If I add that after the existing redirect, it appears to not have any effect.

If I add it just after the RewriteBase / Firefox gives me the message:

The page isn't redirecting properly

In the Firefox Debugger it says

about:neterror?e=redirectLoop&u=https%3A//www.example.com/&c= ....

The Network tab shows 21 requests with a status of 301

SSL is managed by the hosting company but without attempting the new redirect adding the s to the address results in a working SSL site.

  • Please include the HTTP to HTTPS redirect(s) you have tried. There's nothing particularly unusual in the directives you've posted that would prevent this from working. How is your SSL managed? What do you mean by "site not loading" exactly? Are you getting a redirect loop?
    – MrWhite
    Apr 5, 2018 at 10:03
  • You don't want to modify that rewrite rule to force HTTPS. You will want other rules or virtual host configurations to do so. Apr 5, 2018 at 10:36
  • Thanks for your help so far, I've some additional info as requested. Apr 6, 2018 at 9:32

1 Answer 1


If I add that after the existing redirect, it appears to not have any effect.

Yes, that is correct. mod_rewrite directives execute top-down (in any given context). The existing directives implement a front-controller type pattern and consequently rewrite most requests to index.php. If the request is rewritten then any directives that follow (ie. your redirect) are simply never processed. (However, change your request to something like /foo/bar.css - regardless of whether this file exists or not - and the redirect should still be triggered.)

If I add it just after the RewriteBase / Firefox gives me the message:

Yes, the HTTP to HTTPS redirect should be placed at the top of your file. After the RewriteBase directive is a logical place to put it.

The page isn't redirecting properly

In other words, you are seeing a redirect-loop. With the directive you've given, that uses the HTTPS server variable, this error implies your host has implemented SSL with some kind of front-end proxy and traffic from the front-end proxy to your site is probably plain-old HTTP (ie. unencrypted).

You need to clarify with your webhost that this is the case and they should be able to tell you exactly what directive(s) you should be using. This might be specific to your server config.

Some hosts set an HTTPS environment variable (yes, same name, but different variable) when the request comes in over HTTPS. This is accessed like %{ENV:HTTPS} (as opposed to %{HTTPS}). This is reasonably common, but is server specific.

A standard proxy server will set the X-Forwarded-Proto HTTP request header in the forwarded request to your application server. So, you can perform the required HTTP to HTTPS redirect with something like the following instead:

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

However, you must clarify with your webhost that this is indeed how the SSL is implemented before using something like this in production. Otherwise, if your site is not behind a (SSL) proxy server then it's possible for someone to construct a malicious request and prevent the site from redirecting to HTTPS.

Since you are messing with 301 (permanent) redirects, you must clear your browser cache before testing.

Aside: Just a few additional comments about the following .htaccess code...

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

I've seen this code repeated a lot with regards to OpenCart (in fact it does seem to be part of the official distribution), however, it strikes me as a bit odd/puzzling:

  1. The presence of the 3rd RewriteCond directive that checks against REQUEST_URI prevents any request that contains .ico or .gif etc. (ie. usually "static resources"), being routed through Opencart. However, since this check appears after the first two conditions that already check for existing files/directories, then it is a check for requests to "static resources" that don't actually map to real files?! Is this a security feature?

    A check of this nature is usually implemented to improve efficiency since filesystem checks are "expensive". But to do that it should be implemented as a separate rule before the front-controller. This would have the same "security" (?) benefit as above, but with improved efficiency.

    In other words, remove this RewriteCond directive and use something like the following before the front-controller instead (although the regex is still begging for an end-of-string anchor ie. $ at the end of the regex, otherwise it is matching .css (for example) anywhere in the URL - maybe that is the intention, but it's also less efficient):

    RewriteRule \.(ico|gif|jpg|jpeg|png|js|css) - [L]
  2. The RewriteRule pattern ^([^?]*) looks like a newbie mistake. On first glance it might look like it is trying to capture everything in the URL up to, but not including, the query string (that starts with a literal ? in the URL). However, it doesn't, the query string is not part of the URL-path that is matched by the RewriteRule pattern. Instead, this matches everything up to the first URL-encoded ? in the URL-path (if any). This is strange, unless it is another "security" feature? But if it is a "security" feature then it should instead be implemented as a blocking directive earlier in the .htaccess file?

Unfortunately, I've not been able to find any further explanation as to why the directives might have been written this way.

  • Haven't got an answer back from my hosting company yet, so temporarily tried your suggestion but this also resulted in a redirect loop. Apr 9, 2018 at 14:39
  • Did you try both? You can also examine the contents of the $_SERVER superglobal in PHP, as this will indicate what environment variables and HTTP request headers are set on the request that hits your server (but it also contains a lot of other stuff about your system).
    – MrWhite
    Apr 9, 2018 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.