My site is HTTPS enabled and all the pages are served using HTTPS only. Client now has the requirement where he wants to show static pages like about-us
, termsofus
as HTTP pages and not as HTTPS. This means that even if the user tries to open about-us
page as HTTPS it should redirect to HTTP version of about-us
.
My .htaccess
code is as follows:
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: Whenever I open HTTP/HTTPS version of about-us
page it keeps on redirecting me to index.php
.
For example: https://example.com/about-us
to https://example.com/index.php
The site uses PHP YII framework.
Use
THE_REQUEST
variable instead ofREQUEST_URI
.THE_REQUEST
variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules.Make sure to clear your browser cache before testing this change.
anubhava's answer already addresses the problem and provides a good solution. I thought I'd just provide some additional explanation as to what was happening with your stated example with reference to your original code:
Given a request for
https://example.com/about-us
:This matches your second rule (HTTPS is "on" and
about-us
is requested) and redirects tohttp://example.com/about-us
(ie. back to HTTP).The redirected request (ie.
http://example.com/about-us
) now matches the last rule and gets internally rewritten toindex.php
(the front-controller).However, in per-directory
.htaccess
files (directory context) "the rewritten request is handed back to the URL parsing engine" and the process effectively starts over. TheREQUEST_URI
server variable is also updated to hold the rewritten URL ie./index.php
.On the second pass through the
.htaccess
file the 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
. (The internal rewrite is effectively changed into an external redirect.)The redirected request (now
https://example.com/index.php
) does not match any rules in your.htaccess
file, so passes through unchanged. Page is served.If you check the network traffic, you should see the two external redirects mentioned above.
Another possible solution is to use the
END
flag (Apache 2.4+ only) on the lastRewriteRule
. This effectively ends the URL rewriting process, so the process stops at step #2. Although I would still favour anubhava's solution and check againstTHE_REQUEST
instead, which works on Apache 2.2 and will still work should you introduce additional rewrites.