RewriteRule violates while switching from https to http - php

I write a lot of RewriteRule in my .htaccess file , but problem occurs when I switch from https to http pages; it does not follow these rules
NOTE : everything working fine on localhost , issues are on server <---- UPDATE
Here is my website , currently all links display as per RewriteRule*
for e.g. about us page link display as
http://www.mywebsite.com/about
BUT
if I am at login page ( which is on https ) and click on about us page then it turns into below.
http://www.mywebsite.com/about?slug=about_us
or if I click on any category on left panel then it comes as
http://www.mywebsite.com/auction/category/1?cid=1
Note : even mouse hovering on pages display rewrite link
below is .htaccess file with needed information.
IndexIgnore *
RewriteEngine on
Options +FollowSymLinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^auction/category/([0-9]+)/?$ bids.php?cid=$1 [NC]
RewriteRule ^login/?$ login.php [NC]
RewriteRule ^register/?$ register.php [NC]
RewriteRule ^logout/?$ logout.php [NC]
# static pages
RewriteRule ^about/?$ page.php?slug=about_us [NC]
# Rewrite to https
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} /login [OR]
RewriteCond %{REQUEST_URI} /do_login.php
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L,QSA]
# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|ico|css|js)$ - [NC,L]
# traffic to http:// except some pages
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !(/login|/do_login.php)
RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L,QSA]
Note : Here is complete .htaccess file
Please tell me where I am wrong/missing ?
I Also have few more confusion
If i change the case of rewrite URL ( Login or lOgin or logiN ) then it gives error?
Is it good practice to write [NC,L] with all RewriteRule?
Exactly when I should write [QSA] ?
UPDATE
After suggestions from all answers, changing in RewriteRule almost fixed all issue but now there is one last issue.
/login URL always changed into /login.php.
below is my updated .htaccess
IndexIgnore *
Options -MultiViews
Options +FollowSymLinks
#mod_rewrite
RewriteEngine on
RewriteBase /
# Rewrite www to non www
RewriteCond %{HTTP_HOST} ^www.%{HTTP_HOST} [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]
# minimize the css on all http:// pages
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off
RewriteRule ^(.*).css$ /csszip.php?file=$1.css [L]
</IfModule>
#switch over http to https
# Rewrite to https
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC]
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|ico|css|js)$ - [NC,L]
# traffic to http:// except some pages
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !(/login|/do_login)\.php [NC]
RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^login/?$ login.php [NC]
RewriteRule ^register/?$ register.php [NC]
# ...many other rules...with [NC] falg
RewriteRule ^auction/category/([^/.]+)/?$ bids.php?cid=$1 [NC]
RewriteRule ^about/?$ page.php?slug=about_us [NC]
# ...many more rules.... with [NC] flag

HTTPS suggestion
For your HTTPS issue I would match on port or HTTPS as there are known apache problems relating to the HTTPS tag.
To cover this match on both (as shown in your edited answer)
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} != on
##REWRITE RULE
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTPS} = on
##REWRITE RULE
A valid point is also that %{REQUEST_URI} isn't affected by any substitutions.
The way you are using it at the moment, if any rule matches you will send them to the original url (before any substitution started).
If you want to take the url after and substition and matching use $1
Answers to your further questions:
If I change the case of rewrite URL then it gives error?
This is because your [NC] isn't on the rewrite cond for the HTTPS section of your .htaccess
You match RewriteCond %{REQUEST_URI} /login [OR] this is only looking for lower case login, if you want to accept uppercase login append NC.
Is it good practice to write [NC,L] with all RewriteRule?
No, it depends what you want to do [NC] says don't match case on this rule, if you don't want to match case on that rule (or condition) then add it.
Not matching the case with [NC] means site.com/login.php = sYte.cOm/LoGin.PHP
[L] means if this is true, stop processing everything
Exactly when I should write [QSA] ?
QSA applies when you have a ? in your substitution and you want to append toe old string to the new URL
Consider the following rule:
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
With the [QSA] flag, a request for /pages/123?one=two will be mapped to /page.php?page=123&one=two. Without the [QSA] flag, that same request will be mapped to /page.php?page=123 - that is, the existing query string will be discarded.
Do use QSA if you want to keep any additional get arguments.
Another further question
/login URL always changed into /login.php
The only way for this to happen is if you have a redirect [R=301] somewhere in your code, the only place I can see that is this section:
# Rewrite to https
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} != on
RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC]
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Where this will only match the following URL's
.php, /login.php, /do_login.php
I believe the culprit is as I outlined in the first response with %{REQUEST_URI}
Your code essentially says, if these conditions are met, send them to https://theurltheywentto, which is not what you want to do, you want to send them to /login.
Have you tried using (as mentioned in my https section)
RewriteRule ^(.*) https://%{HTTP_HOST}/login [R=301,L]
Or perhaps (if you have /do_login) and other options
RewriteRule ^(.*).php https://%{HTTP_HOST}/$1 [R=301,L]
Where test.com/do_login.php will become https://test.com/do_login
How about you try:
# Rewrite to https
RewriteCond %{REQUEST_URI} (/login|/do_login)\.php [NC]
RewriteCond %{HTTPS} != on
RewriteRule ^(.*)\.php https://%{HTTP_HOST}/$1 [R=301,L]

I think this might be of your help
.htaccess redirect https to http not working
and for last question this might be of your help
http://httpd.apache.org/docs/current/rewrite/flags.html and
http://www.addedbytes.com/download/mod_rewrite-cheat-sheet-v2/png/
EDIT:
You can try using
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{SERVER_PORT} !^443$
instead of
RewriteCond %{HTTPS} on [NC]
RewriteCond %{HTTPS} off [NC]
For detail
Please see this link, someone had similar problem. Please see second reply of the post
http://www.webmasterworld.com/apache/3228459.htm

you can solve this by creating the domain alias
You can't do it within .htaccess, but within a http.conf <VirtualHost> section you can use the ServerName and ServerAlias directives to accomplish this.

Your confusion over /about is due to redirecting to %{REQUEST_URI}, which isn't changed as you make substitutions. Capture the URI and use $1 if you don't really want the URI as it started uring this round of rewrite processing.

Related

Redirect Apache with RewriteRule http or https non-www url to url format https://www [duplicate]

I've had a look through existing questions, but I haven't really come across anything which works for me.
I'm currently running a site with a Secure SSL certificate. It can be accessed at https://www.example.co.uk a problem is the site can also be accessed at http://www.example.co.uk - I don't want this to be possible. I need it to redirect from http to https.
I found this one snippet of code to use in an .htaccess file.
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.co.uk [NC]
RewriteRule ^(.*)$ https://example.co.uk/$1 [L,R=301]
This works fine when the user enters example.co.uk into their address bar, but I also need to add a conditional statement of some sort so that if the user enters 'www.example.co.uk' or 'http://www.example.co.uk'.
I've tried using the likes of [OR], but this ends up creating server errors.
Any help and suggestions is appreciated.
Cheers.
Try the following:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
Also, you can also redirect based on port number, for example:
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
This will redirect all requests received on port 80 to HTTPS.
Add the following code in .htaccess file.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
change example.com with your website domain
URLs redirect tutorial can be found from here - Redirect non-www to www & HTTP to HTTPS using .htaccess file
Try this, I used it and it works fine
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Try this:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Source:
https://www.ndchost.com/wiki/apache/redirect-http-to-https
(I tried so many different blocks of code, this 3 liner worked flawlessly)
For me work ONLY this variant:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Thanks https://www.reg.ru/support/hosting-i-servery/sajty-i-domeny/kak-dobavit-redirekt/redirekt-s-http-na-https (in Russian)
I try all of above code but any code is not working for my website.then i try this code and This code is running perfect for my website. You can use the following Rule in htaccess :
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
//Redirect http to https
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
//Redirect non-www to www
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
</IfModule>
Change example.com with your domain name and sorry for my poor english.
# Switch rewrite engine off in case this was installed under HostPay.
RewriteEngine Off
SetEnv DEFAULT_PHP_VERSION 7
DirectoryIndex index.cgi index.php
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# RewriteCond %{HTTP_HOST} ^compasscommunity.co.uk\.com$ [NC]
# RewriteRule ^(.*)$ https://www.compasscommunity.co.uk/$1 [L,R=301]
To redirect http://example.com or http://www.example.com to https://www.example.com in a simple way, you can use the following Rule in htaccess :
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond www.%{HTTP_HOST} ^(?:www\.)?(www\..+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [NE,L,R]
[Tested]
%{REQUEST_SCHEME} variable is available since apache 2.4 , this variable contains the value of requested scheme (http or https), on apache 2.4 you can use the following rule :
RewriteEngine on
RewriteCond %{REQUEST_SCHEME} ^http$
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]
There are better and more secure ways to make sure that all your traffic goes over https. For example setting up two virtual hosts and redirecting all traffic from your http to your https host. Read more on this in this answer here on security.stackexchange.com.
With setting up a virtual host for redirecting you can send a 301 status (redirect permanently) so the browser understands that all the following requests should be sent to the https server where it was redirected to. Hence no further http requests will be made after the first redirect response.
You should also carefully check the given answers because with the wrong rewrite rules set you might loose the query params from your incoming requests.
If you want to redirect HTTP to HTTPS and want to add www with each URL, use the htaccess below
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
it will first redirect HTTP to HTTPS and then it will redirect to www.
Since this is one of the top results in the search, if you're trying to add http to https redirect on AWS beanstalk, the accepted solution will not work.
You need following code instead:
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^.*$ https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Try this
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
Perfect Code Going to HTML index :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^YourNameWebsite\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.YourNameWebsite\.com$
RewriteRule ^/?$ "https\:\/\/YourNameWebsite\.com\/index\.html" [R=301,L]
Or
Perfect Code Going to PHP index :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^YourNameWebsite\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.YourNameWebsite\.com$
RewriteRule ^/?$ "https\:\/\/YourNameWebsite\.com\/index\.php" [R=301,L]
None of these worked for me, except for this. My site was hosted in https://www.asmallorange.com
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
The below code, when added to the .htaccess file, will automatically redirect any traffic destined for http: to https:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</IfModule>
If your project is in Laravel add the two lines
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
just below RewriteEngine On. Finally your .htaccess file will look like the following.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Visite here to more information
in .htaccess file add following line to restrict http access
SSLRequireSSL
for some reason its inverted in my host
so if i want it to reditect i need to check if https is on and then redirect to https
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]
is the code i use

Redirect One Page to http instead of https

I have my .htaccess file like below for force https to all my pages.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(www\.)?example\.net
RewriteRule ^(.*)$ https://www.example.net/$1 [R,L]
its working fine as per my requirements. Now I want exclude https for one of my page called demo.html
I do not want https for it.
its need
http://example.net/demo.html
instead of
https://example.net/demo.html
You need to add RewriteCond condition for it.
Check the below code :
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(www\.)?example\.net
RewriteCond %{REQUEST_URI} !^/demo\.html$ [NC]
RewriteRule ^(.*)$ https://www.example.net/$1 [R,L]
you could make that in same number of lines like this :
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule !^demo\.html$ https://www.%1%{REQUEST_URI} [L,R]
If that is OK , change R to R=301 to get permanent redirection because R alone will be considered as R=302 and that temporary redirection .

I want to redirect specific url to non https using htaccess

my current htaccess is:-
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
</IfModule>
i want to add rule to htaccess for url like https://www.example.com/abc/arg1/arg2 should redirect to http://www.example.com/abc/arg1/arg2
for this https://www.example.com/abc/* it should redirect to non-https format with keeping all arguments.
Use below rule, check after clearing your cache.
RewriteCond %{REQUEST_URI} ^/abc/(.*) [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Edit: Please try with below rule,
RewriteCond %{REQUEST_URI} !^/abc/(.*) [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
In above rule we are appending https to all url which are not starting with abc/(.*) you have to use this rewritecond where your original https rule exists.
If you want to redirect all https requests starting with abc/ to http, you must check for both abc/ and HTTPS
RewriteCond %{HTTPS} on
RewriteRule ^abc/ http://www.example.com%{REQUEST_URI} [R,L]
When everything works as it should, you may replace R with R=301 (permanent redirect). Never test with R=301.
I am not sure how you achieve the job, but the following should be working perfectly for you.
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} ^/abc [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Send subdomain as post data

Having spent the past few hours looking for a solution, I thought I'd ask here.
I'm looking for a way to process links such as:
http://subdomain.domain.com/page/subpage/
so they are passed to the server as:
http://domain.com/index.php?subdomain=subdomain&page=page&subpage=subpage
which can be taken by index.php to display the correct page information.
I can get the page and subpage to work but have no clue how to get the subdomain. Note: if there is no subdomain, I would like that field to either be left blank or contain a default value.
Any assistance would be much appreciated. :)
Edit:
Just to clarify, I want the first URL to be what the user sees and can input into the address bar and the second URL to be the page that is loaded by the server when the user navigates to the first URL.
My .htaccess file
Options +FollowSymlinks -MultiViews -Indexes
RewriteEngine On
RewriteBase /
# Remove 'www'
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# Add slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://resolutiongaming.com/$1/ [L,R=301]
# Subdomain redirect
RewriteCond %{HTTP_HOST} ^resolutiongaming.com$
RewriteRule ^webdev/$ http://webdev.resolutiongaming.com [R=301,L]
RewriteRule ^artwork/$ http://artwork.resolutiongaming.com [R=301,L]
RewriteRule ^music/$ http://music.resolutiongaming.com [R=301,L]
ErrorDocument 404 /error.php
You may try this in one .htacces file in root directory:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(?:www\.)?([^\.]+)\.domain\.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/([^/]+)/([^/]+)/? [NC]
RewriteRule .* http://domain.com/index.php?subdomain=%1&page=%2&subpage=%3 [R=301,L]
It will redirect permanently:
http://subdomain.domain.com/page/subpage/ or http://www.subdomain.domain.com/page/subpage/
To:
http://domain.com/index.php?subdomain=subdomain&page=page&subpage=subpage
For the rule to work, the incoming URL scheme: /page/subpage/ must be kept.
To replace permanent redirection with silent mapping, remove R=301 from [R=301,L] or replace it with R for temporal redirection.

Htaccess HTTPS redirection

I'm trying to get my .htaccess file to redirect only certain pages/folders to https and if its not the pages that need to be encrypted then it should shoot the user the the http page. Also I would like to be able to list certain folders that can either be HTTP or HTTPS
Here is what I tried using writing up myself. But seemed to not work all correctly.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{SERVER_PORT} 80
RewriteCond $1 ^(myaccount|payment\.html)
RewriteRule ^(.*)$ https://www.domain.com/$1 [R=301,L]
RewriteCond %{SERVER_PORT} 443
RewriteCond $1 !^(myaccount|payment\.html)
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
</IfModule>
You're checking a literal $1 in your RewriteCond patterns. It should be:
RewriteCond %{REQUEST_URI} ...stuff to match against here...
This should do what you want.
RewriteCond %{SERVER_PORT} 443 [NC]
RewriteCond %{REQUEST_URI} !^/(myaccount|payment)\.html [NC]
RewriteRule . http://www.domain.com/%{REQUEST_URI}/ [R=301,L]

Categories