Apply second mod_rewrite to query - apache

Basically, I am sent a query string that I need to reformat into a URL where the values are divided by slashes and where the dots are cleared out of one of the values. I can do either of those things, but when I try to chain them together it doesn't work.
Here is the original URL
https://www.example.com/?id1=5&id2=7&id3=9&id4=7&id5=source.website.com&id6=5
Here is what I have right now ...
# Takes the dots and replaces name of server
RewriteCond %{QUERY_STRING} ^(.*source.website.com.*)$
RewriteCond %{QUERY_STRING} (.*id5=).*(id6=.*)$
RewriteRule ^(.*) %1newwebsitecom&%2?
# Rewrites Query to URL
RewriteCond %{QUERY_STRING} ^id1=(\w+)&id2=(\w+)&id3=(\w+)&id4=(\w+)&id5=([a-zA-Z0-9\.\%]+)&id6=(\w+)
RewriteRule ^(.*) https://www.example.com/dir/%1/%2/%3/%5/%6?
Separately, both of these work. However, the second rule simply takes the query and performs the actions as if the first never took place. How do I get around that?

Have you tried merging the two rules?
I've tested this rule set on htaccess.madewithlove.be and it seems to achieve the desired results.
RewriteCond %{QUERY_STRING} ^(.*source.website.com.*)$
RewriteCond %{QUERY_STRING} (.*id5=).*(id6=.*)$
RewriteCond %{QUERY_STRING} ^id1=(\w+)&id2=(\w+)&id3=(\w+)&id4=(\w+)&id5=([a-zA-Z0-9\.\%]+)&id6=(\w+)
RewriteRule ^(.*) https://www.example.com/dir/%1/%2/%3/%4/newwebsitecom/%6?

Related

.htaccess catch GET parameters in any order

Im trying to write a rewrite rule that checks if multiple get paramaters are set in any order and then redirect to a url using the arguments from these get parameters this is what I have tried
RewriteCond %{QUERY_STRING} (?:^|&)retailer_filter=([^&]+)
RewriteCond %{QUERY_STRING} (?:^|&)product=([^&]+)
RewriteCond %{QUERY_STRING} (?:^|&)sitechange=([^&]+)
RewriteRule ^$ /?product=%1&retailer_filter=%2 [R=301,L]
This redirects but only has the sitechange argument so
/?product=test&retailer_filter=test&sitechange=1 redirects to ?/product=1&retailer_filter=
when I want it to redirect ?/product=test&retailer_filter=test
but it needs to be able to accept the get parameters in differen orders so
/?sitechange=1t&retailer_filter=test&product=test would also need to redirect to ?/product=test&retailer_filter=test
any help would be appreciated
You are effectively trying to delete sitechange query parameter. You can use this rule:
RewriteEngine On
RewriteCond %{THE_REQUEST} \?(.*&)?sitechange=[^&]*&?(\S*)\sHTTP [NC]
RewriteRule ^/?$ %{REQUEST_URI}?%1%2 [R=301,NE,L]
This rule will accept GET parameters in any order. sitechange= can be at first or last or in middle position.

redirect url with query string to path, and url without query string must be internally rewritten

I've been trying and trying.
If one goes to:
www.domain.nl/vereniging
internally a page is requested from:
www.domain.nl/?p=vereniging
For that I use this:
RewriteCond %{QUERY_STRING} !(p=.*)$
RewriteRule ^(.+)$ ?p=$1 [NC]
If a users visits:
www.domain.nl/?p=vereniging
I want the users to be redirected to:
www.domain.nl/vereniging
For that I use:
RewriteCond %{QUERY_STRING} ^p=(.*)$ [NC]
RewriteRule ^$ http://www.domain.nl/%1? [NC,R=301]
(If I put RewriteCond %{REQUEST_FILENAME} !-d before this, it doesn't redirect anymore. That's strange because a query is not a directory right?)
Separately, these 2 chunks of code work.
However, if I put them together in 1 .htaccess it bitches about looping.I don't understand this, because the conditions should prevent looping.
Try applying the END flag to either the first or second RewriteRule.
Look at the END flag here: http://httpd.apache.org/docs/current/rewrite/flags.html
You need to check against the actual request:
RewriteCond %{THE_REQUEST} \?p=([^&\ ]+)
RewriteRule ^ /%1? [L,R=301]

Apache mod_rewrite query string without specific order

I have a rule that translates old-style urls into new style. It works ok as long as I use the same order of parameters in the query:
RewriteCond %{QUERY_STRING} ^country=([a-z]{2})&id=([0-9]+)$ [NC]
RewriteRule ^(.*)$ http://%1.localhost/%2? [R=301,L]
So url localhost/index.php?country=us&id=1234 would go to us.localhost/1234
But the problem is that using localhost/index.php?id=1234&country=us (note that arguments are now swapped in order) then the rule of course doesn't apply.
I thought about changing the rule to handle arguments separately, like this:
RewriteCond %{QUERY_STRING} country=([a-z]{2}) [NC]
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule ^(.*)$ http://%1.localhost/%2? [R=301,L]
But when entering localhost/index.php?id=1234&country=us I get 1234.localhost/us which is not what I expect (I'd expect first cond to give me %1 and second cond %2 but it seems the order isn't determined this way)
Is there any easy way to achieve this? Of course I could write two separate rules each handling each case, but was wondering if some generic approach could be used (think if we had 3 parameters then permutations would make this unmanageable)
From the documentation, it looks like you can only reference rules from the last match:
RewriteCond backreferences: These are backreferences of the form %N (0 <= N <= 9). %1 to %9 provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions. %0 provides access to the whole string matched by that pattern.
I've been racking my brains on a good way to do this and the best I can come up with is to use multiple rules to extract the data into environment variables and then reference those at the end for your final rewrite.
Something like this:
RewriteCond %{QUERY_STRING} country=([a-z]{2}) [NC]
RewriteRule ^(.*)$ - [E=URL_COUNTRY:%1]
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule ^(.*)$ - [E=URL_ID:%1]
RewriteRule ^(.*)$ http://%{ENV:URL_COUNTRY}.localhost/%{ENV:URL_ID}? [R=301,L]

Rewriting every occurrence of pattern in query string via mod_rewrite

I have queries of this form going towards my server:
http://my.host.com/moo?p=1&s=2&targetURL=http://foo.com/sub/more/query
What I need to do is replace a part of the parameter of this query, specifically I need to replace http://foo.com/sub/ with http://bar.com/, preserving all the other parameters in this query and also preserving the parameters of http://foo.com/sub/more/query. I would be content with just replacing it in targetURL, so I tried this:
RewriteCond %{REQUEST_URI} ^/moo
RewriteRule ^/moo(.*)targetURL=http://foo.com/sub(.*)$ http://other.host.com/moo$1targetURL=http://bar.com$2 [L,R]
RewriteRule ^/moo(.*)$ http://other.host.com/moo$1 [L,R]
But the first query just never matches. Any help?
EDIT: To make clear, I have this:
http://my.host.com/moo?p=1&s=2&targetURL=http://foo.com/sub/more/query
and I want it to become this:
http://other.host.com/moo?p=1&s=2&targetURL=http://bar.com/more/query
Try this:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^my\.host\.com [NC]
RewriteCond %{QUERY_STRING} ^(.*)targetURL=http://foo.com/sub/(.*)$
RewriteRule ^/?moo$ http://other.host.com/moo?%1targetURL=http://bar.com/%2 [L,R=301]
You need to match the targetURL=http://foo.com/sub/ part from within the %{QUERY_STRING} variable using a RewriteCond. The query string isn't part of the URI when a RewriteRule matches against it. You can then use the %1 and %2 back references to reference the groupings matched in the query string.
Try this version which i tested and works for me.
<i>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^my\.host\.com/moo [NC,OR]
RewriteCond %{QUERY_STRING} ^p\=1\&s=2\&targetURL\=http\:\/\/foo.com/sub/more/query$ [NC,OR]
RewriteRule ^/(.*) http://other.host.com/moo?p=1&s=2&targetURL=http://bar.com/more/query/$1 [R=301,L]
</IfModule>

Use rewrite rule by query string

How can I make that if the QUERY_STRING matches something it would use that rule?
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)/?$ index.php?uri=$1 [L,QSA]
RewriteCond %{QUERY_STRING} uri=admin
ReqriteRule ^admin\?(.*)/?$ index.php?uri=admin&q=$1 [L,QSA]
Eg. http://localhost/admin?poll/new
After the ? should be the paramater q, the the query would be uri=admin&q=poll/new
Any idea on how I could do this?
Thanks.
Well, it happens that your problem is more simple than the link I gave you as you do not want any analysis on the query string content.
If you use this single line:
RewriteRule ^admin index.php?uri=admin&q= [L,QSA]
Where QSA mean append the query string to the result. You will obtain an internal redirection to:
index.php?uri=admin&q=&poll/new
Which is not OK, this is because the way you use argument (admin?poll/new) is not the standard way. So it seems we'll need to capture the query string content and put it by hand on the rewriteRule. This should work (if you need it only for /admin url):
RewriteCond %{REQUEST_FILENAME} admin [NC]
RewriteCond %{QUERY_STRING} (.*) [NC]
RewriteRule .* index.php?uri=admin&q=%1 [L]
Where %1 is the first parenthesis match in the RewriteCond :(.*), meaning everything in the query string, the query string being anything after the question mark. So in fact this allows admin?poll/new but also admin?poll/new&foo=toto, giving index.php?uri=admin&q=poll/new&foo=bar