流れ
- Resumable upload sessionを作成する
- 作成したsessionにチャンクをアップロードする。ただし、最終のものを除き、チャンクサイズは256KB(262144 bytes)の倍数である必要がある。
- 最後までチャンクがアップロードされると、GCS上でオブジェクトとして認識される。
なお、GCS JSON API(v1)にて。
例
使うファイル
786432(bytes) chunk1.txt
213568(bytes) chunk2.txt
を結合して、file.txtを作る、とする。
Resumable upload sessionの作成
curl -v \
-H "Authorization: Bearer <access_token>" \
-H "Content-Length: 0" \
-H "X-Upload-Content-Type: text/plain;charset=utf-8" \
-H "X-Upload-Content-Length: 1000000" \
-X POST \
"https://www.googleapis.com/upload/storage/v1/b/<bucket>/o?uploadType=resumable&name=file.txt"
すると
< HTTP/1.1 200 OK
< X-GUploader-UploadID: AEnB2Uoatj_...
< Location: https://www.googleapis.com/upload/storage/v1/b/<bucket>/o?uploadType=resumable&name=file.txt&upload_id=AEnB2Uoatj_...
<
な感じのレスポンスが返る。
AEnB2Uoatj_...
が、このオブジェクトへのResumable upload sessionを表すIDとなる。
なお、sessionは一週間有効な模様。document link
またOAuth2 access_tokenの取得は
http://qiita.com/giiko_/items/b0b2ff41dfb0a62d628b
がわかりやすい。
チャンクアップロード
chunk1.txtをアップロードする。
curl -v \
-H "Authorization: Bearer <access_token>" \
-H "Content-type: text/plain;charset=utf-8" \
-H "Content-Range: bytes 0-786431/1000000" \
-H "Content-Length: 786432" \
-H "Expect: ''" \
-X PUT \
--data-binary '@chunk1.txt' \
"https://www.googleapis.com/upload/storage/v1/b/<bucket>/o?uploadType=resumable&name=file.txt&upload_id=AEnB2Uoatj_..."
アップロードサイズは256KBの倍数になるように注意する。
中途半端なサイズは切断される。また数byteなど、小さすぎるサイズも弾かれる。
また、Content-Range: bytes 0-786431/1000000
のように、範囲の末尾の指定は、
アップロードサイズ-1 になることに注意。
ちなみに、Expect: ''
は、リクエストボディのサイズが大きいと、curlが自動で Expect: 100-continue
を付けてくれるのを抑止するため。
レスポンスは、以下のような感じ
< HTTP/1.1 308 Resume Incomplete
< X-GUploader-UploadID: AEnB2Uoatj_...
< Range: bytes=0-786431
< X-Range-MD5: ...
< Content-Length: 0
308 Resume Incomplete
で、オブジェクトが未完成なことが示される。
残りのchunk2.txtをアップロードする。
curl -v \
-H "Authorization: Bearer <access_token>" \
-H "Content-type: text/plain;charset=utf-8" \
-H "Content-Range: bytes 786432-999999/1000000" \
-H "Content-Length: 213568"
-H "Expect: ''" \
-X PUT \
--data-binary '@chunk2.txt' \
"https://www.googleapis.com/upload/storage/v1/b/<bucket>/o?uploadType=resumable&name=file.txt&upload_id=AEnB2Uoatj_..."
すると、
< HTTP/1.1 200 OK
< X-GUploader-UploadID: AEnB2Uoatj_...
な感じのレスポンスが返り、
オブジェクトのアップロードが完了したことがしめされる。
アップロード中断したオブジェクトの状態を知りたい
curl -v \
-H "Authorization: Bearer <access_token>" \
-H "Content-Length: 0" \
-H "Content-Range: bytes */1000000" \
-X PUT \
"https://www.googleapis.com/upload/storage/v1/b/<bucket>/o?uploadType=resumable&name=file.txt&upload_id=AEnB2Uoatj_..."
すると、
< HTTP/1.1 308 Resume Incomplete
< X-GUploader-UploadID: AEnB2Uoatj_...
< Range: bytes=0-786431
< X-Range-MD5: ...
< Content-Length: 0
なレスポンスが返り、786432bytesまでアップロード完了していることが判断できる。