.htaccess http to https - .htaccess

I am having a conflict between a couple of redirects causing issues.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ https://www.mywebsite.org/ [R=301,L]
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Options +FollowSymLinks -MultiViews
RewriteCond %{REQUEST_FILENAME} !403\.shtml
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php?a_aid=$1 [NC,L,R=301]
The issue I am running into is that when someone enters a non secure url it forwards them to
http://www.mywebsite.org/index.php?a_aid=https://www.mywebsite.org/url

My bet is that you'll need to add the [L] at the end of your line :
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
The L tag tells the code to stop running if the rule is applied, in your case it keep goin so the last rule is applied..
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
i think this is what i sould be.
In this section you wil find the different flag you can apply to your rules. i suggest you add the NC flag too (as for no case) so it match HTTPS also
http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

Related

How to redirect all the www requests to non www with query params

I am trying to redirect all the www URLs to non-www URLs
from :
1. http://example.com/web-url
2. http://www.example.com/web-url
3. https://www.example.com/web-url
to :
https://example.com/web-url
I have used the configuration as below.
RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
By the above, all seems to be okay, but the 3rd option is not working as expected. The issue is
https://www.example.com/web-url is redirected to https://example.com/index.php
Can anyone tell me what is the issue with my configuration?
Changing the order of the rules worked as expected.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php

Mod Rewrite not redirecting as expected

I have rewrite rule to redirect to www and rewrite rules to redirect to ssl. This is my desired setup and everything works perfectly except when I add this new condition:
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
If that condition is true I do not want the ssl redirect to happen. The problem I am seeing is that when I do this the entire url redirects to https://www.example.com/index.php?query=string
The normal behavior even for every other page works just fine. the URI stays the same but index.php is run. Here is my htaccess file below:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
My expected behavior is someone types in the url http://www.example.com/new-review?query=string and this page runs the code on index.php without switching the users uri to index.php. I just can't figure out why the last rewrite rule:
RewriteRule . index.php
follows expected behavior for everything except that one condition. All I want is for this one page to work as a non-ssl page but still run via index.php.
Important trick is to use THE_REQUEST variable instead of REQUEST_URI in your condition. THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules.
So you can use:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{THE_REQUEST} !^\s/new-review [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
The rewrite engine will loop until the URI stops changing. What happens when you request /new-review is it doesn't match any of the redirect rules, then it matches the last rule and it gets applied, thus /new-review is rewritten to /index.php. Now, the rewrite engine loops, and the new URI is applied. This time, your second rule matches the URI (/index.php) and thus gets redirected. If you don't want index.php to get redirected, then you need to either prevent all looping, or add a passthrough:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
or
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteRule ^(index\.php)?$ - [L]
RewriteCond %{HTTP_HOST} ^(?!www\.).*$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !^/new-review?.* [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

htaccess rewritecond and rewrite rule not working properly

I'm trying to redirect all /admin calls into subdomain with this two lines in .htaccess:
RewriteCond %{REQUEST_URI} ^admin [NC]
RewriteRule ^(.*)/$ http://admin\.somedomain\.com/$1/ [R,L]
Well, nothing happens. It just ignores the redirect rule and shows content of /admin directory.
Just for reference (and to skip requests to paste my entire .htaccess file), here it is:
Options +FollowSymlinks -Indexes
RewriteEngine on
Redirect 404 /favicon.ico
RewriteCond %{REQUEST_URI} ^admin [NC]
RewriteRule ^(.*)/$ http://admin\.somedomain\.com/$1/ [R,L]
# Send all admin. traffic to /admin
RewriteCond %{HTTP_HOST} ^admin\. [NC]
RewriteRule ^(.*)$ /admin/$1 [L]
# Check for www. and add it
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^admin\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R,L]
# Add trailing slash if not found
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !favicon.ico
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [R,L]
# Process virtual links/directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !favicon.ico
RewriteRule ^(.*)$ index.php/?$1 [QSA,L]
RewriteCond %(HTTP_HOST} !^admin\.somedomain\.com$
RewriteCond %{REQUEST_URI} ^/admin [NC]
RewriteRule ^(.*)$ http://admin.somedomain.com$1 [R,L]
You were missing a leading slash on your RewriteCond match. With the assumption that admin.somedomain.com may be in the same configuration as the other domain, I also added a check to ensure the rule isn't applied if the domain is already admin.somedomain.com. In the RewriteRule, I made a couple of minor modifications: You aren't matching on the right side, so you don't need to escape the dots.
There are some issues with your remaining rules as well. This won't work, for example:
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1
You can't use server variables on that side of the rule.

https in htaccess and order of rules (using Expression Engine)

I'm building a site in expression engine that part of needs to be https. The site is also using a new domain name (new one www.example-new.com the old one www.example.old.com).
I want to do the following things:
remove the index.php
force www
force https for any url starting www.example.old.com/extranet
redirect https URLs that are not www.example.old.com/extranet (e.g. www.example.old.com/news to http
I have the following code so far that works for the first two requirements:
<IfModule mod_rewrite.c>
RewriteEngine On
# Force www
RewriteCond %{HTTP_HOST} ^example-new.com$ [NC]
RewriteRule ^(.*)$ http://www.example-new.com/$1 [R=301,L]
# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
AddType x-httpd-php53 .php
I seem to be going round in circles, so I've two questions that will help me write the other rewrites (although feel free to share suggestions...):
1) Should the code for requirements 3 and 4 be positioned before "removes index.php" code?
2) Does the position have any bearing on the redirects that will be coming from the old site e.g. www.example-old.com/some-link-here.asp will be redirected to www.example-new.com/some-new-link-here
Thanks,
Gregor
1) Remove 'index.php' from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
2) Add 'www' to all URIs
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
3) Force https:// for any URI starting with /extranet
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/extranet(.*)$ [NC]
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]
4) Redirect https:// URIs that are not /extranet
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/extranet(.*)$ [NC]
RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]
Putting it all together, here's your complete set of RewriteRules:
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/extranet(.*)$ [NC]
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/extranet(.*)$ [NC]
RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
1) Should the code for requirements 3 and 4 be positioned before "removes index.php" code?
The rules are processed in the order that you write them. I expect that you want the site to redirect first then do the remove index, so yes, it should go before
2) Does the position have any bearing on the redirects that will be coming from the old site e.g. www.example-old.com/some-link-here.asp will be redirected to www.example-new.com/some-new-link-here
If you are using the same directory for both sites, then you would need to prefix all rules for one site with a RewriteCond that limits the domain. Otherwise, order of the rules (old vs new site) is important.
Your redirects from the old site should also incorporate rules in the new e.g. ensure that you are going to http/s as necessary to avoid extra redirects.
Below is the code to force http/s
#if not secure
RewriteCond %{HTTPS} off
#and starts with /extranet
RewriteCond %{REQUEST_URI} ^/extranet [NC]
#redirect to secure
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#if secure
RewriteCond %{HTTPS} on
#and does not start with /extranet
RewriteCond %{REQUEST_URI} !^/extranet [NC]
#redirect to http
RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# force www on hostname, but keep same protocol (http/https)
RewriteCond %{HTTP_HOST} !^www\.(.+)
RewriteCond %{HTTPS}s ^(on(s)|offs)
RewriteRule ^ http%2://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If it helps... I just did this yesterday for an ecommerce site... Here's my .htaccess file
# Remove WWW from URL
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]
# Add a trailing slash to paths without an extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)$ $1/ [L,R=301]
#remove index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
#Force HTTPS on checkout/account pages
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} (checkout|account)
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
#remove HTTPS on all other pages
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(img|_|images|checkout|account)
RewriteRule ^(.*)$ http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

.htaccess - how make rules apply to both specific pages and directories

I got help from this site to get functioning code for .htaccess:
# force https for /login.php and /register.php
RewriteCond %{HTTPS} off
RewriteRule ^(login|register)\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|css|js)$ - [NC,L]
# force http for all other URLs
RewriteCond %{HTTPS} on
RewriteCond %{SCRIPT_FILENAME} !(login|register)\.php$
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But now I realize I also need to add a couple of directories to these rules. How can this be done?
Why doesn't the following work:
# force https
RewriteCond %{HTTPS} off
RewriteCond %{SCRIPT_FILENAME} ^(securimage|ADM)/(.*)$
RewriteCond %{SCRIPT_FILENAME} ^(login|register)\.php$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|css|js)$ - [NC,L]
# force http for all other URLs
RewriteCond %{HTTPS} on
RewriteCond %{SCRIPT_FILENAME} !(securimage|ADM)/(.*)$
RewriteCond %{SCRIPT_FILENAME} !(login|register)\.php$
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
I've tried a few different variances, nothing's working. :(
I solved it by putting separate .htaccess files in the directories I wanted to secure, containing:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Resources