Friday 21 August 2009

Redirecting from a 404 in Nginx

This morning I was trying to get the new version of my pog website to redirect requests for old pages to the old website (which I have mounted under a v1 subdomain). So, I was doing the same thing that I was most of yesterday.

First of all I tried a simple test case with a 404 page:
<?php
header('HTTP/1.1 301 Moved Permanently', true, 301);
header('Location: http://www.google.com');
exit();
?>
I saved that as 404.php, and then in my nginx config for the site I added
error_page 404 /404.php;

I went to a non-existent address on the website, and got the same thing I was seeing yesterday - a blank page. Checking the headers I saw the same thing too,
Location: http://www.google.com

404 Not Found

Visting the 404.php page directly, the redirection would work. So I guess that with NginX when it can't find a page and loads the error page, it must add the HTTP Status code after receiving the page back from fcgi, thus overwriting any HTTP Status headers you send from the PHP page.

In Apache though, the redirect from a 404 page seems to work fine.

Next I tried to find out how to do the redirection in the NginX config. I imagine it should be much less resource intensive and faster to process the redirect in Nginx as opposed to in PHP anyway.

I spent quite a few hours yesterday looking at this, but the solution was actually quite obvious, and I got it working on my first try today:
 location / {
index index.html;
root /path/to/site;

#If the file exists don't do any processing
if (-e $request_filename)
{break;}

#A rewrite rule
if (-e $request_filename.php) {
#rewrite any other page to page.php
rewrite ^/([^\.]+)$ /$1.php last;
}

#If the file exists on the old site, redirect there
if (-e /path/to/old/site$document_uri)
{
rewrite ^.*$ http://oldsite.domain.co.uk$document_uri permanent;
}

}

error_page 404 /404.php;
The important bit is that you only check if the file exists on the old site (and if it does redirect there), AFTER checking if the file exists on the current site and checking all the rewrite rules you have for your current site.

If you used rewrite rules for your old site, you would just need to add these rules after you check if the file exists on the old site.

After getting this working, I realised that when going to http://domain.com/old_file.html, I would be re-directed to http://www.domain.com/old_file.html, and then be redirected to http://oldsite.domain.com/old_file.html. I did some googling to see if there was any problem with a double redirect. I didn't find much, and nothing saying they were a big no-no, but the consensus seemed to be that it's best to avoid double redirects if possible. Double Redirects May Take Google More Time To Pick Up On.

So to prevent double redirects, what I had to do was to copy all of my redirect rules from the config for www.domain.com into the config for domain.com. Then I had to edit all the rewrite rules for domain.com so that they would perform a 301 permanent redirect to www.domain.com. Obviously, I didn't edit the redirect rules for redirecting to the old site, and left them redirecting there.

Then after all the rewrite rules, I just needed one last rewrite rule to catch any urls that weren't matched by any of the other rewrite rules, to redirect to www.domain.com.

So it makes the server config quite a bit longer, and you would also need to make sure that when you add/change any rewrite rules for www.domain.com, you also add/change them for domain.com. But it does solve the double redirect issue.

After lunch I watched the end of an episode of 'Me too!' with L. Granny Murray asked a girl to give her a twiddle (I think she meant a twirl), and also told the girl to put her clothes in her fag (no idea what she was on about there). Raymond did some skill faces while presenting a fashion show as well. Raymond's wife (fat old Dame Edna style taxi driving woman) also had the ultimate accessory according to Raymond - a hat that you can fold up WOW!!!!!!

I went on Animal Crossing, then me and L watched the end of In The Night Garden. Upsy Daisy loves her bed, and that most definitely was a pip.

The me and L went in the garden and filled up the pond as the water level was getting a bit low again.

After this I checked my email, then re-enabled APC (I had disabled it in case it was causing the issue with not being able to redirect from a 404 page), and also set date.timezone in php.ini on the web server. I tried to get my photosite working again on my local PC, but then it was dinner time.

After dinner I carried on trying to get my local photo website working again. I was having a problem with the imagick.so extension not being loaded into PHP for some reason (at least I got an error about class imagick not being defined).

I abandoned working on my photo website for a while to play on Wii Sports Resort. After that I tried to rip 'Tom Brown's Schooldays', not because it's a good film (I guess it's okay), but so me or Moccle can make a video using clips of Stephen Fry.

I spent ages trying to figure out how to do this. I did have a good guide to ripping dvds with Gordian Knot, but I couldn't find it. I found some guides online on Doom9 (though not as good as the PDF guide I couldn't find), and following them I got to a point where the said click on 'Save and encode'.

I spent ages looking at all the different tabs and googling to try and find this 'save and encode' button, but there was no 'save and encode' button on Gordian Knot. Eventually I managed to find the PDF guide to ripping dvds with Gordian Knot, and this said that you need to click 'save and encode' on the video preview window.

It seems that when I had earlier minimized all windows, it had made the Gordian Knot video preview window disappear, so this is why I hadn't found the 'save and encode' button. And the online guides to using Gordian Knot didn't say that the 'save and encode' button was on the video preview window.

So now I had found the 'save and encode' button, I could actually start encoding the ripped DVD files, though the actual encoding process takes ages.

I downloaded and compiled the latest imagick extension, and then imagick seemed to work okay again. I guess the problem was that I had just copied the imagick extension and all the other files over from one user account to a different one. (The old user account name matched my username at Evohosting, the new user account name matches my username at WebFaction). Since when you compile imagick you need to specify the location of ImageMagick (and I had now deleted the old user account), I think this would be why it didn't work.

The weather today was a mixture of sun and cloud. It was very windy all day and also rained a bit. I think there was a good sunset.

Food
Breakfast: Strawberry jam toast sandwich; cup o' tea.
Lunch: Cheese on toast; Lidl or Aldi fake Kettle Chips; Nectarine; plum (from the garden); Time out (single); cup o' tea.
Dinner: Battered Fish portion; buttered peas; potatoes; ground black pepper. Pudding was a raspberry ripple mousse and a milk chocolate digestive. Coffee; piece of Fairtrade fudge.

No comments: