CI部 平野です。 本記事執筆時は3月ですが花粉で苦しむ方が多いですね。 私は春の花粉はほぼ感じないですが、秋の花粉症が酷くてあまり共感されません。。。
今回はS3を利用してWebサイトをホストしていた時に発生した事象について記載します。
どういう現象?
S3に静的Webページをホスティングしている際に、<https://ドメイン名/ディレクトリ/>というパスへアクセスすると4xxエラーが発生せず、ダウンロード処理が走り空ファイルがダウンロードされてしまう事象が発生しました。
調べたところ、S3の仕様が原因で起こる事象でした。次からはその原因と、実際にどう対処したかをご紹介します
原因
S3の中身はKey-Value ストア型です。つまり「Key=オブジェクトパス」「Value=ファイルデータ」となります。
この前提で考えると、厳密にはS3に「ディレクトリ」という概念は存在しません。私たちが普段ディレクトリとして認識しているものは、システム内部では単なる「ディレクトリ名/ファイル名」というkey(オブジェクトパス)でしかないのです。
よって、S3のマネジメントコンソール上の「フォルダの作成」から新規フォルダを作成するとS3内部では「新規フォルダ名/ 」というkeyのフォルダオブジェクトが1つ作られることになります。このオブジェクトをブラウザ側がダウンロードしてしまったものが今回の事象にあった空ファイルでした。
対処
本事象の対応策の1つとして、S3コンソール上から「フォルダの作成」をしないということが挙げられます。空のフォルダを作成することは即ち「新規フォルダ名/ 」というオブジェクトをS3で作成することと同義だからです。その代わりにディレクトリ構成を維持した状態でファイルをS3にアップロードする必要があります。S3上に「新規フォルダ名/ファイル名」という構成でアップロードすることで、S3は「新規フォルダ名/ファイル名」をkeyとして認識し、「新規フォルダ名/ 」というフォルダオブジェクトを新たに作りません。
下記は実際に「フォルダの作成」で作成したS3オブジェクト「CreateDirectoy」とディレクトリ構成を維持したままファイルをアップロードした「UploadDirectory」の比較です。(ファイル名等は実際の値とは変えています)
「CreateDirectoy」に0バイトのオブジェクトが確認できます。これがフォルダ作成時に作られたフォルダオブジェクトです。一方「UploadDirectory」ではフォルダオブジェクトが存在しないことが確認できました。
$ aws s3 ls s3://hirano-blog-s3/CreateDirectoy/ --sum 2022-02-22 06:45:40 0 2022-03-10 06:43:43 202 xxx.css 2022-03-10 06:49:10 42393 yyy.png Total Objects: 3 Total Size: 42595 $ aws s3 ls s3://hirano-blog-s3/UploadDirectory/ --sum 2022-04-03 03:46:00 33333 111.html 2022-04-03 03:46:00 33221 222.html 2022-04-03 03:46:00 33222 333.html 2022-04-03 03:46:00 2847 index.html Total Objects: 4 Total Size: 102623
では上記の「CreateDirectoy」のように既にフォルダオブジェクトが作られてしまっている場合、フォルダオブジェクトだけを削除することができるのか、そして今回の事象「空ファイルをダウンロードしてしまう」を解消できるのか検証してみました。
$ aws s3 ls s3://hirano-blog-s3/CreateDirectoy/ --sum 2022-02-22 06:45:40 0 2022-03-10 06:43:43 202 xxx.css 2022-03-10 06:49:10 42393 yyy.png Total Objects: 3 Total Size: 42595 $ $ aws s3 rm s3://hirano-blog-s3/CreateDirectoy/ delete: s3://hirano-blog-s3/CreateDirectoy/ $ $ aws s3 ls s3://hirano-blog-s3/CreateDirectoy/ --sum 2022-03-10 06:43:43 202 xxx.css 2022-03-10 06:49:10 42393 yyy.png Total Objects: 2 Total Size: 42595 $
フォルダ毎消えてしまうのではないかと心配しましたが、無事フォルダオブジェクトのみ削除することができました。 この状態でブラウザ側からS3のディレクトリパスを指定すると、空ファイルがダウンロードされることなく4xxエラーが返ってきました。
あとがき
S3がKey-Value ストア型という話を聞いたことはありましたが、普段特に意識することが無かったので思わぬ落とし穴でした。今回ハマってしまったことで、少しは以前よりS3と仲良くなれた気がしますが、、、まだまだS3は底知れぬ存在です。