What RewriteRule would be to redirect based on the on query string parameters? - apache

If requested page page1.html and in query string uin is anything but not 12 or 13, let them see this page1.html page, otherwise redirect them to page2.html
Update: BTW, there are also other params in the query string. They should be sent to either page too.

The Rewrite Condition you're looking for is %{QUERY_STRING}
Here's another SO question doing something similar: Redirecting URLs (with specific GET parameters)

This will redirect to page2.html if uin=12 or uin=13. The entire query string will be sent to the page2.html page:
# EDIT: Doesn't properly handle all cases
RewriteCond %{QUERY_STRING} [\&]+uin=1[23][&]+ [OR]
RewriteCond %{QUERY_STRING} ^uin=1[23][&]+
RewriteRule ^/page1\.html /page2.html [R]
EDIT: This is a lot better and will handle the parameter in any position in the query string, beginning or end, and will also account for filtering out cases where the string is within another parameter, like suin=123
RewriteCond %{QUERY_STRING} ^(.*&)*uin=1[23](&.*)*$
RewriteRule ^/page1\.html /page2.html [R]
I tested on the following cases:
Redirected:
http://local.sandbox.com/page1.html?hello=world&uin=13&test=1
http://local.sandbox.com/page1.html?uin=12&test=1
http://local.sandbox.com/page1.html?uin=12
http://local.sandbox.com/page1.html?uin=13
http://local.sandbox.com/page1.html?uin=13&t=t
http://local.sandbox.com/page1.html?t=t&r=r&uin=13&t=3
http://local.sandbox.com/page1.html?t=t&uin=13
Didn't redirect:
http://local.sandbox.com/page1.html?uin=11&test=1
http://local.sandbox.com/page1.html?hello=world&uin=1&test=1
http://local.sandbox.com/page1.html?hello=world&ui=13&test=1
http://local.sandbox.com/page1.html?t=t&&r=r&suin=13&t=3
http://local.sandbox.com/page1.html?t=t&&r=r&uin=134&t=3
http://local.sandbox.com/page1.html?suin=134&t=3
http://local.sandbox.com/page1.html?auin=13&t=t
http://local.sandbox.com/page1.html?uin=134&t=3
http://local.sandbox.com/page1.html?t=t&uin=134
http://local.sandbox.com/page1.html?t=t&auin=13

Related

Can't pass parameters to another redirect website

I want to redirect to another website, and pass the parameters also.
Example: I go to my website: source.example/?code=12345
Then, I want it to redirect to target.example/?code=12345.
I am currently using this for my .htaccess file, since I figured out from other posts that if I query a certain parameter, it will get passed also:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^code=[NS]$
RewriteRule "www.google.com" /$1 [R=302,L]
Also, I tried many different approaches looking at these stack questions:
simple .htaccess redirect : how to redirect with parameters?
Redirect and keep the parameter in the url on .htaccess
But I can't get it running :(
since I figured out from other posts that if I query a certain parameter, it will get passed also
This is not true. The query string is passed through by default - there is nothing extra you need to do if you want the same query string on the target URL.
RewriteCond %{QUERY_STRING} ^code=[NS]$
RewriteRule "www.google.com" /$1 [R=302,L]
This code won't match the source URL for many reasons:
"www.google.com" - The first argument to the RewriteRule directive is a regex that matches the source URL-path (less the slash prefix). In your example the URL-path is empty.
^code=[NS]$ matches either code=N or code=S - which is not the intention from your example. (The [NS] looks like a mangled RewriteRule flag?!)
/$1 - this is the substitition string, ie. the URL you want to redirect to. (The $1 backreference is always empty, so this is meaningless.)
To redirect from source.example/?code=<number> to https://target.example/?code=<number> then try the following instead:
RewriteCond %{HTTP_HOST} ^source\.example [NC]
RewriteCond %{QUERY_STRING} ^code=\d+$
RewriteRule ^$ https://target.example/ [R=302,L]
This only matches a query string of the form code=1234. It does not match code= or code=1234&foo=bar, etc.
The query string is passed through by default.
If source.example is the only domain being hosted at the current location then you can remove the first condition that explicitly checks the requested hostname.
The order of directives in the .htaccess file is important. An external redirect like this should go near the top.

apache query string rewrite rules

I am setting up Query string redirect :
expo.com/en/general/campaigns/on-second-thought.html?slide=ost-2016-tank to
expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html
RewriteCond %{HTTP_HOST} ^(.*)expo\.com
RewriteCond %{QUERY_STRING} slide=ost-2016-tank
RewriteRule  ^/en/general/campaigns/on-second-thought.html?$  http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html [R=301,L,NC]
redirect happening but its appending ?slide=ost-2016-tank like below
http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html?slide=ost-2016-tank
slide=ost-2016-tank parameter is added to redirected page
Since your rule does not define a new query string, the default behavior of Apache is to copy the old query string to the new URL. To get rid of it, append a ? to the address you rewrite/redirect to:
RewriteRule ^/en/general/campaigns/on-second-thought\.html?$ http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html? [R=301,L,NC]
Or, for Apache >= 2.4, you can also use the flag QSD (Query String Discard):
RewriteRule ^/en/general/campaigns/on-second-thought\.html?$ http://www.expo.com/en/general/campaigns/on-second-thought/ost-2016-tank.html [R=301,L,NC,QSD]
Simply add a blank query string when redirecting:
RewriteCond %{HTTP_HOST} ^(.*)expo\.com
RewriteCond %{QUERY_STRING} ^slide=(ost-2016-tank)$
RewriteRule ^(/?en/general/campaigns/on-second-thought)\.(html)$ $1/%1.$2? [R=301,L,NC]
No need to mention http://expo.com again when redirecting. It'll automatically redirect to the same hostname because of R flag. No need to repeat same strings over and over. Using match groups and referencing them later works.
Your pattern had .html?$ in it, which actually means that it'll match .html as well as .htm. You do not receive query strings in RewriteRule context.

Rewrite rule to redirect a URI without a query param after appending a query param

I need to check if a UIRI from a folder contains any query param and if not, add the query param and redirect the uri in browser also using Apache rewrite rule. For this all url's starting with /abc/def/xyz/ the url should be appended with ?v=2, if not already having a query param
For example, /abc/def/xyz/folder/test.pdf should become /abc/def/xyz/folder/test.pdf?v=2
But /abc/def/xyz/folder1/test.pdf?v=3 should be left untouched.
I was able to add the query param using below but it causes infinite redirects. Thats why I need the selective redirect
RewriteRule ^abc/def/xyz/(.*) /abc/def/xyz/$1?v=2 [L,R=301]
the below does not redirect the browser URL to the new URI with the query param:
RewriteRule ^abc/def/xyz/(.*) /abc/def/xyz/$1?v=2 [PT,L]
You can make use of RewriteCond to check for Query Strings. I guess the following should do the trick. If there is a query String available, it would skip the rule. Else, it would append the query string v=2
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^abc/def/xyz/(.*)$ /abc/def/xyz/$1?v=2 [L, R=301]
Hope it helps.

mod_rewrite: encode only certain matches in URL

I am trying to rewrite a URL using mod_rewrite and encode a substring in my URL which is between brackets. My URL:
http://localhost/something?var_a=A&var_b=(B&2/3&)&var_c=C
and my .htaccess:
RewriteEngine On
RewriteCond %{QUERY_STRING} (.+)\((.*?)\)(.+)
RewriteRule ^.*$ somedir/%1%2%3? [R,B]
so I capture three strings, anything before the brackets, anything within, and anything after.
Result is:
somedir/var_a%3dA%26var_b%3dB%262%2f3%26%26var_c%3dC
but I would like to encode only the text which was within the brackets of my initial URL, such that
somedir/var_a=A&var_b=dB%262%2f3%26&var_c=C
The problem seems to be that the [B] option decodes the whole string. Is there a way to do this selectively? Also, my solution could only capture an occurrence of brackets once, it would be nice to have this more generic; could someone give me a hint?
Note that this question is related to my previous one, where I was trying to capture text between brackets.
This is extremely tricky for mod_rewrite but I took a shot at it. Solution is not pretty as it involves 2 redirects and use of cookies, but it works.
RewriteEngine On
# store non bracket query string in cookie while redirecting value in brackets using B flag
RewriteCond %{QUERY_STRING} ^(.+?&)?(var_b=)\(([^)]*)\)(.*)$ [NC]
RewriteRule !^somedir/ /somedir/%3? [L,CO=QS:%1-%2-%4:%{HTTP_HOST},B,R]
# retrieve value from cookie and use it to construct full URL
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{HTTP_COOKIE} QS=([^-]*)-([^-]+)-([^;]+) [NC]
RewriteRule ^(somedir)/(.*)$ /$1/%1%2$2%3? [L,R,NE]
Using these rules when I visit this URL: http://localhost/something?var_a=A&var_b=(B&2/3&)&var_c=C
it gets redirected to: http://localhost/somedir/var_a=A&var_b=B%262%2f3%26&var_c=C

.htaccess: Check if query string has a certain value or else redirect it

I'm trying to learn a bit of .htaccess and am really anxious on what it can do. I saw a snippet online but can't get it to work, it basically goes like this If a query string does not have a certain value, redirect it to index.php instead or some other page. How do I do that?
This looks for the value apples:
www.domain.com/somefile.php?a=apples&b=xyz
This will redirect to index.php instead:
www.domain.com/somefile.php?a=stinkycheese&b=xyz
You need to use the %{QUERY_STRING} variable inside a RewriteCond. So for example, if you don't want to redirect if there exists a redirect=no in the query string, it would look like this:
RewriteCond %{QUERY_STRING} !(^|&)redirect=no($|&)
RewriteRule . /index.php [L]
So if the RewriteCond fails (it has a redirect=no in the query string), then do not apply the following rule, which rewrites whatever the request URI is to /index.php. The actual rule that you need may be different, but using RewriteCond and %{QUERY_STRING} is the basic idea that you want.