I try to force all my website to https. So I did:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
It works. The problem is that I want that http calls on mywebsite.com/api/... work too. So I add RewriteCond %{REQUEST_URI} !^/api(/.*)?.
My .htaccess is:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/api(/.*)?
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
But it doesn't work. If I call http://mywebsite.com/api/xxx it redirects me to https://mywebsite.com/index.php ..
I don't know why. Do you have any ideas?
I use Zend 1
---- EDIT ----
Changed my .htaccess to this:
RewriteEngine On
# HTTPS
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/api(/.*)?
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php
Options +Indexes
IndexIgnore *
But still doesn't work
---- EDIT 2 ----
The new .htaccess (this one is working):
RewriteEngine On
RewriteBase /
# HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/api
RewriteCond %{QUERY_STRING} !^/api
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [NC,L,QSA]
I had to add condition with QUERY_STRING and change last redirect to index.php
Thank you @MrWhite
You have the directives in the wrong order. Your canonical HTTP to HTTPS redirect should come before your internal rewrite (ie. your front controller). Otherwise, a request for /api/<something> is going to be internally rewritten to /index.php (since I assume /api/<something> doesn't exist as a real file). /index.php then won't match against your RewriteCond directive that is checking for /api/<something>. So you then get redirected to https://example.com/index.php (although you've given http in your example?).
not behind a proxy
If you're not behind a proxy server then you should remove the conditions that check the X-Forwarded-Proto HTTP request header (these are only set by a proxy server, and if you aren't behind a proxy server then the client could maliciously set this header and avoid your redirect).
These two lines:
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] RewriteCond %{HTTP:X-Forwarded-Proto} =""
UPDATE: If you get a redirect loop after removing the above conditions then it might be that you are behind an SSL proxy after all (you should be able to tell by examining the HTTP request headers your application sees - you don't necessarily need access to the server config - in fact, you may not be able to tell by looking at the server config).
(When you are behind an SSL proxy then HTTPS is always off - your application serves an HTTP response to the SSL proxy that then serves an encrypted HTTPS response back to the client.)
Try the following:
Options +Indexes
IndexIgnore *
RewriteEngine On
RewriteBase /
# HTTP to HTTPS, except for the api subdirectory
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteRule !^api https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
# Front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
Note that this doesn't canonicalise the www vs non-www.
Regardless of your code ,put only the following code at your main directory .htaccess file :
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{THE_REQUEST} !\s/+api/ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
This will force all request except api/ to be https then if you request yourwebsite/api with http , http,wwwor without www it will go to api/ directory because it is not api/ issue to come with or without https as well as www and the above rule will be applied for none https because of this condition RewriteCond %{HTTPS} !=on so if comes with this it will override thi rule and that why http://yourwebsite/api and https://yourwebsite/api will work
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With