Creating redirects for query string parameters in AWS S3

01/03/13 00:00:00    

By Michael Mealling

Important Update

There is a hard limit of 20 for the number of Routing Rules allowed for a given static website on S3. This means that, while the method used at the end of this article does indeed work, it does not solve the problem if you have more than 20 links to rewrite. AWS is checking on a solution but as of January 16 I have no additional information.

Part of what I'm doing with this blog reboot is figuring out how to turn what was a dynamic website powered by Wordpress, and thus PHP, into a static site running on S3. There are several reasons why I wanted to do this:

1) Static sites are inherently more secure. I just got fed up with keeping both Wordpress and PHP up to date when what I really wanted to do was just write.

2) I wanted to eat the Rails dogfood a bit more

3) Its cheaper and faster. A hell of a lot faster.

The problem is that much of what I had done with the Wordpress blog was based on query parameters. I'd never really bothered with the permalink parameters (i.e. an article link is foo.com/?p=4 vs foo.com/article4.html). So even though its fairly easy to import the old Wordpress articles into Middleman and to put the comments into Discus, none of the old links would work. And that's bad for SEO and just a bad user experience.

So how do you mimic Wordpress' permalink feature where foo.com/?p=4 redirects to an actual link on S3? Its just a 301 redirect so why not create an S3 object and set the objects metadata to force a redirect. So I created an object with the name “?p=4” (which S3 diligently let me do). But you couldn't access it because S3 converted it into escaped form “%3Fp%3D4”. So that doesn't work.

But after digging I found that each bucket configured for serving static websites has a customizable routing policy section in its base configuration. The cool thing is that these policies accept anything and don't attemp to do encoding. So something like this is possible:


    <RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>?p=4</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <ReplaceKeyPrefixWith>
                2013/01/02/predictions-for-2013.html
            </ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    </RoutingRules>

Go ahead try clicking on this URL: http://rocketforge.org/?p-4. It should cause a 301 redirect to an actual article. All based on S3. Not a single line of PHP anywhere.


comments powered by Disqus