как загрузить файл в Dropbox через Delphi 7?

Я пытаюсь загрузить файл в Dropbox.
Я использую 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;

Я получил «400 Bad request».
Все жетоны правильны (другие api хорошо работают). Как передать параметры для этого api?

6
nl ja de
Чтобы поместить файл в тело POST, вы просто передаете файл в TIdHTTP.Post() напрямую, не используйте TIdMultipartFormDataStream вообще. TIdHTTP имеет несколько перегруженных версий метода Post() . В качестве ввода принимается строка имени файла. Другой принимает не-Multipart TStream как вход, например TFileStream .
добавлено автор Remy Lebeau, источник
«Поскольку весь орган POST будет рассматриваться как файл, любые параметры должны быть переданы как часть URL-адреса запроса. URL-адрес запроса должен быть подписан так же, как вы подписываете любой другой URL-адрес запроса OAuth». - может, это проблема?
добавлено автор Nickolay Olshevsky, источник
Попробуйте с этим URL-адресом и поместите файл так же, как и раньше, через Params.AddFile.
добавлено автор Nickolay Olshevsky, источник
Просто примечание: «Мы рекомендуем использовать/files_put вместо этого из-за более простого интерфейса».
добавлено автор kobik, источник
может быть. Я знаю, как передавать параметры, но как положить файл в тело запроса? https.Post (URL + 'test.txt? oauth_signature_method = PLAINTEXT & oauth_consumer_ke & zwnj; y =' + FAppKey + '& oauth_token =' + FOAuth.AccessToken + 'oauth_signature = & zwnj;' + FAppSecret + '&' + FOAuth.AccessTokenSecret, Params); - 400 Неверный запрос
добавлено автор barbaris, источник

2 ответы

Попробуйте это вместо этого:

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;
7
добавлено
  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;
    
0
добавлено
Пожалуйста, отформатируйте свой код
добавлено автор David Heffernan, источник
Delphi & Lazarus
Delphi & Lazarus
274 участник(ов)

Чат про Delphi и Lazarus