S3でRedirection Rulesを使ってディレクトリごとにエラーページを変えてみる

2016.07.26

世間がポケモンにわいている中、妖怪ウォッチ3をプレイしている森永です。
ポケモンもやっていますが。。。

S3にはRedirection Rulesという機能があり、example.com/hoge/ にアクセスが来たら、example.com/fuga/ にリダイレクトするといった設定ができます。
実はこれ、ステータスコード(404とか)によってリダイレクトするということも出来るんです。
今回はこの機能を使ってディレクトリ毎にエラーページを変えてみます。

エラーページにリダイレクトすることは可能ですが、リダイレクト先のステータスコードは200番になります。本来は404のエラーページならステータスコードも404となるべきです。そこを許容できる方のみご活用下さい。

S3は以下の様なディレクトリ構造にします。
想定としてはルート以下がPCなどからのアクセス、sp以下がスマホからのアクセスとします。
あくまで想定なのでエージェントを見てリダイレクトなどはしていません。

ルート以下でエラー時にはcommon.htmlへリダイレクトされ、sp以下では、sp.htmlへとリダイレクトされれば成功です。

└ /
 ├ index.html
 ├ sp/
 │ └ index.html
 └ error/
  ├ common.html
  └ sp.html

やってみる

Redirection Rulesは静的ウェブホスティングの機能の一部です。
ひとまず、静的ウェブホスティングを有効化します。
バケットポリシーも忘れずに設定してアクセスできる事を確認しましょう。

S3_Management_Console

$ curl -IL http://hogehoge.s3-website-ap-northeast-1.amazonaws.com/
HTTP/1.1 200 OK
x-amz-id-2: qb+0/JrpR7iODF/Ka5nP/U7EqwidO7k6luvYNVwp34DKoBpGF1+bmt1TxXYXGE1cvcl9gA8KEYQ=
x-amz-request-id: 340717784AD26681
Date: Tue, 26 Jul 2016 08:35:22 GMT
Last-Modified: Tue, 26 Jul 2016 08:05:38 GMT
ETag: "402e7a087747cb56c718bde84651f96a"
Content-Type: text/html
Content-Length: 8
Server: AmazonS3

早速、リダイレクトの設定を行いましょう。
「リダイレクトルールを編集する」をクリックし、テキストエリアを表示します。

S3_Management_Console 2

そこに以下のように設定します。

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
            <KeyPrefixEquals>sp/</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <HostName>hogehoge.s3-website-ap-northeast-1.amazonaws.com</HostName>
            <ReplaceKeyWith>error/sp.html</ReplaceKeyWith>
        </Redirect>
    </RoutingRule>

    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>hogehoge.s3-website-ap-northeast-1.amazonaws.com</HostName>
            <ReplaceKeyWith>error/common.html</ReplaceKeyWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

Conditionでリダイレクトする条件を指定し、Redirectでリダイレクト先を指定します。

キモとなるのはCondition内にある、HttpErrorCodeReturnedEqualsKeyPrefixEqualsです。
HttpErrorCodeReturnedEqualsではステータスコードを指定します。
今回の例で言うと404の時にリダイレクト、という意味となります。

KeyPrefixEqualsではパスを指定します。
HttpErrorCodeReturnedEqualsと組み合わせて使用するとAND条件になります。
sp/以下のディレクトリ、かつステータスコード404の時にリダイレクトする、という設定となります。

また、RoutingRuleは上から順に評価されるようなので、sp/の方を先に記述するようにして下さい。

では試してみます。
まずは、ルート以下で存在しないファイルへアクセスしてみます。

$ curl -IL http://hogehoge.s3-website-ap-northeast-1.amazonaws.com/hoge.html
HTTP/1.1 301 Moved Permanently
x-amz-id-2: RHKYco6aTXjB4edmO0clNRyh6tPlsV9i5zZwn3nl9e6sYPq9FpcepOeL7ijuGFcluGY3Ju2H3Xk=
x-amz-request-id: 2ADF90CE3CBD52D5
Date: Tue, 26 Jul 2016 09:20:25 GMT
Location: http://hogehoge.s3-website-ap-northeast-1.amazonaws.com/error/common.html
Content-Length: 0
Server: AmazonS3

HTTP/1.1 200 OK
x-amz-id-2: Q/KWicXwKUdha6/VCFbg7uCHBARFcJcyLiqHQvEaQMN9T7DG9cD37PLi8FTNIDXoYl7Av8iCgCc=
x-amz-request-id: 52B38CA3FD0CF784
Date: Tue, 26 Jul 2016 09:20:25 GMT
Last-Modified: Tue, 26 Jul 2016 08:53:38 GMT
ETag: "b24dc54d77a0913cf7915b5dba0c11ea"
Content-Type: text/html
Content-Length: 7
Server: AmazonS3

リダイレクトされ、common.html が表示されました!
次に、sp以下で存在しないファイルにアクセスしてみます。

$ curl -IL http://hogehoge.s3-website-ap-northeast-1.amazonaws.com/sp/hoge.html
HTTP/1.1 301 Moved Permanently
x-amz-id-2: sSXyfvnBmtEe1aXF3aFYWfjrsgZOKTOQV/IVvllyzUw2oHB222x41MZmMP1S8I5DpybpFqkII7A=
x-amz-request-id: 2DDA0183C2EC533C
Date: Tue, 26 Jul 2016 09:22:42 GMT
Location: http://hogehoge.s3-website-ap-northeast-1.amazonaws.com/error/sp.html
Content-Length: 0
Server: AmazonS3

HTTP/1.1 200 OK
x-amz-id-2: FKyIdhz5JltnKs3DXXzX1Q6GzEq44MCcQeru5V6T4QVh8rF9C37Hg6+ol5P45X38YXUiybPQIps=
x-amz-request-id: F999F9D0A5B6227F
Date: Tue, 26 Jul 2016 09:22:42 GMT
Last-Modified: Tue, 26 Jul 2016 08:53:38 GMT
ETag: "59b45eb698f1643acbdc0fd957ca72b1"
Content-Type: text/html
Content-Length: 12
Server: AmazonS3

正しくsp.htmlにリダイレクトされましたね!!

最後に

リダイレクト先は同じS3である必要はなく、HostNameで自由に指定できます。
別にエラーファイル保管用のS3を用意するもよし、EC2に投げて処理させるもよし、色々夢が広がります。
リダイレクト先のステータスコードを変えられるようになると嬉しいなぁ…