1

In .htaccess (Apache 2.4.6) file i do this:

RewriteCond %{HTTPS} =off [NC]
RewriteCond %{REQUEST_URI} ^\/(login|checkout)\/?(.*) [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

So, if my user get in http://site/login he is redirected to https://site/login. The same for checkout page.

But, for all others pages i do not want allow access to https protocol. In this cases i want force 301 redirect to http protocol.

For example: If my user access https://site/products i need it redirect him to http://site/products.

So, i added a new RewriteCond negating the regex, like this:

RewriteCond %{HTTPS} =on [NC]
RewriteCond %{REQUEST_URI} ^\/((?!login|checkout))\/?(.*) [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

But it didn't work.

Any ideas for this problem? Tks.

My .htaccess file

Options +FollowSymLinks -MultiViews
DirectoryIndex index.php

RewriteEngine On

# Force HTTP to HTTPS
RewriteCond %{HTTPS} =off [NC]
RewriteCond %{REQUEST_URI} ^/index.php/(login|checkout) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Force HTTPS to HTTP
RewriteCond %{HTTPS} =on [NC]
RewriteCond %{REQUEST_URI} !^/index.php/(login|checkout) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# From /index.php/ to /
RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule ^(.*)index.php/?$ /$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

The first rule, if my user get in on /index.php/login he is redirected to /login, removing the /index.php/ from URI.

The last rule delegate all calls to index.php for request dispatch (front controller).

Kennedy
  • 77
  • 1
  • 10

1 Answers1

1

Your negative lookahead doesn't seem to be correct.

And you can negate earlier URI matching condition in a simpler syntax also. So overall these 2 rules should work:

Options +FollowSymLinks -MultiViews
DirectoryIndex index.php

RewriteEngine On

# Force HTTP to HTTPS
RewriteCond %{HTTPS} =off [NC]
RewriteCond %{THE_REQUEST} /(login|checkout) [NC]
RewriteRule ^(login|checkout) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Force HTTPS to HTTP
RewriteCond %{HTTPS} =on [NC]
RewriteCond %{THE_REQUEST} !/(login|checkout) [NC]
RewriteRule !^(login|checkout) http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# From /index.php/ to /
RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule ^(.*)index.php/?$ /$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Delegate all requests to the index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Tks. But, with this rules, when i access /login or /checkout i'm being redirected to the index, always. – Kennedy Jan 05 '14 at 14:45
  • Yes, I had also fixed. Now, https to http, works fine! But, `http://`site/login back to index, also `https://`site/login. – Kennedy Jan 05 '14 at 15:02
  • Hmm that is definitely not because of these rules. Do you have other rules OR any other .htaccess on your system? – anubhava Jan 05 '14 at 15:28
  • I have. I will test without it. – Kennedy Jan 05 '14 at 15:41
  • Also I believe `/login` or `/checkout` not real directories or files? – anubhava Jan 05 '14 at 15:59
  • Yes, are page routes, not a dir or a file. – Kennedy Jan 05 '14 at 16:00
  • Tks. I've tested and when i access `http://`site/login or `https://`site/login keeps coming back to `http://`site/`index.php` and then `http://`site/ (without `index.php`). – Kennedy Jan 05 '14 at 16:27
  • I bet that is because of your last rule. Can you comment out `Delegate all requests to the index.php` rule and retest. – anubhava Jan 05 '14 at 16:33
  • Without `Delegate all requests to the index.php` and with this changes ^`/index.php/`(login|checkout) and !^`/index.php/`(login|checkout), worked fine! Thank you! But the URL got `/index.php/` in all requests. Any idea for solve this? – Kennedy Jan 05 '14 at 16:54
  • Can you update your .htaccess so that I can understand better and suggest accordingly. – anubhava Jan 05 '14 at 16:59
  • Updated! I need to hide `/index.php/` from URL. The URI has to be passed to the index.php, but without the user see, like this rule does: http://pastebin.com/ffcHLsYz – Kennedy Jan 05 '14 at 17:17
  • Hmm I believe question has gone well beyond the actually stated problem of forcing http or https for certain URIs. On top of that I don't even know how `/login` is handled. Made a last attempt, see if that works out. If not then I suggest opening a new question since this question about https/http redirection. – anubhava Jan 05 '14 at 17:44
  • I tried several other things, but it did not work. Thanks for your support! – Kennedy Jan 05 '14 at 19:17