Forum Moderators: phranque

Message Too Old, No Replies

Removing all query parameters except one

RewriteRule and QUERYSTRING madness

         

badbadmonkey

7:05 am on Mar 15, 2014 (gmt 0)

10+ Year Member



I am trying to redirect an old MediaWiki install to its new home. Google has been allowed to index a bunch of the old URLs which I want forwarded.

I need
/wiki/index.php?title=Article&param1=val1&param2=val2...&param99=val99
to be redirected to
example.com/kb/Article

So I need the value of 'title' but ALL other parameters need to be dumped.

I have gotten this far. It successfully redirects, loses one extra parameter, but keeps appending any of the remaining parameters.


RewriteCond %{REQUEST_URI} ^/wiki/index.php [NC]
RewriteCond %{QUERY_STRING} ^(.*)title=(.+)(&(.*)*)$ [NC]
RewriteRule (.*) http://kb.example.com/kb/%2? [R=301,L]


What am I doing wrong? Do I need to use multiple steps?

[edited by: phranque at 9:13 am (utc) on Mar 15, 2014]
[edit reason] Please Use example.com [webmasterworld.com] [/edit]

matrix_jan

7:18 am on Mar 15, 2014 (gmt 0)

10+ Year Member



I've done something like this a long time ago. From what I can recall this should work:

RewriteCond %{REQUEST_URI} ^/wiki/index.php [NC]
RewriteRule ^/wiki/index.php\?title=(.*)\&(.*)$ http://kb.example.com/kb/%1? [R=301,L]


If I were you, I'd do it through php, since it's just a simple 301.

[edited by: phranque at 9:07 am (utc) on Mar 15, 2014]
[edit reason] exemplified domain [/edit]

lucy24

8:14 am on Mar 15, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It successfully redirects, loses one extra parameter, but keeps appending any of the remaining parameters.

RewriteCond %{REQUEST_URI} ^/wiki/index.php [NC]
RewriteCond %{QUERY_STRING} ^(.*)title=(.+)(&(.*)*)$ [NC]
RewriteRule (.*) http://www.example.com/kb/%2? [R=301,L]

Get that REQUEST_URI out of the condition and put it in the body of the rule where it belongs. It will save your server a load of work. I can't think of any situation where you'd want a positive REQUEST_URI in a condition instead of in the rule itself. (Negative, yes, often.)

^(.*)title=(.+)(&(.*)*)$

Heavens, what complications. All you need is

RewriteCond %{QUERY_STRING} (?:^|&)title=([^&]*)
RewriteRule ^wiki/index.php http://www.example.com/kb/%1? [R=301,L]


If no-capture markup makes you anxious, leave off the ?: and revert to %2 in the target.

The reappended parameters were a big mystery at first glance, since your target ends in a ? the way it should. But it's an artifact of the wording of your condition:

title=(.+)(&(.*)*)$

Regular Expressions are greedy by nature. So if the original URL had more than one parameter after "title", only the last one will be dropped. In fact the result could be quite messy, because

/index.php?blahblah&title=something&name=somethingelse&hanky=panky&foobar=widget

work with me here
would be redirected only to

/kb/something&name=somethingelse&hanky=panky

That's why you need to use [^&]* to capture only the "title" parameter. You don't need to say anything at all about what might come afterward, since you're just throwing that part away.

Edit:
The (&(.*)*) makes no sense. I suspect what you were aiming for was
((&[^&]*)*)
but since you're not capturing for reuse, there's no need to include this part at all.

g1smd

7:23 am on Mar 15, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Dump all the
.*
constructs. These are greedy, promiscuous and ambiguous.

Just extract
(^|&)title=([^&]+)(&|$)
into
%2
.


RewriteCond %{QUERY_STRING} (^|&)title=([^&]+)(&|$)
RewriteRule ^wiki/index\.php http://example.com/kb/%2? [R=301,L]

phranque

9:07 am on Mar 15, 2014 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



badbadmonkey, Please Use example.com For Domain Names in Posts [webmasterworld.com]

badbadmonkey

9:19 am on Mar 15, 2014 (gmt 0)

10+ Year Member



Thanks all, particularly Lucy, really appreciate it. It is the element () formatting that I fail at. As you say the result was messy with the clinging parameters. Working as intended now!

g1smd

9:35 am on Mar 15, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Post your updated code.

Make sure the new rule is before you non-www/www hostname canonicalization rule.