سؤال

لدي المهمة التالية: قم بتنزيل ملف باستخدام HTTPS والمصادقة. Indy يبدو أن الطريق للذهاب ولكن لسبب ما لا يعمل حتى الآن. لدي ما يلي في المكان:

  • مكون Tidhttp الذي استخدمه للتنزيل
  • مكون Tiduri يستخدم لإنشاء عنوان URL
  • مكون tidssliohandlersocketopenssl الذي يجب أن يوفر الاتصال الآمن. DLLs المطلوبة موجودة في المجلد الثنائي.

يتطلب الموقع أيضا المصادقة وأدرج المستخدم / تمرير المستخدم في عنوان URL كما في المثال أدناه. باختصار هذا هو الرمز:

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);

باستخدام هذا الرمز أحصل على "قراءة مهلة" استثناء Eidreadtimeout بسرعة كبيرة. اختبار عنوان URL في متصفح يعمل دون مشكلة. أي أفكار حول ما هو مفقود أم ما فعلت خطأ؟

هل كانت مفيدة؟

المحلول

لقد تخلت أخيرا Indy و Openssl واستخدم Wininet للتنزيل. هذا هو التعليمات البرمجية التي عملت بالنسبة لي:

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;

نصائح أخرى

لقد رأيت نفس الشيء. إعداد Tidhttp.ReadTimeout إلى الصفر يعمل على إصلاح المشكلة بالنسبة لي.

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

ستفشل جميع الوظائف ذات الصلة SSL للاتصالات الآمنة ما لم يتم تثبيت بعض المكتبات الإضافية بشكل صحيح.

1.) تحميل المكتبات

2.) Unzip ونسخ كل من DLLs إلى مجلد المشروع الخاص بك (أو في مكان ما في مسار نظامك)

مع هذا الكود الخاص بك من السؤال يعمل بشكل جيد بالنسبة لي.

- reinhard.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top