how to upload file to dropbox via Delphi 7?
Asked Answered
B

2

7

I try to upload file into dropbox.
I use dropbox api https://www.dropbox.com/developers/reference/api#files-POST

procedure TDropbox.Upload2;
const
  URL = 'https://api-content.dropbox.com/1/files/dropbox/';
var
  Response: String;
  Params: TIdMultipartFormDataStream;
  https: TIdHTTP;
  SslIoHandler: TIdSSLIOHandlerSocket;
begin
  https := TIdHTTP.Create(nil);
  Params := TIdMultipartFormDataStream.Create();
  try
    SslIoHandler := TIdSSLIOHandlerSocket.Create(https);
    SslIoHandler.SSLOptions.Method := sslvTLSv1;
    SslIoHandler.SSLOptions.Mode := sslmUnassigned;

    https.IOHandler := SslIoHandler;

    Params.AddFormField('oauth_signature_method', 'PLAINTEXT');
    Params.AddFormField('oauth_consumer_key', FAppKey);
    Params.AddFormField('oauth_token', FOAuth.AccessToken);
    Params.AddFormField('oauth_signature', FAppSecret + '&' + FOAuth.AccessTokenSecret);

    Params.AddFile('file', 'C:\test.txt', 'application/octet-stream');

    https.Post(URL + 'test.txt', Params);
  finally
    FreeAndNil(https);
    FreeAndNil(Params);
  end;
end;

I got "400 Bad request".
All tokens are correct (other api works well).
How pass parameters for this api?

Bywaters answered 29/1, 2013 at 9:51 Comment(5)
"Since the entire POST body will be treated as the file, any parameters must be passed as part of the request URL. The request URL should be signed just as you would sign any other OAuth request URL." - maybe, this is the issue?Haunt
maybe. I know how to pass parameters, but how put file into request body? https.Post(URL + 'test.txt?oauth_signature_method=PLAINTEXT&oauth_consumer_key='+ FAppKey+'&oauth_token='+FOAuth.AccessToken+'oauth_signature='+FAppSecret + '&' + FOAuth.AccessTokenSecret, Params); - 400 Bad requestBywaters
Try with this URL, and put file as you did before - via Params.AddFile.Haunt
Just a note: "We recommend you use /files_put instead due to its simpler interface."Quasar
To put the file by itself in the POST body, you simply pass the file to TIdHTTP.Post() directly, do not use TIdMultipartFormDataStream at all. TIdHTTP has several overloaded versions of the Post() method. One accepts a filename string as input. Another accepts a non-Multipart TStream as input, such as a TFileStream.Smallscale
S
8

Try this instead:

procedure TDropbox.Upload(const AFileName: String);
const
  API_URL = 'https://api-content.dropbox.com/1/files_put/sandbox/';
var
  URL: String;
  https: TIdHTTP;
  SslIoHandler: TIdSSLIOHandlerSocket;
begin
  URL := API_URL+ExtractFileName(AFileName)
    + '?oauth_signature_method=PLAINTEXT&oauth_consumer_key=' + FAppKey
    + '&oauth_token=' + FOAuth.AccessToken
    + '&oauth_signature=' + FAppSecret + '%26' + FOAuth.AccessTokenSecret;

  https := TIdHTTP.Create(nil);
  try
    SslIoHandler := TIdSSLIOHandlerSocket.Create(https);
    SslIoHandler.SSLOptions.Method := sslvTLSv1;
    SslIoHandler.SSLOptions.Mode := sslmUnassigned;

    https.IOHandler := SslIoHandler;
    https.Post(URL, AFileName);
  finally
    FreeAndNil(https);
  end;
end;
Smallscale answered 29/1, 2013 at 18:32 Comment(0)
B
0
  1. Use %26 instead & in oauth_signature parameter. There is two values in one parameter concated by & symbol.
  2. Pass file via TMemoryStream.

    procedure TDropbox.Upload(const AFileName: String);
    const
      API_URL = 'https://api-content.dropbox.com/1/files_put/sandbox/';
    var
      URL: String;
      Stream: TMemoryStream;
      ShortFileName: String;
      https: TIdHTTP;
      SslIoHandler: TIdSSLIOHandlerSocket;
    begin
      if not FileExists(AFileName) then
      begin
        raise EInOutError.CreateFmt('File %s not found', [AFileName]);
      end;
    
      ShortFileName := ExtractFileName(AFileName);
      URL := API_URL+ShortFileName
        + '?oauth_signature_method=PLAINTEXT&oauth_consumer_key=' + FAppKey
        + '&oauth_token=' + FOAuth.AccessToken
        + '&oauth_signature=' + FAppSecret + '%26' + FOAuth.AccessTokenSecret;
    
      https := TIdHTTP.Create(nil);
      Stream := TMemoryStream.Create;
      try
        SslIoHandler := TIdSSLIOHandlerSocket.Create(https);
        SslIoHandler.SSLOptions.Method := sslvTLSv1;
        SslIoHandler.SSLOptions.Mode := sslmUnassigned;
    
        https.IOHandler := SslIoHandler;
        Stream.LoadFromFile(AFileName);
    
        https.Post(URL, Stream);
      finally
        FreeAndNil(Stream);
        FreeAndNil(https);
      end;
    end;
    
Bywaters answered 29/1, 2013 at 11:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.