htaccess woes
November 8, 2005 5:12 PM   Subscribe

Is there a mod_rewrite expert in the house that tell me what I'm doing wrong?

Things I'm trying to accomplish and as close as I (and a friend) got:

-redirecting aggregators that have my RSS feed to a new one:
RewriteRule ^index.php?s=rss&rss=1 /wp-rss2.php [QSA,L]

-redirect hits to links to a new directory:
#RewriteRule ^index.php?id=(.*)$ /old/index.php?=$4 [R]

Why am I doing this? So people's links to me stay good, and so I can throw a new index.php (from a different piece of blog software) in my main DIR. I know it makes more sense to redirect links to the new URL, but when I imported (from textpattern to wordpress) the Post IDs got a bit off due to things like deleted posts, so I don't think I can do that. I'm trying to piece this together from apache's doc and having a heck of a time. THANKS!
posted by ArcAm to Computers & Internet (15 answers total) 1 user marked this as a favorite
 
$4 should be $1. And neither rule will match since URIs start with /. So:

RewriteRule ^/index.php?s=rss&rss=1 /wp-rss2.php [QSA,L]

RewriteRule ^/index.php?id=(.*)$ /old/index.php?=$1 [R]

although I'm not sure about your flags.
posted by nicwolff at 5:26 PM on November 8, 2005


I'd use.

RedirectMatch 301 ^/index.php?s=rss&rss=1 /wp-rss2.php

RewriteRule ^/index.php?id=(.*)$ /old/index.php?=$1 [L]
posted by riffola at 6:31 PM on November 8, 2005


Er make that [R] because [L] will cloak the new URL.
posted by riffola at 6:33 PM on November 8, 2005


Response by poster: Thanks for the tips, but none of this is working out. I know that rewrite works on the server, becasue i can get some very simple stuff to work, but somehow these won't :(
posted by ArcAm at 7:58 PM on November 8, 2005


What does yout .htaccess look like?

RewriteEngine On

RedirectMatch 301 ^/index.php?s=rss&rss=1 /wp-rss2.php

RewriteRule ^/index.php?id=(.*)$ /old/index.php?=$1 [L]


Do you have the RewriteEngine line?
posted by riffola at 8:35 PM on November 8, 2005


Response by poster: Thanks for the response, here's a paste of the .htaccess:


# Options FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RedirectMatch 301 ^/index.php?s=rss&rss=1 /wp-rss2.php
RewriteRule ^/index.php?id=(.*)$ /old/index.php?=$1 [L]


Does it clue you in at all?
posted by ArcAm at 9:43 PM on November 8, 2005


I am not sure why you have
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d


I would drop that if you don't need it, since to me it appears incomplete, there's one more line it normally would have after these two lines depending on what you want it to do.

So try this...

Options FollowSymlinks
RewriteEngine On
RedirectMatch 301 ^/index.php?s=rss&rss=1 /wp-rss2.php
RewriteRule ^/index.php?id=(.*)$ /old/index.php?=$1 [L]

posted by riffola at 10:13 PM on November 8, 2005


First of all, ? is a metacharacter. If you want to match a literal question mark in a pattern you have to quote it with a backslash: "\?". Likewise with period, you should use "\." to match a literal period because using "." means "any character".

But, that's not relevent here. Apache treats the URL (stuff to the left of the ?) and the query string (stuff to the right of the ?) as separate and independent fields. You have to use %{QUERY_STRING} to match anything after the ?.

I don't know why you're testing $REQUEST_FILENAME to be a valid file or directory name. You really don't need that, especially when the point of using mod_rewrite is to rewrite URLs that would otherwise not be valid.
RewriteEngine On
RewriteBase /

# "/index.php?s=rss&rss=1" redirects to "/wp-rss2.php"
# the trailing ? on /wp-rss2.php means to delete the query
# string, so that "?s=rss&rss=1" will be dropped
RewriteCond %{QUERY_STRING} ^s=rss&rss=1$
RewriteRule ^/index\.php /wp-rss2.php? [R,L]

# because [L] was used above, we only get this far if that did not match
# so redirect all other hits to /index.php to /old/index.php
# the query args will be left intact, so that
# "/index.php?(anything)" will translate to "/old/index.php?(anything)"
# this is more robust than trying to match specific values of (anything)
RewriteRule ^/index\.php /old/index.php [R,L]
posted by Rhomboid at 10:17 PM on November 8, 2005


And, if I misinterpreted you and you *really* do want *only* requests of the form /index.php?id=(something) to be redirected to /old, as opposed to all /index.php hits, then you can do something like:
RewriteEngine On
RewriteBase /

# "/index.php?s=rss&rss=1" redirects to "/wp-rss2.php"
# the trailing ? on /wp-rss2.php means to delete the query
# string, so that "?s=rss&rss=1" will be dropped
RewriteCond %{QUERY_STRING} ^s=rss&rss=1$
RewriteRule ^/index\.php /wp-rss2.php? [R,L]

# "/index.php?id=(anything)" redirects to "/old/index.php?id=(anything)"
RewriteCond %{QUERY_STRING} ^id=(.+)$
RewriteRule ^/index\.php /old/index.php [R,L]
posted by Rhomboid at 10:23 PM on November 8, 2005


Btw, that's still not a very good way of doing it, though. In HTTP the order of parameters doesn't matter. So for example if you have a url that's "/index.php?id=123&foo=bar" it's just as valid as "/index.php?foo=bar&id=123" but the above will only match the first not the second. That's why I suggest the first one which passes all index.php traffic that doesn't match the RSS format to the /old/index.php.

You can correct this deficiency by simply looking for "id=" anywhere in the query string.

RewriteCond %{QUERY_STRING} id=
RewriteRule ^/index\.php /old/index.php [R,L]

But this will fail if you happened to have a parameter like "index.php?aid=x" that you did not want to match. sigh. So you can search for "&id=" to force it to be anchored, but then it won't match if it's at the beginning. So you can OR those two combinations.

I guess my point here is that mod_rewrite can get very complex to get perfect, especially if you care about all valid URLs. If you only care about certain forms of urls, like those that *only* have "?id=nn" then life is easy.
posted by Rhomboid at 10:28 PM on November 8, 2005


And, incidently, all of these fail to handle "/index.php?rss=1&s=rss" which is just as valid as "/index.php?s=rss&rss=1". Valid meaning absent of any mod_rewrite stuff, the php script interpreting the query string wouldn't care, because the http standard says they're equivalent.
posted by Rhomboid at 10:35 PM on November 8, 2005


Response by poster: The variety of responses has been interesting, thanks all.

@Rhombold - your second post is what I really am indeed after. Your answer seems so good and yet my site still SUXX. I'm going to show this to my host and see what he thinks. Maybe there's some setting that's off. I'll be sure to post what actually ends up working for the AskArchives.
posted by ArcAm at 10:36 PM on November 8, 2005


Response by poster: Damn you preview! Two posts added on! I'm painfully understanding your point about mod_rewrite being complex. There's that great quote in the doc about it being voodoo.

I really am only trying to alter URLs like "?id=nn" (well, except for that one that is "?rss=1") , so at least I have that going for me.
posted by ArcAm at 10:42 PM on November 8, 2005


For the record, you can actually handle RSS redirects inside your RSS file.

For example, let's say your old feed was at oldfeed.rss and you want to send people to newfeed.rss. Create a static file named "oldfeed.rss" (making sure your CMS doesn't overwrite it, of course), with the contents

<?xml version="1.0"?>
<redirect>
<newLocation>http://mydomain.com/newfeed.rss</newLocation>
</redirect>

I've used this and it works.
posted by adamrice at 7:21 AM on November 9, 2005


Response by poster: hey, that seems really elegant! I'll try it!
posted by ArcAm at 11:49 AM on November 9, 2005


« Older Help me get my domain back!   |   Crypto disco songs? Newer »
This thread is closed to new comments.