I'm attempting to work with the Google Drive API in Delphi XE2, and thus far, I have just about everything working. One thing I'm struggling with is the multipart upload. When I attempt to upload a file, I get a 503 error. Normally, that should indicate a problem with the server. However, when I send an upload request with the same body and headers to the same URL using fiddler rather than my API, the file is uploaded successfully. This tells me there has to be a problem with my code. This particular function is a mess, but here it is.
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;
The line that causes problems is the lHttpHelper.PostResponse
call. The code for that is shown here:
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;
I'm currently calling the MultipartUpload
function from my test, shown here
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;
Any ideas what might be causing the problems? I'm not even sure what to suspect at this point.