Google Cloud Storage 分段上传,最后一个块失败 (503)

Jab*_*key 3 javascript urlfetch google-apps-script google-cloud-storage

因此,我尝试使用分段上传将文件上传到 Google Cloud 存储,方法是预先将文件分成块并通过 http put 请求发送。

问题是,当我上传文件的最后一块时,我收到 503 错误,而不是 200 完整消息。

为了简单起见,我使用驱动器中的 jpeg 图像,转换为 blob,然后转换为字节:

var data = DriveApp.getFileById(DriveImageFileId).getBlob().getBytes();
Run Code Online (Sandbox Code Playgroud)

根据文档,我首先请求一个可重复上传 URI。

  var accessToken = OAuth2.0_Access_Token;
  var header = {'X-Upload-Content-Type' : 'image/jpeg'}
  var body = {"name": "filename.jpeg"}  
  var options = {
    'method':'post',
    'contentType':'application/json',
    'oAuthUseToken':'never',  // Disables OAuth1.0 config 
    'muteHttpExceptions':true,
    'headers':header,
    'contentLength': 582381,
    'payload':JSON.stringify(body)
  };

  var response = UrlFetchApp.fetch('https://www.googleapis.com/upload/storage/v1beta2/b/myCloudStoreBucket/o?uploadType=resumable&access_token='+accessToken,options).getHeaders();
  var uploadUrl = response.Location 
Run Code Online (Sandbox Code Playgroud)

这很好用。

我开始将文件字节解析为 256x1024 字节块,并使用上传 URL 通过 http 使用 PUT 进行上传。这不是问题,因为每次我上传一个块时,我都会收到 308 响应,其中包含预期上传的字节数。我可以多次执行此操作,以 256x1024 为单位,上传整个文件直到最后一个块。

这是最后一个块的 UrlFetchApp 选项和标头,例如:

 var options = {
 "method": "put",
 "contentType": "image/jpeg",
 "contentLength": 58093,
 "oAuthUseToken": "never",
 "muteHttpExceptions": true,
 "headers": {
  "Content-Range": "bytes 524287-582380/582381"
 },
 "payload" : <dataBytes>
 }
 var response = UrlFetchApp.fetch(resumeUrl,options);
Run Code Online (Sandbox Code Playgroud)

返回以下内容:

 Response Type: 503
 Response Header:
 {
 "Date": "Wed, 16 Apr 2014 06:08:43 GMT",
 "Content-Length": "0",
 "Alternate-Protocol": "443:quic",
 "Content-Type": "text/html; charset=UTF-8",
 "Server": "HTTP Upload Server Built on Apr 7 2014 11:59:06 (1396897146)"
 }
No Response body or error message.
Run Code Online (Sandbox Code Playgroud)

响应应为 200 文件上传完成。我究竟做错了什么?

Jab*_*key 5

回答自己的问题,因为这个问题正在解决:

所以这里有两个部分是错误的。

  1. 第一个是我最后发送的最后一个文件块短了一个字节。我一直在使用在标头中发送的字节范围来对字节数组进行切片。因此,最后一个字节被丢失。

    通过调整脚本,以便对于最后一个文件块,它捕获最后一个尾随字节,我能够获得 200 HTTP 响应,并且文件已成功上传。

  2. 第二部分错误是 API 返回空白 503,这应该是 服务不可用错误。根据 Cloud Storage 文档,在出现 503 的情况下,您应该尝试以指数方式回退服务。API应该抛出 4xx 文件上传错误,这就是为什么我花了这么长时间才找出这里出了什么问题。上传。

我向 Google Cloud Storage 团队报告了 503 错误,他们将在接下来的几个版本中对其 API 进行修复。