Change uri parameters passing - mod-rewrite

Link example jumppage support:
http://server-address/index.php?param1={value1},{value2},{value3}
-Above is comma separated
Link example our website support:
http://server-address/index.php?param1={value1}&param2={value2}&param3={value3}
How can i reformat the initial paramaters are passed according to our standard?
Thanx!

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^param1=(.*?),(.*?),(.*)$
RewriteRule ^index\.php$ index.php?param1=%1&param2=%2&param3=%3 [L]
Note this does an internal redirect rather than a 301 or 302. Also not that is the comma separated list contain a variable number of items or there are other parameters, this can also be handled but the rules get a lot more complicated.

Related

HTTPS RewriteCond with two / routes

i have n URL like this:
http://name.co/othername/xname
http://name.co/othername/yname
So name.co/othername are equal. Just the 'xname' is changing to a different.
I need a redirect to the HTTPS Side.
I tried this:
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
but the result was not correct. it would be nice if someone could help me
REQUEST_URI will exclude the query string. Also, you need flags, at least [R] and usually [L] as well. You will probably want a 301 redirect in this case, unless you think you are likely to turn this off later. Try replacing the RewriteRule you have with:
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R=301,L]
The R flag means to actually send a redirect to the browser as opposed to just changing how the URL is handled insternally; the L flag means this is the last directive that should be processed; it shortcuts the rest of the processing and avoids any additional changes made by other rules.

Mod Rewrite + QSA : Same querystring param in rewrite target and in querystring - Force use of target possible?

We have the following rewrite rule:
RewriteRule ^([A-Za-z0-9\_]+)$ index.php?rewrite=$1 [L,QSA]
We were wondering if there was a way to have the ?rewrite=$1 take precedence over one that is passed via the query string in the request uri?
Because as it stands now, due to the QSA flag (which we do need btw) if the following url is hit:
http://www.domain.com/this_rewrite_will_match_the_above_rule?rewrite=some_value
The value of $_GET['rewrite'] in PHP will be some_value, and not this_rewrite_will_match_the_above rule.
Before we go in and start modifying the rewrites and adding a RewriteCond to match the query string, etc etc... We were hoping there was a flag to set so that the target url (index.php?rewrite=$1 in this case) took precedence over the passed query string values.
Hope this makes sense.
Thanks.
Slightly hackish
RewriteRule ^([A-Za-z0-9\_]+)$ index.php?%{QUERY_STRING}&rewrite=$1 [L]
This works because, in php, the second rewrite=... overwrite the first.
I have searched for some mechanics to override single querystring parameters in an Apache rewrite multiple times and quite intensely, but it looks like there is no option to do that, even with the latest Apache version (2.4.3 at the time of this writing).
But there is an alternative that makes use of the fact that the PHP querystring parser only returns the last of multiple idententical querystring parameters.
Example:
http://www.domain.com/index.php?id=123&id=456
This will return the following single (!) entry in $_GET:
array(1) {
["id"]=>
string(3) "456"
}
So you can solve your problem by simply appending any override parameters to the end of your existing querystring (without removing them within the querystring). The last occurrence of a repeated parameter is the one that makes it into the $_GET array.
Unfortunately the QSA switch is not suitable for this technique, as it always appends the original parameters to the end of the new querystring. There is no switch that would preprend the old parameters. So you have to take a little detour with a RewriteCond to catch and prepend the original querystring yourself instead of using QSA:
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^([A-Za-z0-9\_]+)$ index.php?%1&rewrite=$1 [L]
The only function of the RewriteCond is to capture the querystring in %1. The regexp (.*) of the condition is always matched, so the following RewriteRule is always executed.
With this technique your above testcase will rewrite to...
http://www.domain.com/index.php?rewrite=some_value&rewrite=this_rewrite_will_match_the_above_rule
...which will be interpreted by the PHP querystring parser to
$_GET["id"] => "this_rewrite_will_match_the_above_rule"
...which is what you want.
Please be aware that this will work only if you take your querystring values from PHP's $_GET array. It will not necessarily work if you parse the content of $_SERVER["QUERY_STRING"] yourself or if you use any other programming language.
I have opted to create an answer of my own, because its slightly cleaner then the examples provided by Jpsy and Gerben.
Credit where credit is due, their suggestions are what got me here, I only expanded on them:
So, our final solution includes 2 rules.
# check if querystring is not empty (this is the addition vs other answers)
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9\_]+)$ index.php?%{QUERY_STRING}&rewrite=$1 [L]
if the above query string fails (mainly, the querystring is empty) this rule will apply.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9\_]+)$ index.php?rewrite=$1 [L]
The reason I opted to go for this dual rule setup is to avoid having the php server variables polluted with "?&rewrite=...." if the query string is empty.
Thanks to jpsy and gerben for the help.
I used the following instructions:
RewriteRule ([^\?]*)\?(.*) $1?$2 [N] (1)
RewriteCond %{QUERY_STRING} (.*?)&?(rewrite=[^&]+)&?(.*)
RewriteRule ^(.*)$ $1?%1&%3 [N] (2)
RewriteRule ^(.*)$ $1?domain=newValue [L,QSA] (3)
The trick is done by the [N] flag in the first two rules, which causes to rewrite engine to re-process the output.
Rule (1) simple rewrites the url as it is. I needed it because I'm using mod_rewrite togheter with mod_proxy_ajp and in the first iteration the query string is not splitted from the url. After the execution of the first line, the url is unchanged but the engine will split the path from the query string.
Rule (2) iterates and removes all occurrences of the parameter "rewrite" from the query string.
Rule (3) sets the new value for the parameter and appends whichever query string survives from the replacement done by rule (2).

mod_rewrite, change one URL with query to a completely different URL

I am migrating data from one content management system to another. There is no relationship between old URLs and new URLs, although both contain query strings. I am trying to set up a set a rewrites that will redirect broad category lists of data from one to the other.
Here's a sample:
OLD
rss.php?categoryID=53
NEW
index.php?module=news&type=user&func=list&tid=1&filter=blogtopic:eq:19
I tried
RewriteRule ^rss.php\?categoryID=53 index.php?module=news&type=user&func=list&tid=1&filter=blogtopic:eq:19 [L]
but it doesn't match. If I follow that one with
RewriteRule ^rss.php index.php?module=news&type=user&func=list&tid=1 [L]
if DOES match, so I conclude that the question mark in the old URL is causing the problem. I am already escaping the question mark. What do I do?
I will probably end up with about 50 of these in my .htaccess file.
You can't match against the query string (all that stuff after the ?) in a RewriteRule, you need to use a RewriteCond and match against the `%{QUERY_STRING} var:
RewriteCond %{QUERY_STRING} ^categoryID=53$
RewriteRule ^rss\.php$ /index.php?module=news&type=user&func=list&tid=1&filter=blogtopic:eq:19 [L]
Or change the brackets to [R=301,L] if you want to redirect the browser.

How to unescape QUERY_STRING in mod_rewrite?

Hi all,
Now I want to use mod_rewrite module in apache2 to redirect url.
The rewrite rule looks like:
RewriteCond %{QUERY_STRING} ^url=(.+)$
RewriteRule ^/redir$ %1 [R=301,L]
However, when http://website.com/redir?url=http%3A%2F%2Fwww.google.com is input, the mod_rewrite module cannot unecsape the url parameter http%3A%2F%2Fwww.google.com, is there any method to resolve this problem?
RewriteMap unescape int:unescape
RewriteCond %{QUERY_STRING} ^url=(.+)$
RewriteRule ^/redir$ ${unescape:%1} [R=301,L]
Apache lets you define custom rewrite mappings from different types of external sources. For example, if you wanted to rewrite /users/<some alias> to /users/<full name>, you could have a text file that specified alias/name pairs, and a rewrite rule that translated the "alias" part of the URL using that mapping.
Mappings can come from multiple types of sources. The alias/name example is the standard plain text (txt) type.
RewriteMap also lets you map to a handful of special internal sources (int). They just pass the value to an internal Apache function and return the result. They are:
toupper: Converts the key to all upper case.
tolower: Converts the key to all lower case.
escape: Translates special characters in the key to hex-encodings.
unescape: Translates hex-encodings in the key back to special characters.
unescape is what you're looking for.
More information can be found in the mod_rewrite documentation.
Yep, there is one method: give it to a Php file then make a redirection in Php with appropriate "header".
Something like:
RewriteCond %{QUERY_STRING} ^url=(.+)$
RewriteRule ^/redir$ /myredir.php?redir=%1 [R=301,L]
And in Php, in the file myredir.php something like:
<?php
if (isset($_GET['redir'])) {
header("Location: ".urldecode($_GET['redir']));
}
exit;
?>

Redirect urls containing rogue characters

We have some crawl errors on our site and I'm trying to write a rewrite rule to fix them. What I want to say is that any url which begins with http://www.mysite.com/co that it should be redirected to a single url.
RewriteEngine On
RewriteBase /
RewriteRule ^co http://www.othersite.com/ [R=301,NC,L]
However, this doesn't work for the following urls
http://www.mysite.com/community/membe%3Cbr%3E%3Chr%3EタグOKです。%3Cbr%3E%3Ctextarea%20name=
http://www.mysite.com/community/membe%3Cbr%3E%3Chr%3E%E3%82%BF%E3%82%B0OK%E3%81%A7%E3%81%99%E3%80%82%3Cbr%3E%3Ctextarea%20name=
Any ideas how I can achieve this?
Thanks
James
Perhaps the easiest way would be whitelisting - redirect anything which contains characters not on your list of allowed characters. In this example, let's say you'd allow only lowercase letters, number 4, and the slash:
RewriteEngine On
RewriteBase /
RewriteRule [^a-z4/] http://example.com/redirect-to-here [R=301,L]

Resources