S3 + Content-Encoding メタデータについて
Contents
概要
- S3 にobject をアップロードする際に、Objectにメタデータを設定することができます。また、Objectをアップロード後にメタデータを編集することができます。
- 先日、S3 コンソールからObject をダウンロードした際の挙動が異なったため、メタデータを調査しました。備忘録として記事にします。
Objectにメタデータを付けてS3にアップロードする
- ローカルにgzip圧縮されたファイルを2つ準備しました。ファイルサイズは、gzip圧縮された状態で3.2KB となります。
$ file testfile*
testfile1.gz: gzip compressed data, was "testfile1", last modified: Thu Mar 11 16:04:43 2021, from Unix
testfile2.gz: gzip compressed data, was "testfile1", last modified: Thu Mar 11 16:04:43 2021, from Unix
- aws s3 cpコマンドを使って、S3 バケットにObject をアップロードします。1つ目は"Content-Encoding"のメタデータ指定なし、2つ目はメタデータに“Content-Encoding"を"gzip"で指定してアップロードします。
$ BUCKET=niikawa-bucket
$ PREFIX=upload
$ aws s3 ls s3://${BUCKET}/${PREFIX}/
2021-03-12 01:08:23 0
$ aws s3 cp testfile1.gz s3://${BUCKET}/${PREFIX}/
upload: ./testfile1.gz to s3://niikawa-bucket/upload/testfile1.gz
$ aws s3 cp testfile2.gz s3://${BUCKET}/${PREFIX}/ --content-encoding "gzip"
upload: ./testfile2.gz to s3://niikawa-bucket/upload/testfile2.gz
$ aws s3 ls s3://${BUCKET}/${PREFIX}/
2021-03-12 01:08:23 0
2021-03-12 01:28:50 3236 testfile1.gz
2021-03-12 01:29:05 3236 testfile2.gz
Objectのメタデータを確認する/編集する
- aws s3api head-objectコマンドを使って、Objectに設定されているメタデータを確認します。1つ目のObject には“ContentType" のみ設定され、2つ目のObject には “ContentType" および “ContentEncoding" が設定されました。
$ aws s3api head-object --bucket ${BUCKET} --key ${PREFIX}/testfile1.gz
{
"AcceptRanges": "bytes",
"LastModified": "Thu, 11 Mar 2021 16:28:50 GMT",
"ContentLength": 3236,
"ETag": "\"74470dc2698ca9be9c44281cf04fbab5\"",
"VersionId": "null",
"ContentType": "binary/octet-stream",
"Metadata": {}
}
$ aws s3api head-object --bucket ${BUCKET} --key ${PREFIX}/testfile2.gz
{
"AcceptRanges": "bytes",
"LastModified": "Thu, 11 Mar 2021 16:29:05 GMT",
"ContentLength": 3236,
"ETag": "\"74470dc2698ca9be9c44281cf04fbab5\"",
"VersionId": "null",
"ContentEncoding": "gzip",
"ContentType": "binary/octet-stream",
"Metadata": {}
}
- 次に、コンソールからObjectに設定されているメタデータを確認します。
- “upload/testfile1.gz" は、下記のメタデータが設定されています。
- “upload/testfile2.gz" は、下記のメタデータが設定されています。
- また、Objectに設定されているメタデータは、[編集する]のボタンを押して編集することも可能です。
Content-Encoding メタデータありのObjectをダウンロード
- コンソール(Webブラウザ)から、先ほどアップロードしたObjectをどちらもダウンロードします。S3 上ではgzip圧縮されて3.2KB のファイルサイズでしたが、ダウンロード後は、"testfile2.gz" のみサイズが変わっていることが分かります。
- fileコマンドで確認すると、"testfile1.gz" はgzip圧縮されたファイルですが、"testfile2.gz" は展開されたテキストファイルであることが分かりました。
- 拡張子は同じ"gz"ですが、2つ目のObjectには“ContentEncoding"メタデータが“gzip"に設定されていたため、Webブラウザからのダウンロード動作で自動的に解凍まで行われた様です。
$ ls -l
total 108
-rwxrwxrwx 1 niikawa niikawa 3236 Mar 12 01:41 testfile1.gz
-rwxrwxrwx 1 niikawa niikawa 102425 Mar 12 01:41 testfile2.gz
$ file testfile*
testfile1.gz: gzip compressed data, was "testfile1", last modified: Thu Mar 11 16:04:43 2021, from Unix
testfile2.gz: ASCII text, with very long lines
$ gunzip testfile2.gz
gzip: testfile2.gz: not in gzip format
- 次は、aws s3 cpコマンドでダウンロードします。aws cliを使用した場合、ファイルサイズはどちらも3.2KB であり、fileコマンドで確認してもgzip圧縮されたファイルであることが分かります。ダウンロードの方法によって、ファイルに対する挙動が変わりました。
$ aws s3 cp s3://${BUCKET}/${PREFIX}/testfile1.gz .
download: s3://niikawa-bucket/upload/testfile1.gz to ./testfile1.gz
$ aws s3 cp s3://${BUCKET}/${PREFIX}/testfile2.gz .
download: s3://niikawa-bucket/upload/testfile2.gz to ./testfile2.gz
$ ls -l
total 8
-rw-r--r-- 1 niikawa niikawa 3236 Mar 12 01:28 testfile1.gz
-rw-r--r-- 1 niikawa niikawa 3236 Mar 12 01:29 testfile2.gz
$ file testfile*
testfile1.gz: gzip compressed data, was "testfile1", last modified: Thu Mar 11 16:04:43 2021, from Unix
testfile2.gz: gzip compressed data, was "testfile1", last modified: Thu Mar 11 16:04:43 2021, from Unix
最後に
- きっかけは、CloudFront のアクセスログを調査するタイミングで発見しました!! CloudFront はアクセスログを有効にすると、S3 にgzip圧縮されたログを格納することができます。先日コンソール(Webブラウザ)を使ってgzip圧縮されたログファイルをダウンロードすると、なぜかダウンロード後に拡張子が"gz" にも関わらず、gzip圧縮が解凍されていました。
- CloudFront のアクセスログの場合は、"ContentEncoding" ではありませんが、Objectに設定されているメタデータによって動作が変わることに気が付きました。コンソール(Webブラウザ)からgzip圧縮されたObjectをダウンロードする場合は、Object に設定されているメタデータによって、Webブラウザの挙動が変わりますので覚えておいてください。