Скачивание файла в Delphi с использованием WinInet (http/https)
Писал под свои нужды, может кому пригодится.
Функция возвращает запись, содержащую ответ сервера, включая код и заголовок ответа.
Код Delphi:
... type tPageOpenMethod = (tpomGet,tpomPost); type tPageStatus = record code: ansistring; err: word; header: AnsiString; end; type tRequestData = record Connection: AnsiString; UserAgent: AnsiString; Referer: AnsiString; Origin: AnsiString; ContentType: AnsiString; Accept: AnsiString; AcceptLanguage: AnsiString; AcceptEncoding: AnsiString; Cookie: AnsiString; CustomHeaders: tStringList; Body: AnsiString; end; ... function WiOpenURL(Method:tPageOpenMethod; RequestData:tRequestData; URL_Base, URL_Page:WideString): tPageStatus; var hInet, hCon, hReq: HINTERNET; Status, StatusSize, Index: DWORD; bytes, b, posi: Cardinal; ResponseString: AnsiString; dwFlag: Cardinal; URL_base_c: WideString; tPS: tPageStatus; fMethod: PChar; fFlag: Cardinal; Header: WideString; UA: AnsiString; Response: array [0..2047] of WideChar; ResponseL: longword; EndPos: longword; i: longword; begin ResponseL:=SizeOf(Response); Response:=''; if (Method=tpomGet) then fMethod:='GET' else fMethod:='POST'; fFlag:= INTERNET_FLAG_RELOAD or INTERNET_FLAG_SECURE or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_IGNORE_CERT_DATE_INVALID; if (RequestData.Connection='keep-alive') then fFlag:=fFlag or INTERNET_FLAG_KEEP_CONNECTION; if (AnsiPos('://',URL_Base)>0) then URL_base_c:=Copy(URL_Base,AnsiPos('://',URL_Base)+3,length(URL_Base)) else URL_base_c:=URL_Base; if (RequestData.UserAgent<>'') then UA:=RequestData.UserAgent else UA:='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'; Header:='Host: '+URL_base_c+sLineBreak; Header:=Header+'User-Agent: '+UA+sLineBreak; if (RequestData.Origin<>'') then Header:=Header+'Origin: '+RequestData.Origin+sLineBreak; if (RequestData.ContentType<>'') then Header:=Header+'Content-Type: '+RequestData.ContentType+sLineBreak; if (RequestData.Accept<>'') then Header:=Header+'Accept: '+RequestData.Accept+sLineBreak; if (RequestData.AcceptLanguage<>'') then Header:=Header+'Accept-Language: '+RequestData.AcceptLanguage+sLineBreak; if (RequestData.AcceptEncoding<>'') then Header:=Header+'Accept-Encoding: '+RequestData.AcceptEncoding+sLineBreak; if (RequestData.Connection='keep-alive') then Header:=Header+'Connection: keep-alive'+sLineBreak; if (RequestData.Referer<>'') then Header:=Header+'Referer: '+RequestData.Referer+sLineBreak; if (RequestData.Cookie<>'') then Header:=Header+'Cookie: '+RequestData.Cookie+sLineBreak; if (Method=tpomPOST) then Header:=Header+'Content-Length: '+IntToStr(length(RequestData.Body))+sLineBreak; Header:=Header+sLineBreak; // Инициализируем hInet := InternetOpenA(PAnsiChar(UA), INTERNET_OPEN_TYPE_PRECONFIG, // Прокси в зависимости от утсановок системы nil, nil, 0); if not Assigned(hInet) then begin FormSlezka.ToLog('Ошибка при выполнении функции InternetOpen' + sLineBreak + SysErrorMessage(GetLastError),clRed); exit; end; try hCon := InternetConnect(hInet, PWideChar(URL_base_c), INTERNET_DEFAULT_HTTPS_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0); if not Assigned(hCon) then begin FormSlezka.ToLog('Ошибка при выполнении функции InternetConnect' + sLineBreak + SysErrorMessage(GetLastError),clRed); exit; end; try hReq := HttpOpenRequest(hCon, fMethod, PChar(URL_Page), 'HTTP/1.1', nil, nil, fFlag, 0); HttpAddRequestHeaders(hReq,PWideChar(Header),length(Header),HTTP_ADDREQ_FLAG_ADD); if not Assigned(hReq) then begin FormSlezka.ToLog('Ошибка при выполнении функции HttpOpenRequest' + sLineBreak + SysErrorMessage(GetLastError),clRed); exit; end; try if (Method=tpomGet) then HttpSendRequest(hReq,'', 0, nil, 0) else HttpSendRequest(hReq,'', 0, PAnsiChar(RequestData.Body), length(RequestData.Body)+1); StatusSize := SizeOf(Status); Index := 0; HttpQueryInfo(hReq, HTTP_QUERY_FLAG_NUMBER or HTTP_QUERY_STATUS_CODE, @Status, StatusSize, Index); tPS.err:=Status; HttpQueryInfo(hReq, HTTP_QUERY_RAW_HEADERS_CRLF, @Response, ResponseL, Index); posi := 1; b := 1; ResponseString := ''; while b > 0 do begin if not InternetQueryDataAvailable( hReq, bytes, 0, 0 ) then begin FormSlezka.ToLog('Ошибка при выполнении функции InternetQueryDataAvailable' + sLineBreak + SysErrorMessage(GetLastError),clRed); exit; end; SetLength( ResponseString, Length(ResponseString) + bytes ); InternetReadFile( hReq, @ResponseString[Posi], bytes, b ); Inc(Posi, b); end; finally InternetCloseHandle(hReq); end; finally InternetCloseHandle(hCon); end; finally InternetCloseHandle(hInet); end; //========== конец получения кода страницы ========== EndPos:=AnsiPos(#13+#10+#13+#10,Response); tPS.header:=''; for i := 0 to EndPos do tPS.header:=tPS.header+Response[i]; tPS.code:=ResponseString; Result:=tPS; end;
Оставьте свой комментарий
Войдите, чтобы оставлять комментарии
Оставить комментарий как гость