サマリ
S3へのファイルアップロードをしたあとに、そのファイルの正当性を確認したいというケースはよくあるのだろう。恥ずかしながらちゃんとやったことなかったけど。
ということでどうやって実現するのがいいかと調べてみたところ、 S3へのPUT系のAPIには、リクエストのヘッダの中に、ファイルのMD5値を入れて送ると、PUT完了時にS3側でアップロードされたファイルのMD5値を取って検証をしてくれる 機能があった。超便利。
こんな感じにリクエストヘッダにファイルのMD5値を埋め込む。
Content-MD5: YOUR_FILE_MD5
MD5の検証に失敗すると以下のようなエラーが返ってくる。
Error Code | Description | HTTP Status Code |
---|---|---|
InvalidDigest | The Content-MD5 you specified is not valid. | 400 Bad Request |
下記のように、PubObjectにもUploadPart(MultiPartUpload時の個々のパートのアップロード用API)にもその機能があることは下記のようにドキュメントで確認できる。
PubObject
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
UploadPart
http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html
To ensure that data is not corrupted traversing the network, use the Content-MD5 header. When you use this header, Amazon S3 checks the object against the provided MD5 value and, if they do not match, returns an error. Additionally, you can calculate the MD5 while putting an object to Amazon S3 and compare the returned ETag to the calculated MD5 value.
どう使うのか
REST APIを生で使っているのであれば自分でContent-MD5を生成してヘッダに含めてやればよいと思うが、AWSが提供するツールを使う分には、ローカルでのMD5計算からヘッダに含めるところまでの実装がある程度カバーされている。すべての言語のSDKでカバーされているかは確認していないので注意。
AWS SDK for Java
ここで実装されているのが確認できる。
https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/AmazonS3Client.java
boto
コードは見てないけどアップロード中の動作をdebugしてみて、確かにContent-MD5がPutObject時にもUploadPart時にも付与されるのを確認した。指定したディレクトリ内のファイルをS3にまるまるSyncするツールを書いてみた。DynamoDBをロックマネージャーとして使うで書いたものにMultiPartの機能を付けただけ、だけれども。
https://gist.github.com/imaifactory/6132f8a60461584b4613
s3put
botoに同梱されているs3putでもContent-MD5を付与してくれるのを確認した。
awscli
aws s3api put-object
ではContent-MD5が付くのを確認。aws s3 (cp|sync)
では残念ながらContent-MD5は、デフォルトではつかないようだ。
Disclaimer
この投稿は私個人のメモであり、所属する組織や会社を代表するものではありません。