@interface AQBlog : NSBlog @end

Tutorials, musings on programming and ePublishing

Redirection on Octopress and Heroku


For a little while now I've had notifications from gaug.es that a number of inbound links were getting HTTP 404 errors. This all stemmed from the fact that I reassigned this domain from a Tumblog (still accessible at tumblr.alanquatermain.me, btw) and ported all the relevant (i.e. longer-form) posts across from that source. There were still a few links out there which were pointing to the old Tumblr articles, though, which no longer worked.

What to do?

Well, most of the traffic was coming from Stack Overflow, where I have enough reputation that I could simply edit any comments or posts which linked to my site to update the link targets. There were still a few others though, some of which seemed to be coming directly from folks' bookmarks or bit.ly URLs or similar, which I couldn't affect. There were even a few from other people's blogs (I know– inconceivable!).

I did a little digging (a very little) and turned up this rather wonderful and informative post by Adam Wiggall. As it transpires, it's quite easy to achieve what I needed with a little Rack magic:

  1. Install the rack-rewrite gem: add gem rack-rewrite to your Gemfile.
  2. Edit config.ru to require the new gem and install some HTTP 301 handlers as appropriate:
require 'bundler/setup'
require 'sinatra/base'
require 'rack-rewrite'
# The project root directory
$root = ::File.dirname(__FILE__)
use Rack::Rewrite do
r301 %r{^/post/114613488/lockless-lazily-initialized-static-global-variables/?$}, '/2009/05/28/lockless-lazily-initialized-static-slash-global-variables/'
r301 %r{^/post/528737778/aqgridview-lives-for-my-ipad-dev-camp-hackathon/?$}, '/2010/04/17/aqgridview-lives/'
r301 %r{^/post/45422432268/on-two-occasions-i-have-been-asked-pray-mr/?$}, 'http://tumblr.alanquatermain.me/post/45422432268/on-two-occasions-i-have-been-asked-pray-mr'
r301 %r{^/post/3054286645/apple-states-the-obvious-and-inevitable/?$}, '/2011/02/01/apple-states-the-obvious-and-inevitable/'
r301 %r{^/post/1670154581/lesson-for-today/?$}, '/2010/11/24/lesson-for-today/'
class SinatraStaticServer < Sinatra::Base
run SinatraStaticServer
  1. Fire it up, and visit a previously-invalid URL, such as http://blog.alanquatermain.me/post/114613488/lockless-lazily-initialized-static-global-variables
  2. Be AMAZED as the blog automatically takes you to the correct location!

As was pointed out in the comments, there's a potentially better way using nginx's own methods, rather than relying on the application server to do all the work. Heroku's documentation is lacking as to whether that's feasible on their platform, however, and there's no telling whether, if it works today, it will continue to do so (their use of nginx is what we in the software business would call an implementation detail).

Scoping to a given version of a user-configured web application stack though? That should keep working.