概要
データをクライアントとサーバー間で伝送する際にエラーが発生することがあります。COSはMD5検証の方式でアップロードしたデータの完全性を保証することができます。COSサーバーが受信したデータのMD5チェックサムとユーザーが設定したMD5チェックサムが一致した場合のみ、データのアップロードが成功します。
COS内の各オブジェクトには1つのETagが対応しています。ETagはオブジェクトが作成された時点でのオブジェクト内容の情報タグですが、ETagはオブジェクト内容のMD5チェックサムと必ずしも同じではありません。このため、ETagによってダウンロードしたオブジェクトと元のオブジェクトが同じかどうかを検証することはできませんが、 ユーザーはカスタムオブジェクトメタデータ(x-cos-meta-*)を使用することで、ダウンロードしたオブジェクトと元のオブジェクトの整合性検証を実現することができます。
データチェック検証方式
アップロードオブジェクトの検証
COSにアップロードしたオブジェクトとローカルのオブジェクトが一致しているかを検証したい場合、ユーザーはアップロードの際にHTTPリクエストのContent-MD5フィールドを、Base64エンコードを経たオブジェクト内容のMD5チェックサムに設定することができます。このときCOSサーバーはユーザーがアップロードしたオブジェクトを検証し、COSサーバーが受信したオブジェクトのMD5チェックサムとユーザーが設定したContent-MD5が一致した場合のみ、オブジェクトを正常にアップロードします。 ダウンロードオブジェクトの検証
ダウンロードしたオブジェクトと元のオブジェクトが一致しているかを検証したい場合、ユーザーはオブジェクトをアップロードする際に検証アルゴリズムを使用してオブジェクトのチェックサムを計算し、カスタムメタデータによってオブジェクトのチェックサムを設定し、オブジェクトのダウンロード後にオブジェクトのチェックサムを再計算し、カスタムメタデータとの比較によって検証することができます。この方式では、ユーザーはご自身で検証アルゴリズムを選択できますが、同一のオブジェクトについては、アップロードとダウンロードの際に使用する検証アルゴリズムは一致させる必要があります。
APIインターフェースの例
シンプルアップロードリクエスト
以下はユーザーがオブジェクトをアップロードする場合のリクエストの例です。オブジェクトをアップロードする際、Content-MD5を、Base64エンコードを経たオブジェクト内容のMD5チェックサムに設定します。こうすることで、COSサーバーが受信したオブジェクトのMD5チェックサムとユーザーが設定したContent-MD5が一致した場合のみ、オブジェクトのアップロードが正常に行われるようにし、かつカスタムメタデータx-cos-meta-md5をオブジェクトのチェックサムに設定します。
説明:
例で示したものはMD5検証アルゴリズムによって得られたオブジェクトのチェックサムです。ユーザーはご自身で他の検証アルゴリズムを選択することができます。
PUT /exampleobject HTTP/1.1
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
Date: Fri, 21 Jun 2019 09:24:28 GMT
Content-Type: image/jpeg
Content-Length: 13
Content-MD5: ti4QvKtVqIJAvZxDbP/c+Q==
Authorization: q-sign-algorithm=sha1&q-ak=AKID8A0fBVtYFrNm02oY1g1JQQF0c3JO****&q-sign-time=1561109068;1561116268&q-key-time=1561109068;1561116268&q-header-list=content-length;content-md5;content-type;date;host&q-url-param-list=&q-signature=998bfc8836fc205d09e455c14e3d7e623bd2****
x-cos-meta-md5: b62e10bcab55a88240bd9c436cffdcf9
Connection: close
[Object Content]
マルチパートアップロードリクエスト
以下はマルチパートアップロードの初期化リクエストの例です。オブジェクトのパートをアップロードする際、ユーザーはマルチパートアップロードを初期化することによってオブジェクトのカスタムメタデータを設定できます。ここではカスタムメタデータx-cos-meta-md5をオブジェクトのチェックサムに設定します。
POST /exampleobject?uploads HTTP/1.1
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
Date: Fri, 21 Jun 2019 09:45:12 GMT
Authorization: q-sign-algorithm=sha1&q-ak=AKID8A0fBVtYFrNm02oY1g1JQQF0c3JO****&q-sign-time=1561109068;1561116268&q-key-time=1561109068;1561116268&q-header-list=content-length;content-md5;content-type;date;host&q-url-param-list=&q-signature=998bfc8836fc205d09e455c14e3d7e623bd2****
x-cos-meta-md5: b62e10bcab55a88240bd9c436cffdcf9
注意:
マルチパートアップロードのファイルについて、COSは各パートのMD5値のみを検証し、合体後の完全なファイルのMD5値の計算は行いません。
オブジェクトダウンロードの応答
以下はユーザーがオブジェクトダウンロードリクエストを送信後に取得する応答の例です。ユーザーは応答の中からオブジェクトのカスタムメタデータx-cos-meta-md5を取得することができ、オブジェクトのチェックサムを再計算してそのカスタムメタデータとの比較を行うことで、ダウンロードしたオブジェクトと元のオブジェクトが一致しているかを検証できます。
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 13
Connection: close
Accept-Ranges: bytes
Cache-Control: max-age=86400
Content-Disposition: attachment; filename=example.jpg
Date: Thu, 04 Jul 2019 11:33:00 GMT
ETag: "b62e10bcab55a88240bd9c436cffdcf9"
Last-Modified: Thu, 04 Jul 2019 11:32:55 GMT
Server: tencent-cos
x-cos-request-id: NWQxZGUzZWNfNjI4NWQ2NF9lMWYyXzk1NjFj****
x-cos-meta-md5: b62e10bcab55a88240bd9c436cffdcf9
[Object Content]
SDKの例
次に、Python SDKを例に、オブジェクトの検証方法についてご説明します。完全なサンプルコードは次のとおりです。
説明:
コードはPython 2.7ベースです。Python SDKの詳細な使用方法については、Python SDKのオブジェクトの操作ドキュメントをご参照ください。 1. 初期化設定
SecretId、SecretKey、Regionを含むユーザー属性を設定し、クライアントオブジェクトを作成します。
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from qcloud_cos import CosServiceError
from qcloud_cos import CosClientError
import sys
import os
import logging
import hashlib
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
secret_id = os.environ['COS_SECRET_ID']
secret_key = os.environ['COS_SECRET_KEY']
region = 'ap-beijing'
token = None
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token)
client = CosS3Client(config)
2. シンプルアップロードオブジェクトの検証
(1)オブジェクトのチェックサムの計算
MD5検証アルゴリズムによってオブジェクトのチェックサムを取得します。ユーザーはご自身で他の検証アルゴリズムを選択することができます。
object_body = 'hello cos'
md5 = hashlib.md5()
md5.update(object_body)
md5_str = md5.hexdigest()
(2)オブジェクトのシンプルアップロード
コード内にEnableMD5=Trueと表示されていればMD5検証が有効になっており、Python SDKがContent-MD5を計算します。有効にするとアップロードの消費時間が増加し、COSサーバーが受信したオブジェクトのMD5チェックサムとユーザーが設定したContent-MD5が一致した場合のみ、オブジェクトのアップロードが正常に行われます。
x-cos-meta-md5はユーザー定義のパラメータです(カスタムパラメータ名の形式はx-cos-meta-*)。このパラメータはオブジェクトのMD5チェックサムを表します。
response = client.put_object(
Bucket='examplebucket-1250000000',
Body='hello cos',
Key='example-object-1',
EnableMD5=True,
Metadata={
'x-cos-meta-md5' : md5_str
}
)
print 'ETag: ' + response['ETag']
(3)オブジェクトのダウンロード
オブジェクトをダウンロードし、ユーザー定義のパラメータを取得します。
response = client.get_object(
Bucket='examplebucket-1250000000',
Key='example-object-1'
)
fp = response['Body'].get_raw_stream()
download_object = fp.read()
print "get object body: " + download_object
print 'ETag: ' + response['ETag']
print 'x-cos-meta-md5: ' + response['x-cos-meta-md5']
(4) オブジェクトの検証
オブジェクトのダウンロードに成功後、ユーザーはオブジェクトのチェックサムを再計算し(検証アルゴリズムはオブジェクトのアップロード時のものと一致させます)、ユーザー定義のパラメータx-cos-meta-md5と比較し、ダウンロードしたオブジェクトとアップロードしたオブジェクトの内容が一致するかどうかを検証します。
md5 = hashlib.md5()
md5.update(download_object)
md5_str = md5.hexdigest()
print 'download object md5: ' + md5_str
if md5_str == response['x-cos-meta-md5']:
print 'MD5 check OK'
else:
print 'MD5 check FAIL'
3. マルチパートアップロードオブジェクトの検証
(1)オブジェクトのチェックサムの計算
オブジェクトの分割をシミュレートし、オブジェクト全体のチェックサムを計算します。以下ではMD5検証アルゴリズムによってオブジェクトのチェックサムを取得しますが、ユーザーはご自身で他の検証アルゴリズムを選択することができます。
OBJECT_PART_SIZE = 1024 * 1024
OBJECT_TOTAL_SIZE = OBJECT_PART_SIZE * 1 + 123
object_body = '1' * OBJECT_TOTAL_SIZE
md5 = hashlib.md5()
md5.update(object_body)
md5_str = md5.hexdigest()
(2)マルチパートアップロードの初期化
マルチパートアップロードの初期化の際、カスタムパラメータx-cos-meta-md5を設定し、オブジェクト全体のMD5チェックサムをパラメータの内容とします。
response = client.create_multipart_upload(
Bucket='examplebucket-1250000000',
Key='exampleobject-2',
StorageClass='STANDARD',
Metadata={
'x-cos-meta-md5' : md5_str
}
)
upload_id = response['UploadId']
(3)オブジェクトのマルチパートアップロード
オブジェクトのマルチパートアップロードは、オブジェクトを複数のパートに分割してアップロードを行うもので、最大10000パートの分割をサポートします。各パートのサイズは1MB~5GBで、最後のパートは1MB未満とすることができます。マルチパートアップロードの際は、各パートのPartNumber(番号)を設定する必要があります。パートの検証はEnableMD5=Trueで有効化でき、有効にするとアップロードの消費時間が増加します。このときPython SDKは各パートのContent-MD5を計算し、COSサーバーが受信したオブジェクトのMD5チェックサムとContent-MD5が一致した場合のみ、パートのアップロードを正常に行います。アップロードに成功すると、各パートのETagが返されます。
part_list = list()
position = 0
left_size = OBJECT_TOTAL_SIZE
part_number = 0
while left_size > 0:
part_number += 1
if left_size >= OBJECT_PART_SIZE:
body = object_body[position:position+OBJECT_PART_SIZE]
else:
body = object_body[position:]
position += OBJECT_PART_SIZE
left_size -= OBJECT_PART_SIZE
response = client.upload_part(
Bucket='examplebucket-1250000000',
Key='exampleobject-2',
Body=body,
PartNumber=part_number,
UploadId=upload_id,
EnableMD5=True
)
etag = response['ETag']
part_list.append({'ETag' : etag, 'PartNumber' : part_number})
print etag + ', ' + str(part_number)
(4)マルチパートアップロードの完了
すべてのパートのアップロードが完了した後、マルチパートアップロード完了操作を行う必要があります。各パートのETagとPartNumberをそれぞれ対応させ、COSサーバーを使用してパートの正確性を検証します。マルチパートアップロードの完了後に返されるETagは合体後のオブジェクトの一意のタグ値を表すもので、オブジェクト内容全体のMD5チェックサムを表すものではありません。このためオブジェクトをダウンロードする際は、カスタムパラメータによって検証を行ってください。
response = client.complete_multipart_upload(
Bucket='examplebucket-1250000000',
Key='exampleobject-2',
UploadId=upload_id,
MultipartUpload={
'Part' : part_list
},
)
print "ETag: " + response['ETag']
print "Location: " + response['Location']
print "Key: " + response['Key']
(5)オブジェクトのダウンロード
オブジェクトをダウンロードし、ユーザー定義のパラメータを取得します。
response = client.get_object(
Bucket='examplebucket-1250000000',
Key='exampleobject-2'
)
print 'ETag: ' + response['ETag']
print 'x-cos-meta-md5: ' + response['x-cos-meta-md5']
(6)オブジェクトの検証
オブジェクトのダウンロードに成功後、ユーザーはオブジェクトのMD5チェックサムを再計算し、ユーザー定義のパラメータx-cos-meta-md5と比較し、ダウンロードしたオブジェクトとアップロードしたオブジェクトの内容が一致するかどうかを検証します。
fp = response['Body'].get_raw_stream()
DEFAULT_CHUNK_SIZE = 1024*1024
md5 = hashlib.md5()
chunk = fp.read(DEFAULT_CHUNK_SIZE)
while chunk:
md5.update(chunk)
chunk = fp.read(DEFAULT_CHUNK_SIZE)
md5_str = md5.hexdigest()
print 'download object md5: ' + md5_str
if md5_str == response['x-cos-meta-md5']:
print 'MD5 check OK'
else:
print 'MD5 check FAIL'
この記事はお役に立ちましたか?