Htaccess conditional https for static pages
My site is HTTPS enabled and all pages are served using HTTPS only . The client now has a requirement that he show a static page, like about-us
, termsofus
such as HTTP pages, rather than as the HTTPS . This means that even if the user tries to open the page about-us
as HTTPS, he must redirect to the HTTP version about-us
.
My .htaccess
code looks like this:
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine on
#RewriteCond %{HTTPS} off
#RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^\/about-us
RewriteCond %{REQUEST_URI} !^\/termsofus
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} \/about-us [OR]
RewriteCond %{REQUEST_URI} \/termsofus
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
</IfModule>
Problem: . When I open the HTTP / HTTPS version of the page about-us
, it redirects me to index.php
. For example: https://example.com/about-us
beforehttps://example.com/index.php
The site uses PHP YII framework.
source to share
Use THE_REQUEST
instead REQUEST_URI
. THE_REQUEST
the variable represents the original request that Apache received from your browser and is not rewritten after some rewrite rules are followed .
Options -Indexes
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !\s/+(about-us|termsofus) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} \s/+(about-us|termsofus) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
Be sure to clear your browser cache before testing this change.
source to share
Anubhava's answer already solves the problem and provides a good solution. I thought I'd just explain what's going on with your stated example with a link to your source code:
For example:
https://example.com/about-us
tohttps://example.com/index.php
Given the request https://example.com/about-us
:
-
This matches your second rule (HTTPS is requested "on" and
about-us
) and redirects tohttp://example.com/about-us
(ie back to HTTP). -
Now the redirected request (i.e.
http://example.com/about-us
) matches the last rule and is internally rewritten toindex.php
(front controller). -
However, in the files
.htaccess
(directory context) for each directory, "the rewritten request is passed to the url parsing engine" and the process starts efficiently. The server variable isREQUEST_URI
also updated to store the rewritten url i.e./index.php
... -
In the second pass through the file, the
.htaccess
request (now rewritten tohttp://example.com/index.php
) matches your first rule (HTTPS is "off" and the request is not/about-us
or/termsofus
), so the request is redirected (a second time) tohttps://example.com/index.php
. (Internal rewriting effectively changes to external redirection.) -
The forwarded request (now
https://example.com/index.php
) does not match any of the rules in your file.htaccess
, so it passes unchanged. The page is being served.
If you are checking network traffic, you should see the two external redirects mentioned above.
Another possible solution is to use a flag END
(Apache 2.4+ only) on the latter RewriteRule
. This effectively ends the url rewriting process, so the process stops at step 2. Although I still prefer the anubhava solution and check instead instead THE_REQUEST
, that works on Apache 2.2 and will still work if you add additional rewrites.
source to share