Вы обнаружили несколько c ошибок в TIdHTTP
, которые необходимо исправить. Я открыл для этого новую заявку:
# 315: Ошибки в обработке прокси TIdHTTP
Вот что я вижу в вашем «неудачном» сценарии:
TIdHTTP
подключается к прокси, отправляет запрос CONNECT
, который успешно подключается к my.service.com:443
, а затем отправляет POST
запрос (с использованием HTTP 1.0, а не HTTP 1.1 a ).
a) для отправки запроса POST
с HTTP 1.1 необходимо установить для свойства TIdHTTP.ProtocolVersion
значение pv1_1
, И включите флаг hoKeepOrigProtocol
в свойстве TIdHTTP.HTTPOptions
. В противном случае TIdHTTP.Post()
принудительно устанавливает ProtocolVersion
на pv1_0
.
HTTP-сервер отвечает перенаправлением ответа 302 Found
на другой URL-адрес, включая заголовок Keep-Alive
, указывающий, что сервер будет закройте соединение, если новый запрос не будет отправлен в течение следующих 5 секунд.
Когда TIdHTTP
завершит обработку ответа POST
, он знает, что он собирается повторно отправить тот же запрос новому URL. На следующей итерации l oop он видит, что целевой сервер тот же, а прокси-сервер все еще подключен, поэтому соединение не закрывается, а код, который отправил бы новый запрос CONNECT
, пропускается.
Непосредственно перед отправкой запроса POST
проверяется свойство Response.KeepAlive
, чтобы узнать, закрывать ли соединение сокета в любом случае. Получатель свойства KeepAlive
видит, что свойство ProtocolVersion
равно pv1_0
и что в ответе нет заголовка Proxy-Connection: keep-alive
(даже если есть заголовок Connection: keep-alive
), поэтому он возвращает False, а затем сокет соединение закрыто.
TIdHTTP
затем снова подключается к прокси, но не отправляет новый запрос CONNECT
до отправки запроса POST
. Прокси-сервер не знает, что делать с POST
, поэтому он не выполняет запрос с ответом 400 Bad Request
.
Вот что я вижу в вашем «рабочем» сценарии:
Все то же, что и выше, до момента, когда обрабатывается 1-й запрос POST
. Затем возникает задержка примерно в 16 секунд (вероятно, поскольку вы выполняете код) - больше, чем позволяет задержка в 5 секунд Keep-Alive
, поэтому HTTP-сервер закрывает свое соединение с прокси-сервером, который затем закрывает свое соединение с * 1059. *.
К тому времени, когда TIdHTTP
готов отправить 2-й запрос POST
, он знает, что был отключен от прокси, поэтому он повторно подключается к прокси, отправляет новый CONNECT
запрос, а затем отправляет запрос POST
.
Пока я не смогу исправить ошибки должным образом, попробуйте следующее:
включите флаг hoKeepOrigProtocol
в свойстве TIdHTTP.HTTPOptions
, чтобы разрешить TIdHTTP.Post()
использовать HTTP 1.1. Это само по себе может решить проблему с ненужным закрытием соединения перед отправкой 2-го POST
запроса на перенаправленный URL.
, если это не решит проблему, попробуйте отредактировать IdHTTP.pas
самостоятельно и перекомпилируйте Indy, чтобы обновить метод TIdCustomHTTP.ConnectToHost()
, чтобы принудительно использовать Disconnect()
, если свойство Response.KeepAlive
имеет значение False ДО , для локальной LUseConnectVerb
переменной установлено значение not Connected
в случае где ARequest.UseProxy
- это ctSSLProxy
(и ctProxy
тоже). Таким образом, второй запрос POST
отключится от прокси и повторно подключится с новым запросом CONNECT
.