mlissner
mlissner

Reputation: 18206

Redirect homepage in S3 Routing Rules

I'm using S3 routing rules to deprecate an old domain, routing the traffic to a new domain. So, the old domain was product.com, and the new location is my-organization.com/product/.

I am using routing rules to redirect pages. So, I have a rule like this that redirects the FAQ:

    <Condition>
        <KeyPrefixEquals>faq</KeyPrefixEquals>
    </Condition>
    <Redirect>
        <Protocol>https</Protocol>
        <HostName>my-organization.com</HostName>
        <ReplaceKeyPrefixWith>product/faq</ReplaceKeyPrefixWith>
        <HttpRedirectCode>301</HttpRedirectCode>
    </Redirect>

This works well!

The one thing left to do is redirect the old homepage to the product page. I've tried using / to match the homepage:

<KeyPrefixEquals>/</KeyPrefixEquals>

But it doesn't seem to match anything. And I've tried matching on the empty key:

<KeyPrefixEquals></KeyPrefixEquals>

But that matches everything. Is there a way to just redirect the homepage in S3 routing rules? What I want is something like:

    <Condition>
        <KeyPrefixEquals>/</KeyPrefixEquals>
    </Condition>
    <Redirect>
        <Protocol>https</Protocol>
        <HostName>my-organization.com</HostName>
        <ReplaceKeyPrefixWith>product/</ReplaceKeyPrefixWith>
        <HttpRedirectCode>301</HttpRedirectCode>
    </Redirect>

Thanks!

Upvotes: 2

Views: 3702

Answers (1)

Michael - sqlbot
Michael - sqlbot

Reputation: 179364

The root of a bucket isn't /, it's empty string. An empty key prefix wouldn't do exactly what you want, since everything has a prefix that matches an empty string (because LEFT(${some_string},LENGTH('')) == '', regardless of the content of ${some_string}), so such a rule wouldn't match only the root, in any event. It would match everything.

There is no way to specifically redirect the root page only, but here's the workaround that I've been using that works well. Place this as your last routing rule (since they're matched in order, and this one does indeed match everything that hasn't already been matched, if there's not already a page there).

<RoutingRule>
    <Condition>
        <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
        <ReplaceKeyPrefixWith>product/</ReplaceKeyPrefixWith>
        <Protocol>https</Protocol>
        <HostName>new-site.example.com</HostName>
    </Redirect>
</RoutingRule>

You should not have public listing of the bucket enabled, but if you do, you'll need to replace 403 with 404. If you have an index document, you'll need to remove it.

Essentially, for any request that would be denied due to the lack of a public page at that path, product/ gets appended so http://bucket.example.com/ becomes https://new-site.example.com/product/.

Similarly, http://bucket.example.com/some/random/file.txt will redirect to https://new-site.example.com/product/some/random/file.txt but the old page was already invalid, so the new page will be invalid, so nothing lost/nothing gained. Since rules are matched in order, this rule shouldn't break anything else if you add it last.

Or, depending on the grand scheme of what you're actually needing to do, this rule may actually be the only redirect rule you need, once you remove the old content from the bucket.

Upvotes: 2

Related Questions