Forum Moderators: phranque

Message Too Old, No Replies

rewrite redirect avoid passing query string (qsa?)

         

Grimmjow

9:13 pm on Jan 7, 2010 (gmt 0)

10+ Year Member



edit: I'm sorry for the title, it's a bit misleading since not only the query string is the problem, but the whole redirect.

Hi, I don't understand why this simple redirect doesn't work.

I've a Wordpress installation and I'm going to add a rule to redirect a page from an old site that was there.

I want to redirect /home/index.php?page=banner to /

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# My RULE:
RewriteRule ^home/index\.php\?page=banner$ / [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

It redirects to:

http://www.example.org/?page=banner
insted of
http://www.example.org/

I tried other variants, such as:

Redirect 301 /home/index.php?page=banner http://www.example.org
RewriteRule ^home/.*$ / [L]

But none seems to work. Could anyone help? Thanks.

jdMorgan

10:49 pm on Jan 7, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




RewriteCond %{THE_REQUEST} ^[A-Z]+\ /home/index\.php\?page=banner\ HTTP/
RewriteRule ^home/index\.php$ http://www.example.com/? [R=301,L]

This code appears to be somewhat redundant, but it prevents a potential 'infinite' internal-rewrite/external-redirect loop by making sure that the script-path-plus-query-string request is only redirected if it is directly requested as a URL by a client, and not as a result of a previous internal rewrite.

The question mark at the end of the RewriteRule substitution URL is an operator not a literal, and serves to clear the current query string.

As for your box-stock WP rewrite rule, it's slow and inefficient. See this recent thread [webmasterworld.com] for a detailed discussion of cleaning it up and speeding it up by a factor of 2 at minimum.

Jim

[edit] Corrected as noted below. [/edit]

[edited by: jdMorgan at 5:22 pm (utc) on Jan. 8, 2010]

Grimmjow

11:21 pm on Jan 7, 2010 (gmt 0)

10+ Year Member



Thank you Jim for the hints, you make simple working with rewrites, this is not the first time you help me, thanks :)

But the the code above doesn't seem to work, I cannot understand why, I checked the documentation of THE_REQUEST, other examples and it looks damn correct.

I narrowed my .htaccess in local machine to only this:

RewriteEngine On
RewriteBase /
RewriteCond ${THE_REQUEST} ^[A-Z]+\ /home/index\.php\?page=banner\ HTTP/
RewriteRule ^home/index\.php$ http://example.local/? [R=301,L]

And the browser returns 404 Not Found. This is the line in Apache access.log:

127.0.0.1 - - [08/Jan/2010:00:07:14 +0100] "GET /home/index.php?page=banner HTTP/1.1" 404 212

It looks correct to me :¦

In the meanwhile I found another couple of directives that do work:

RewriteCond %{QUERY_STRING} ^page=banner$
RewriteRule ^home/index\.php$ http://example.local/? [R=302,L]

But I'm still courious why the one with THE_REQUEST doesn't work, it appears to be correct and it may be useful in the future :(

jdMorgan

4:27 pm on Jan 8, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The "THE_REQUEST" method looks at the actual request received from the client (e.g. browser). Does the "/home" path-part actually appear in the published URLs, or is that a path-part added only inside the server?

Look at the log entries for these requests: The RewriteCond %{THE_REQUEST} pattern must match the quoted client request line that you see on your logs, starting with "GET" and ending with "HTTP/1.1" or "HTTP/1.0".

Jim

g1smd

4:45 pm on Jan 8, 2010 (gmt 0)

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



The problem is caused by a typo in your code.

The

[b]$[/b]{THE_REQUEST}
should be
[b]%[/b]{THE_REQUEST}
.

jdMorgan

5:23 pm on Jan 8, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well-spotted! - Thanks!

Jim

Grimmjow

10:58 pm on Jan 8, 2010 (gmt 0)

10+ Year Member



Oh, nice catch :)