LoginSignup
3
4

More than 5 years have passed since last update.

GoogleCloudStorageに、curlでResumable Upload メモ

Posted at

流れ

  1. Resumable upload sessionを作成する
  2. 作成したsessionにチャンクをアップロードする。ただし、最終のものを除き、チャンクサイズは256KB(262144 bytes)の倍数である必要がある。
  3. 最後までチャンクがアップロードされると、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までアップロード完了していることが判断できる。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4