简体   繁体   中英

Htaccess conditional https for static pages

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 of REQUEST_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 .

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

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:

For example: https://example.com/about-us to https://example.com/index.php

Given a request for https://example.com/about-us :

  1. This matches your second rule (HTTPS is "on" and about-us is requested) and redirects to http://example.com/about-us (ie. back to HTTP).

  2. The redirected request (ie. http://example.com/about-us ) now matches the last rule and gets internally rewritten to index.php (the front-controller).

  3. 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. The REQUEST_URI server variable is also updated to hold the rewritten URL ie. /index.php .

  4. On the second pass through the .htaccess file the request (now rewritten to http://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) to https://example.com/index.php . (The internal rewrite is effectively changed into an external redirect .)

  5. 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 last RewriteRule . This effectively ends the URL rewriting process, so the process stops at step #2. Although I would still favour anubhava's solution and check against THE_REQUEST instead, which works on Apache 2.2 and will still work should you introduce additional rewrites.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM