Problems with rewrite module and negation patterns - apache

I have the following problem:
If the url contains the keyword "formulario-" and it is a http connection, I want to redirect to the https version.
If the url doesn't contain the keyword "formulario-" and it is a https connection, I want to redirecto to http version.
I tried the following .htaccess but it doens't work properly:
RewriteEngine On
RewriteCond %{HTTPS} =on
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{HTTPS} !=on
RewriteRule ^formulario-(.*) http://%{HTTP_HOST}%{REQUEST_URI}
Thanks for your help!

Untested, but the general idea is:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule formulario- https://%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !formulario-
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
The theory being you cannot negate a RewriteRule, but you can negate a RewriteCond.

What exactly does not work?
One thing that comes to mind is: Try using the [L] flag for the first rule, so that apache stops to process the second rule, if the first rule applies.
I am not sure that's it though. You probably need some way to test whether the user was already redirected before.

Related

Apache manipulating query string on https

the following rules works on http but don't on https.
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1? [L]
RewriteRule ^/path/file.html$ https://www.domain.tld/path/file/ [R=301,L]
Why the query_string part doesn't work in https?
Based on the comments of your question, it appears that you just want to remove the query string anytime there is a page parameter. This type of rewrite rule doesn't strip off or change the URL unless there is a redirect. So if you don't add R=301 or R to the rewrite rule, the query string will not be removed. All of the following worked on my server to remove the query string, and my server is 100% HTTPS:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1? [R=301,L]
Or you may be able to use the QSD flag instead of question mark:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1 [R=301,L,QSD]
Or you may be able to use something like this:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule .* /? [R=301,L]
Or just R (for 302) instead of R=301:
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1? [R,L]
But in no case was the query string removed unless I used a redirect.
Really all you need is QSD http://httpd.apache.org/docs/current/rewrite/flags.htm
RewriteCond %{QUERY_STRING} "page=" [NC]
RewriteRule (.*) /$1 [L,QSD]
I'm not sure why it would work on http but not https unless you're using separate vhosts for http and https and the settigns were slightly different
Remember that Rewrite rules are internal unless using the R flag. When you use the R flag it tells the browser to go to a different page causing a full server/client round-trip. Otherwise, it just changes the request and proceeds as normal.
I'm not really strong with .htaccess file, and I can't explain what's going on behind the scenes, but from my opinion your .htaccess file should look like this:
RewriteCond %{QUERY_STRING} page= [NC]
RewriteRule (.*) /$1? [L]
RewriteRule ^path/file.html$ https://www.domain.tld/path/file/ [R=301,L]
It work perfectly for
http://example.com?page=1
https://example.com/?page=1
http://example.com/path/file.html
https://example.com/path/file.html
Tested (with love) here

.htaccess rewrite rule is also rewriting a different url

I'm using .htaccess to make a couple pages on my site secure -- /renew and /renew-result. I have a script that takes the user's inputs from /renew, sends them offsite to complete something, and then they should be returned to /renew-result. This works without the https rewrite rule, but when I try to implement the rule (see below), instead of returning to /renew-result, the user is redirected to /renew.
Here's the relevant part of my .htaccess file:
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^renew https://www.mydomain.com/renew [R,L]
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^renew\-result https://www.mydomain.com/renew-result [R,L]
Thanks in advance for any assistance.
The problem is that /renew-results matches the URL starting with /renew (this is your first rule). There are few ways to bypass this 'problem'..
First (the longest URL to match goes first):
RewriteCond %{HTTPS} off
RewriteRule ^renew-result https://www.mydomain.com/renew-result [R,L]
RewriteCond %{HTTPS} off
RewriteRule ^renew https://www.mydomain.com/renew [R,L]
Second (limit URL to exact match with $ at the end)
RewriteCond %{HTTPS} off
RewriteRule ^renew$ https://www.mydomain.com/renew [R,L]
RewriteCond %{HTTPS} off
RewriteRule ^renew-result$ https://www.mydomain.com/renew-result [R,L]
Third, combination of both cases in one rule. ^renew(-result)?$ matches only /renew or /renew-result capturing -result if it exists in request. While https://www.mydomain.com/renew$1 redirects to https version of /renew or /renew-result if capture presents.
RewriteCond %{HTTPS} off
RewriteRule ^renew(-result)?$ https://www.mydomain.com/renew$1 [R,L]
With out testing, this is something similar to what I have.
RewriteCond %{SERVER_PORT} 80
RewriteRule ^renew https://www.domain.com/renew [L,R=301]

htaccess for redirect to SSL

For the past few hours (days) I have been having some trouble redirecting a
page to SSL.
My setup is as follows: I have the following .htaccess for an e-commerce site
on Apache 2.2.16 on Debian (all required mods enabled)
RewriteEngine On
RewriteBase /shop
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
all requests are passed to index.php which acts as my controller and includes
other .php files as necessary.
I now want to use HTTPS for the checkout process which is a php script
cleverly called checkout.php
I thought it would be as easy as changing my .htaccess to:
RewriteEngine On
RewriteBase /shop
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{SERVER_URI} checkout\.php
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
so that checkout.php is not processed by index.php.
Apparently it is not that simple. I could probably do it by using a hardcoded
https link to checkout but I would prefer to do it with mod_rewrite.
If anyone can share some insight into
this it would be really appreciated.
Thanks in advance
There are a few problems. First, the pattern in your first RewriteRule
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
is written incorrectly. $1 isn't meaningful there (it's a capture result, but no capture has happened yet), and also the query string (part of the request after the ?) isn't part of what's matched, as the RewriteRule documentation says.
Second, I think you meant to use REQUEST_URI instead of SERVER_URI.
So I think you want something like this:
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/checkout\.php
RewriteRule .* https://localhost/shop/checkout.php [L,R]
RewriteCond %{REQUEST_URI} !^/(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ /index.php?/$1 [L]
A few notes:
You don't need to match or add back in the query string in the first RewriteRule; mod_rewrite will automatically add it back in.
It's conventional to test RewriteCond %{HTTPS} off instead of
RewriteCond %{SERVER_PORT} !443, as #Jon Lin suggests.
You may want to add the QSA flag in your second RewriteRule.

Why does this cause my site to redirect to secure.secure.*root domain*.com?

Here is the rewrite rule I am using:
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{HTTP_HOST} !^(www.)secure.\ [NC]
RewriteRule (.*) https://secure.%{HTTP_HOST}%{REQUEST_URI} [R,L]
This rule is supposed to be applied if the port is 443 (SSL port) and if the requested domain does not start with secure or www.secure .
Instead, it redirects to secure.secure and then returns a 404 error. Alternatively, if I remove the secure from rewrite rule creating
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{HTTP_HOST} !^(www.)secure.\ [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
I get a too many redirects error.
I admit, I am not a mod_rewrite expert, but I consider myself able to function with referring to the documentation. On this however, I am stumped. Thanks!
The grouping (www.) is not conditional. This should be something like (www.)?.
http://httpd.apache.org/docs/current/rewrite/intro.html for more extensive documentation.

Apache rewrite based on subdomain

I'm trying to redirect requests for a wildcard domain to a sub-directory.
ie. something.blah.example.com --> blah.example.com/something
I don't know how to get the subdomain name to use in the rewrite rule.
Final Solution:
RewriteCond %{HTTP_HOST} !^blah\.example\.com
RewriteCond %{HTTP_HOST} ^([^.]+)
RewriteRule ^(.*) /%1/$1 [L]
Or as pointed out by pilif
RewriteCond %{HTTP_HOST} ^([^.]+)\.blah\.example\.com$
You should have a look at the URL Rewriting Guide from the apache documentation.
The following is untested, but it should to the trick:
RewriteCond %{HTTP_HOST} ^([^.]+)\.blah\.domain\.com$
RewriteRule ^/(.*)$ http://blah.domain.com/%1/$1 [L,R]
This only works if the subdomain contains no dots. Otherwise, you'd have to alter the Regexp in RewriteCond to match any character which should still work due to the anchoring, but this certainly feels safer.
Try this:
RewriteCond %{HTTP_HOST} (.+)\.blah\.domain\.com
RewriteRule ^(.+)$ /%1/$1 [L]
#pilif (see comment): Okay, that's true. I just copied a .htaccess that I use on one of my projects. Guess it has a slightly different approach :)
#Sam
your RewriteCond line is wrong. The expansion of the variable is triggered with %, not $.
RewriteCond %{HTTP_HOST} ^([^\.]+)\.media\.xnet\.tk$
^
that should do the trick