Apache RewriteCond ignored in case of https - apache

I have to redirect from one domain to another domain. Both the domains have http and https protocol enabled. so in order to map http and https i have tried various combinations in conf file as below:
#RewriteCond %{HTTPS} =on
#RewriteCond %{SERVER_PORT} ^443$
#RewriteRule ^(.+)$ - [env=askapache:https]
#RewriteCond %{HTTPS} !=on
#RewriteRule ^(.+)$ - [env=askapache:http]
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
RewriteRule ^(.+)$ - [env=askapache:%2]
RewriteCond %{HTTP_HOST} ^([www.]+)?test-redirect\.com$ [NC]
RewriteRule ^(.*)$ http%{ENV:askapache}//amit.test.com/content/test/category/6 [L]
#RewriteCond %{HTTP_HOST} ^([www.]+)?test-redirect\.com$ [NC] <BR>
#RewriteCond %{HTTPS} !on
#RewriteRule .? http://amit.test.com/content/test/category/6 [L]`
But every time https condition is skipped/ignored. there is nothing rewrite logs as well. i have seen so many examples on net. but fail to understand why it is not detecting https? where http is working perfectly fine.

Rewrite logs may very well be in 2 diff locations for https and http. You can try using HTTP_AA instead of using "askapache" for the name of the env. The prefix HTTP_ANYTHING is a more fail safe way to make sure the var is available since some setups don't allow custom vars that start with anything other than HTTP_ which they have to allow due to it represents a HTTP header usually.
Make sure your https port is actually 443 or you will need to change the code.
Make sure your mod_rewrite block of code works by trying the first and second methods here: Even Newer HTTP/HTTPS Rewrite Code If it doesn't work using the first example you need to get it working using that rule first.
Try setting the HTTP_AA var above the rewrite code using the SetEnvIfNoCase directive or with
SetEnv HTTP_AA
Verify your vhost/httpd.conf settings for both SSL and non-SSL like the document root and Options and AllowOverrides, Logs and maybe StdEnvVars for SSLOptions.
Build a shtml file using mod_includes that just does a printenv. Then view both the ssl and non-ssl outputs and pay particular attention to the vars with the prefix REDIRECT_ and obviously make sure the HTTP_AA var shows up correctly in the printenv output. Or you could use the printenv cgi script or the shtml example on the askapache site.
Don't forget http://httpd.apache.org/.
Or try this
Options +FollowSymLinks +ExecCGI
# Set var now to try to try to have it availabe for mod_rewrite
SetEnv HTTP_AA
RewriteEngine On
RewriteBase /
# HTTP_AA is set to either s or is blank
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
RewriteRule ^(.+)$ - [env=HTTP_AA:%2]
# if host not new domain, its old so redirect both http/https to new
RewriteCond %{HTTP_HOST} !^amit\.example\.com$ [NC]
RewriteRule .* http%{ENV:HTTP_AA}://amit.example.com/content/test/category/6 [R=301,L]

Related

RewriteCond and rules except some page

Hello I want use redirect module on apache2
if request "test.net/xxx" then redirect to "test.test..net/xxx"
but except index.html page
for example if request "test.net/index.html" then no redirect
i wrote the apache2 conf file as below.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^test\.net [NC]
RewriteRule ^http://test\.net/([^index\.html]) http://test.test.net/$1 [R=301,L]
but doesn't work
how to edit above sentences? please tell me
thanks!
You add a condition to take care that the rule is only applied if the exception is not met and fix the actual rewriting rule:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^test\.net$ [NC]
RewriteCond %{REQUEST_URI} !^/index\.html$
RewriteRule ^/?(.*)$ http://test.test.net/$1 [R=301]
That rule will work in the http servers host configuration but also in dynamic configuration files (".htaccess").
If you receive an http status 500 ("internal server error") with above rule then chances are that you operate a very old version of the apachE http server. The error log files will then point out an unknown flag [END]. Replace it with the old [L] flag in that case.

.Htaccess RewriteRule (Subdomain vs Request_URI)

I have several domain names, each with their own multiple subdomains.
currently, I have a global RewriteRule for any domain with a specific Request_URI meant for my REST APIs.
.htaccess
RewriteEngine on
RewriteRule ^/?api/(.*)$ /api/inbound.php [NC,L]
Affected Url Examples:
acct.domain1.com/api/clients/123
my.domain2.com/api/tasks/2323
new.domain3.com/api/products/1212
And the Rule works great!
Now I've started using these subdomains:
api.domain1.com/api/clients/123
api.domain2.com/api/tasks/2323
api.domain3.com/api/products/1212
Though this still works, it's annoyingly redundant.
So, if the Subdomain happens to be "api, sandbox, api.test, or any chosen nuance I'm going to omit the /api/ path from the URL.
How would the RewriteRule look for this scenario?
Examine the HTTP Host Header value with a RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^api(\.test)?|sandbox
RewriteRule ^/?(.*)$ /api/inbound.php [NC,L]

Redirect all HTTP to HTTPS

I have a SSL on my site and would like to redirect all my http pages to https
I find something below and work for www.yourdomain.com.
If I also need transfer all yourdomain.com(without www) to https what should I add to htaccess? Thanks!
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]
<!-- Please put the redirect without www here, thanks-->
A simple Google search reveals hundreds of results. For example, this official FAQ.
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context

Redirect Loop while redirecting all http requests to https using .htaccess

I have the following rules on my .htaccess file
# to redirect http to https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
# to redirect urls with index.php to /
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
# to redirect non www requests to www url
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
When I am trying to access the website, it turns into a Redirect Loop. How to fix this issue and redirect properly?
Just in case somebody have redirect loop when using Apache http->https rewrite behind load balancer, here's solution that worked for me.
I had the same problem when used RewriteCond %{HTTPS} off for Apache behind load balancer, when load balancer does SSL stuff.
If https version of the site is not configured via Apache ModSSL it doesn't set %{HTTPS} variable to "on" and keeps redirecting infinitely.
The simplest solution to fix it is to target all https traffic to another Apache VirtualHost (when SSL is handled by load balancer) that is the copy of main one, but has different port (lets say 81). And in .htaccess do mod_rewrite for everything that is not on port 81:
ReWriteCond %{SERVER_PORT} !^81$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
The second way to do this is to send X-Forwarded-Proto header from load balancer to Apache and use it in rewrite condition:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
I've seen a lot of people suffering redirect loops when trying to use .htaccess files to move from http to https. And there are a LOT of different answers to how to solve this issue. Some people say:
ReWriteCond %{SERVER_PORT} 80
OR
RewriteCond %{HTTPS} off
OR
RewriteCond %{HTTPS} !on
OR (as above)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
OR EVEN
RewriteCond %{HTTP:X-Forwarded-SSL} =off
but none of these worked for me. I eventually discovered the underlying truth, that the different servers out there are configured in different ways, and they're all providing different server variables.
If none of the above work for you, then the trick is to use PHP to find out what env variables your particular server is sending you when you access an http page, and what env variables it sends you when you access an https page, and then you can use that variable to do the redirect. Just make a PHP file (such as showphpvars.php) on your server with this code:
<?php phpinfo() ?>
and then view it with a browser. Find the section of variables with _SERVER["HTTP_HOST" (etc)] in it, and have a scout around for one that changes for http versus https. Mine turned out to be a variable called SSL that was set to 1 when using https, and not set at all when using http.
I used that variable to redirect to https with PHP, which is so much nicer than using htaccess, but I think that any of the _SERVER variables can also be accessed using htaccess, if you're keen to continue to use that. Just use the name inside the quotes, without the _SERVER[""] bit that PHP adds.
For your information, it really depends on your hosting provider. It may be using a Load Balancer, as stated by Konstantin in another answer.
In my case (Infomaniak), nothing above actually worked and I got infinite redirect loop.
The right way to do this is actually explained in their support site:
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://your-domain.com/$1 [R=301,L]
So, always check with your hosting provider. Hopefully they have an article explaining how to do this. Otherwise, just ask the support.
If you get a redirect loop no matter what you do in htaccess, do the redirect in PHP instead.
I used phpinfo(), like #z-m suggests, to find the variable that changes when I'm on SSL. In my case it was $_SERVER['HTTP_X_PROTO'] == "https". When not on SSL, this variable is not set.
This is the code I use to redirect from HTTP to HTTPS:
if ($_SERVER['HTTP_X_PROTO'] != "https") {
header("HTTP/1.1 301 Moved Permanently");
$location = "https://" . $_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI];
header("Location: $location");
exit;
}
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{
In my case it was:
if ($_SERVER['HTTPS'] != "on")

http/https Rewrite not working, adds index.php to path

I'm trying to add some secure pages to a site. The links in the site all use the current protocol (i.e. are protocol independent, paths start with //).
I need the paths /info/season-tickets/* and /ticketcontroller/* to use https, and all others using http.
I've tried building rules to do the following (ignoring the ticketcontroller part for now):
If Port==80 and Path==/info/season-tickets/, rewrite with https
If Port==443 and Path!=/info/season-tickets/, rewrite with http
However, when I access /info/season-tickets/, rather than redirecting to the https version, I get example.com/index.php/info/season-tickets
The .htaccess is below - my attempts are below # Force https on certain pages and # Force http everywhere else, and the other bits are from the Kohana framework
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
# Force https on certain pages
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} ^/info/season-tickets/?
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
# Force http everywhere else
RewriteCond %{SERVER_PORT} 443
RewriteCond %{REQUEST_URI} !^/info/season-tickets/?
RewriteRule ^(.*)$ http://www.example.com/$1 [R,L]
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
I tried re-ordering the rules to see if that fixed it, but it didn't.
Any ideas why this isn't working (http://htaccess.madewithlove.be/ shows that it should work)...
Thanks!
I've solved this issue, not with htaccess, but in the index.php file (all requests go through this).
By default, I assume port 80. Then, if $_SERVER['REQUEST_URI'] is in an array of secure paths, I switch the variable to 443.
Then, if $required_port != $_SERVER['SERVER_PORT'], I redirect and exit().