Amazon S3の特殊文字を含んだをオブジェクトキーをオブジェクト URLから参照する

2024.04.04

はじめに

S3 にアップロードした際、特殊文字を含んだファイルのみ想定していた URL で取得できなかったケースがありました。

私のケースではアンパサンド ("&")を含んだファイルをパブリックに公開したバケットから参照する際に、そのままのファイル名では取得できませんでした。

通常であれば以下の形式でオブジェクト URL が発行されます。

https://{S3 バケット名}.s3.{リージョン}.amazonaws.com/{オブジェクト名}

例えば S3 バケット名がtest-bucket、アップロードしたオブジェクト名がhogehoge-&.txtだとすると、以下のようになる想定でした。

https://test-bucket.s3.ap-northeast-1.amazonaws.com/hogehoge-&.txt

しかし、このリンクにアクセスしても Access Denied の画面が表示されます。

こうしたケースがどのような場合に発生するのか調べていこうと思います。

最初にまとめ

  • アンパサンド ("&")などのドキュメント上の特殊な処理を必要とする可能性がある文字を利用する場合に発生する
    • オブジェクト URL は S3 側で自動 URL エンコードされるため、参照する際はエンコード後の文字列を想定する
    • S3 URI やオブジェクトキーは URL エンコード前の文字列が利用される
  • 基本オブジェクトキーにはドキュメント上のセーフ文字を利用する

参照しておくべきドキュメントはこちらです。

オブジェクトキー名の作成 - Amazon Simple Storage Service

基本はドキュメントを参照して、セーフ文字を利用していきましょう。

特殊文字を含んだオブジェクトをアップロード

まずは事象を確認するため、特殊文字を含んだオブジェクトをアップロードします。 今回はhogehoge-&.txtというファイルをアップロードしてみました。

アップロードには問題なく、S3 URI などもhogehoge-&.txtと確認できます。

オブジェクト URL を確認してみると、オブジェクトキーの部分がhogehoge-%26.txtとなっていました。

https://{S3バケット名}.s3.ap-northeast-1.amazonaws.com/hogehoge-%26.txt

この URL をブラウザに入力すると、問題なくファイルをダウンロードできます。

S3 のオブジェクト URL は以下の形式で生成されますが、オブジェクト名に特殊文字含まれると URL として正しく動作しない可能性があるため、S3 側で自動 URL エンコードしてくれるようです。

https://{S3バケット名}.s3.{リージョン}.amazonaws.com/{オブジェクト名}

自動で URL エンコードされることを押さえておかないと、URL エンコード前のオブジェクト URL にアクセスして Access Denied の画面が表示されるので注意しましょう。

その他ドキュメント特殊な処理を必要とする可能性がある文字に記載があるドル記号 ("$")アットマーク ("@")も同じようにアップロードしてみましたが、全て URL エンコードされたオブジェクト URL が表示されました。

記載がある文字列を使用する必要がある場合は、事前にエンコードした URL で参照しましょう。

オブジェクトURLを取得

コンソールではエンコード済みの URL が表示されているので、そのままコピーして利用できます。しかし Python などのコードでオブジェクト URL を取得する場合は、事前に URL エンコードした上で取得しましょう。

Python であれば以下のブログが参考になります。

[Python] Amazon S3のオブジェクトキーとして安全な文字列に変換する | DevelopersIO

URLエンコード済みのファイル名をアップロードしてみる

興味本位で URL エンコード済みのファイル名でアップロードした場合、どのような動作になるのか試してみました。ちなみに%はドキュメント上使用しない方がよい文字となっていますので、利用しないようにしましょう。

hogehoge-&.txtというファイルを URL エンコードするとhogehoge-%26.txtになるため、この URL エンコードしたファイル名をアップロードしてオブジェクト URL を確認してみます。

ファイルはアップロードできましたが、以下のオブジェクト URL ではアクセスできませんでした。

https://{S3バケット名}.s3.ap-northeast-1.amazonaws.com/hogehoge-%26.txt

コンソールのオブジェクト URL を確認してみると、オブジェクトキーがhogehoge-%2526.txtとなっています。なぜか25が増えていますが、どうやら%26を URL エンコードすると%2526になるようです。

動作としては、オブジェクト URL にする際、S3 のサービス側で URL エンコード処理を入れてくれていると思えば良さそうです。

まとめ

特殊文字を使用した時のオブジェクト URL についての動きを確認してみました。

コンソールからオブジェクト URL を参照する際には問題ないですが、Lambda 等で利用する際には URL エンコードしたオブジェクトキーを URL にするよう注意しましょう。

参考