Domanda

Ho il seguente compito: scaricare un file utilizzando HTTPS e l'autenticazione. Indy sembra la strada da percorrere, ma per qualche motivo non funziona così lontano. Ho il seguente al suo posto:

  • un componente TIdHTTP che uso per il download
  • un componente TIdURI utilizzato per creare l'URL
  • un componente TIdSSLIOHandlerSocketOpenSSL che dovrebbe garantire il collegamento sicuro. Le DLL necessarie si trovano nella cartella binario.

Il sito richiede anche l'autenticazione e ho incluso l'utente / passaggio nell'URL come nell'esempio qui sotto. In breve questo è il codice:

URI := TIdURI.Create('https://test.example.com/');
URI.Username := ParamUserName;
URI.Password := ParamPassword;

HTTP := TIdHTTP.Create(nil);
if URI.Protocol = 'https' then
begin
  IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  IOHandler.SSLOptions.Method := sslvSSLv3;
  HTTP.IOHandler := IOHandler;
end;

HTTP.Get(URI.GetFullURI([ofAuthInfo]), FileStream);

Utilizzando questo codice ottengo un'eccezione EIdReadTimeout "Leggi Timeout" molto veloce. Testare l'URL in un browser funziona senza problemi. Tutte le idee su ciò che manca o che cosa ho fatto di sbagliato?

È stato utile?

Soluzione

Alla fine ho abbandonato Indy e OpenSSL e utilizzato WinInet per il download. Questo è il codice che ha funzionato per me:

function Download(URL, User, Pass, FileName: string): Boolean;
const
  BufferSize = 1024;
var
  hSession, hURL: HInternet;
  Buffer: array[1..BufferSize] of Byte;
  BufferLen: DWORD;
  F: File;
begin
   Result := False;
   hSession := InternetOpen('', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) ;

   // Establish the secure connection
   InternetConnect (
     hSession,
     PChar(FullURL),
     INTERNET_DEFAULT_HTTPS_PORT,
     PChar(User),
     PChar(Pass),
     INTERNET_SERVICE_HTTP,
     0,
     0
   );

  try
    hURL := InternetOpenURL(hSession, PChar(URL), nil, 0, 0, 0) ;
    try
      AssignFile(f, FileName);
      Rewrite(f,1);
      try
        repeat
          InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen) ;
          BlockWrite(f, Buffer, BufferLen)
        until BufferLen = 0;
      finally
        CloseFile(f) ;
        Result := True;
      end;
    finally
      InternetCloseHandle(hURL)
    end
  finally
    InternetCloseHandle(hSession)
  end;
end;

Altri suggerimenti

Ho visto la stessa cosa. Impostazione del TIdHTTP.ReadTimeout a zero risolve il problema per me.

...
HTTP.IOHandler := IOHandler;
HTTP.ReadTimeout := 0;

Tutte le funzioni relative SSL per connessioni sicure non riuscirà a meno che alcune librerie aggiuntive siano installati correttamente.

1.) Scarica le librerie

2.) Decomprimere e copiare entrambe le DLL nella cartella di progetto (o da qualche parte nel percorso del vostro sistema)

con il che il codice dalla questione funziona bene per me.

- Reinhard

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top