При работе с TIdTCPClient для выполнения HTTPS-запросов может возникнуть проблема, когда сервер ожидает HTTP-команду и в итоге происходит таймаут. В таких случаях важно убедиться, что все шаги выполнены корректно.
Основные моменты
Инициализация соединения: Сначала необходимо создать экземпляры TIdTCPClient и TIdSSLIOHandlerSocketOpenSSL, а также установить необходимые параметры для SSL-соединения.
Настройка параметров SSL: Важно правильно настроить методы шифрования (например, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2) и другие опции.
Отправка HTTP-запроса: После установления соединения следует отправить запрос на сервер. В случае GET запроса важно не забыть добавить пустую строку после заголовков, что является обязательным условием для завершения HTTP-метаданных/заголовков.
Ошибки в исходном коде
В вашем исходном коде присутствуют несколько ошибок:
Создание неиспользуемого объекта TStringList.
Использование устаревших и небезопасных версий SSL (v2 и v3).
Вызов метода IOHandler.ReadLn() до отправки HTTP-запроса, что является излишним.
Ошибка в вызове метода Write() для заголовка sec-ch-ua, который должен быть выполнен с использованием WriteLn().
Запрос на сжатие содержимого HTTP, при этом отсутствует подготовка к его разархивированию.
Неправильное завершение HTTP-запроса без пустой строки после заголовков.
Исправление ошибок
Для исправления этих ошибок необходимо:
Удалить создание неиспользуемого TStringList.
Отключить устаревшие и ненадежные версии SSL (v2, v3).
Не вызывать IOHandler.ReadLn() до отправки запроса.
Исправить вызов метода для заголовка sec-ch-ua на использование WriteLn().
Убрать запрос на сжатие содержимого HTTP, если клиент не может обработать его.
Добавить пустую строку после всех заголовков запроса.
Пример исправленного кода
procedure TForm1.Button1Click(Sender: TObject);
var
Result: string;
TCPC: TIdTCPClient;
OnSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
TCPC := TIdTCPClient.Create(nil);
try
OnSSL := TIdSSLIOHandlerSocketOpenSSL.Create(TCPC);
OnSSL.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
OnSSL.PassThrough := False;
OnSSL.DefStringEncoding := IndyTextEncoding_UTF8;
TCPC.Host := 'xxxxxxx.edu';
TCPC.Port := 443;
TCPC.ConnectTimeout := 100000;
TCPC.ReadTimeout := 500000;
TCPC.IOHandler := OnSSL;
TCPC.Connect;
try
TCPC.IOHandler.WriteLn('GET / HTTP/1.1');
TCPC.IOHandler.WriteLn('Host: xxxxxxx.edu');
TCPC.IOHandler.WriteLn('Connection: close');
TCPC.IOHandler.WriteLn('Pragma: no-cache');
TCPC.IOHandler.WriteLn('Cache-Control: no-cache');
// ... остальные заголовки ...
TCPC.IOHandler.WriteLn(); // Добавляем пустую строку для завершения HTTP-заголовков
Result := '';
while not TCPC.IOHandler.EndOfStream do
Result := Result + TCPC.IOHandler.ReadLn;
finally
TCPC.Disconnect;
end;
finally
TCPC.Free;
end;
end;
Альтернативный способ с использованием TIdHTTP
Если у вас есть возможность использовать TIdHTTP вместо прямого использования TIdTCPClient, это значительно упростит ваш код и избавит от большинства проблем, связанных с ручной обработкой HTTP-запросов.
Использование TIdHTTP позволяет избежать многих сложностей, связанных с ручной обработкой сетевых протоколов.
Заключение
При работе с HTTPS-запросами через TIdTCPClient важно соблюдать правильный порядок действий и корректность отправляемых данных. Использование TIdHTTP является предпочтительным вариантом для большинства задач, так как он предоставляет более высокоуровневый API с меньшим количеством возможных ошибок при ручной настройке соединения.
Примечание: В данном ответе использованы примеры кода на языке Object Pascal, характерные для среды разработки Delphi.
Команда выполняет HTTPS GET запрос через компонент TIdTCPClient в среде программирования.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.