delphi - 分段上传 GoogleDrive Api v2 出现 503 错误

标签 delphi delphi-xe2 google-drive-api

我正在尝试在 Delphi XE2 中使用 Google Drive API,到目前为止,我几乎一切正常。我正在努力解决的一件事是分段上传。当我尝试上传文件时,收到 503 错误。通常,这应该表明服务器有问题。但是,当我使用 fiddler 而不是我的 API 将具有相同正文和 header 的上传请求发送到同一 URL 时,文件上传成功。这告诉我我的代码一定有问题。这个特定的函数很困惑,但它就是这样。

function TGoogleDriveApi.MultipartUpload(aStream : TStream; aTitle : string = 'Untitled';
  aDescription : string = ''; mimeType : string = 'application/octet-stream';
  indexableText : IGoogleDriveIndexableText = nil;
  lastViewedByMeDate : string = ''; modifiedDate : string = '';
  parents : IGoogleDriveParentList = nil) : IGoogleDriveFile;
var
  json, url, body, boundry, contentType : string;
  ss : TStringStream;
  ms : TMemoryStream;
  lHttpHelper : IHttpHelper;
  streamBytes : TBytes;
begin
  boundry := 'a_boundry';
  body := '--'+boundry+sLineBreak;
  body := body + 'Content-Type: application/json; charset=UTF-8';
  lHttpHelper := THttpHelper.Create;
  if(Token.IsExpired) then
    Token.Refresh(TokenUrl, OAuth.ClientId, OAuth.ClientSecret);
  url := 'https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart&access_token='+lHttpHelper.UrlEncode(Token.access_token);
  json := '{';
  json := json + '"title": "'+aTitle+'"';
  if(aDescription <> '') then
    json := json + ', "description": "'+aDescription+'"';
  if(lastViewedByMeDate <> '') then
    json := json + ', "lastViewedByMeDate": "'+lastViewedByMeDate+'"';
  json := json + ', "mimeType": "'+mimeType+'"';
  if(modifiedDate <> '') then
    json := json + ', "modifiedDate": "'+modifiedDate+'"';
  json := json + '}';
  body := body + sLineBreak + sLineBreak + json + sLineBreak + sLineBreak + '--'+boundry;
  body := body + sLineBreak + 'Content-Type: '+mimeType + sLineBreak  + sLineBreak;
  body := body + 'some test text from the api' + sLineBreak + sLineBreak + '--'+boundry+'--';

  ss := TStringStream.Create;
  ss.WriteString(body);
  ss.Position := 0;
  ms := TMemoryStream.Create;
  ms.Write(ss,ss.Size);
  SetLength(streamBytes,aStream.Size);
  aStream.Read(streamBytes,aStream.Size);
  ms.Write(streamBytes[0],aStream.Size);
  ss.Clear;
  ss.Position := 0;
  ss.WriteString(sLineBreak + sLineBreak + '--'+boundry+'--');
  ss.Position := 0;
  ms.Write(ss,ss.Size);

  contentType := 'multipart/related; boundary="'+boundry+'"';
  json := lHttpHelper.PostResponse(url,contentType,ms);
  FreeAndNil(ss);
  FreeAndNil(ms);
  Result := nil;
end;

导致问题的行是 lHttpHelper.PostResponse 调用。其代码如下所示:

function THttpHelper.PostResponse(url, contentType : string; aStream : TStream) : string;
var
  lHTTP: TIdHTTP;
  lStream : TStringStream;
  handler : TIdSSLIOHandlerSocketOpenSSL;
begin
  lStream := TStringStream.Create;
  lHTTP := TIdHTTP.Create(nil);
  handler := TidSSLIOHandlerSocketOpenSSL.Create(nil);
  handler.SSLOptions.Method := sslvSSLv3;
  lHTTP.IOHandler := handler;
  try
    lHTTP.Request.ContentType := contentType;
    lHTTP.Post(url,aStream,lStream);
    lStream.Position := 0;
    Result := lStream.ReadString(lStream.Size);
      //except
  finally
    lStream.Free;
    lHTTP.Free;
    handler.Free;

    lStream := nil;
    lHTTP := nil;
    handler := nil;
  end;
end;

我目前正在测试中调用 MultipartUpload 函数,如下所示

procedure TestIGoogleDriveApi.TestMultipartUpload;
var
  ReturnValue : IGoogleDriveFile;
  fs : TFileStream;
begin
  fs := TFileStream.Create('testupload.jpg',fmOpenRead);
  ReturnValue := FIGoogleDriveApi.MultipartUpload(fs,'Test Multipart Image Upload from API.txt','test file','image/jpeg');
  FreeAndNil(fs);
  if(ReturnValue = nil) then
    fail('ReturnValue cannot be nil');
end;

有什么想法可能导致问题吗?我什至不确定此时该怀疑什么。

最佳答案

您需要以某种方式遵循@RobKennedy 的建议。您需要查看线路上发生的情况才能进行调试。尝试将 https 驱动器 URL 替换为 http,然后使用 Wireshark 进行跟踪。

@Hendra 也是正确的,通常您的应用程序需要实现指数退避并重试 500 个错误,尽管我怀疑这不是您的具体问题(还:-))

关于delphi - 分段上传 GoogleDrive Api v2 出现 503 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12609419/

相关文章:

delphi - 在Delphi 7中获取对象的分配地址

delphi - 使用取消和终止处理程序正确构建 ParallelTask​​ (IOmniParallelTask​​)

android - "createFromResourceId()"到哪里去了?

php - google Drive api (PHP) 中不推荐使用身份验证方法

ios - 无法在 iOS 中使用 Google Drive api v3 列出特定文件夹中的文件

delphi - 如何为Delphi的WebBrowser制作自定义菜单?

c# - 使用 Delphi 使用 WCF - 最大字符串内容长度配额 (8192) 错误

sql - 使用 native 客户端驱动程序从 Delphi 代码创建触发器

Delphi 7 应用程序和 Microsoft 安全要点

delphi - 关于 Firemonkey (Delphi) 中的 TidHttp、mshtml、ActiveX、COMObj