谷歌云存储多部分上传,最后一块失败(503)

Google Cloud Storage Multipart Upload, with Last Chunk Failing (503)

本文关键字:一块 失败 最后 存储 多部 谷歌      更新时间:2023-09-26

因此,我尝试使用多部分上传将文件上传到谷歌云存储,方法是事先将文件分成块,并通过http put请求发送。

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

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

var data = DriveApp.getFileById(DriveImageFileId).getBlob().getBytes();

根据文档,我首先请求一个可重复的上传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 

这很好用。

我开始将文件字节解析为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);

返回以下内容:

 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.

响应应该是200文件上传完成。我做错了什么?

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

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

  1. 第一个是我最后发送的最后一个文件块是一个字节短的我一直在使用我在标头中发送的字节范围对字节数组进行切片。最后一个字节被遗漏,因为这一点。

    通过调整脚本,使得对于最后一个文件块最后一个尾随字节,我得到了200个HTTP响应文件已成功上载。

  2. 第二部分错误是API返回了空白503,这应该是服务不可用错误。根据云存储文档,在503的情况下,您应该尝试指数级地退出服务。API本应抛出4xx文件上载错误,这就是为什么我花了这么长时间才找到上载错误的原因。

我向谷歌云存储团队报告了503错误,他们将在接下来的几个版本中修复他们的API。