9
votes

Comment télécharger un fichier sur https en utilisant Indy 10 et OpenSSL?

J'ai la tâche suivante: Téléchargez un fichier à l'aide de HTTPS et d'authentification. Indy semble la voie à suivre mais pour une raison quelconque, cela ne fonctionne pas jusqu'à présent. J'ai ce qui suit:

  • Un composant TIDHTTP que j'utilise pour télécharger
  • Un composant Tiduri utilisé pour créer l'URL
  • Un composant TidsSliohandlersocketOpensSL qui devrait fournir la connexion sécurisée. Les DLL requises sont dans le dossier binaire.

    Le site nécessite également une authentification et j'ai inclus l'utilisateur / passe dans l'URL comme dans l'exemple ci-dessous. En bref, il s'agit du code: xxx

    à l'aide de ce code, je reçois un "timeout de lecture" EIDReadTimeout Exception très vite. Test de l'URL dans un navigateur fonctionne sans problème. Des idées sur ce qui manque ou ce que j'ai mal fait?


3 commentaires

Y a-t-il un pare-feu / un proxy entre l'application et le serveur? 'Browser Works' ne signifie pas qu'il existe une connexion Internet directe.


@MJustine Si je regarde dans les paramètres du navigateur, il n'y a pas de proxy défini. En outre, le fait que l'approche gagnette fonctionne sans établir de proxy me dit que ce n'est pas le problème.


N'utilisez pas les propriétés de Tiduri.Username / Mot de passe dans cette situation. Vous devez utiliser les propriétés Tidhttp.Asern / Mot de passe à la place.


3 Réponses :


11
votes

J'ai finalement abandonné Indy et OpenSSL et utilisé Wininet pour le téléchargement. Ceci est le code qui a fonctionné pour moi:

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;


2 commentaires

Un mot de prudence concernant le code ci-dessus: Vous devez toujours utiliser Internet_flag_Reload Paramètre pour forcer un téléchargement à partir du serveur et non le cache.so Je vous conseillerais de changer votre code à: HANL: = InternetOpenurl (HSESSION, PCHAR (FULLURL), nil, 0, internet_flag_reload, 0);


Ajouter winapi.wininnet à utilise .



1
votes

Toutes les fonctions liées à SSL pour les connexions sécurisées échoueront à moins que certaines bibliothèques supplémentaires soient correctement installées.

1.) Bibliothèques de téléchargement

2.) Décompressez et copiez les deux DLL sur votre dossier de projet (ou quelque part dans le chemin de votre système)

avec que votre code de la question fonctionne bien pour moi.

- Reinhard


1 commentaires

Merci pour votre réponse. J'ai eu les dlls en place et il semble qu'ils ont été chargés correctement. Le délai de lecture semble être causé par autre chose. L'approche Wininet fonctionne avec le même serveur.



2
votes

J'ai vu la même chose. Réglage de Tidhttp.readtimeout à zéro résoue le problème pour moi. XXX


2 commentaires

Readtimeout = 0 est la valeur du délai d'attente par défaut et représente un délai d'attente infini.


Oui, mais la définition en code après avoir attaché que l'iohandler semble arrêter l'exception eidreadtimeout d'être lancée. (Au moins dans mon expérience, avec les versions indy qui expédient avec Delphi)