Ошибка TidHTTP «Требуется порт» при попытке подключения - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь подключиться к безопасному серверу, используя компонент TIdHTTP.Я назначил обработчик ввода / вывода TIdSSLIOHandlerSocketOpenSSL свойству IOHandler и загрузил файлы OpenSSL.

Когда я вызываю Connect(), он генерирует исключение "Требуется порт". В другом посте предлагается, чтобы *1001* и Port были назначены автоматически для TIdHTTP.Любые предложения относительно того, что я делаю неправильно?

Если я не вызову Connect(), сайт ответит ошибкой 406, поскольку соединение не защищено.

Соответствующие биты кода:

try
  IdHttp1.Connect ('https://test-api.service.hmrc.gov.uk');
  IdHttp1.Request.CustomHeaders.AddValue ('Accept', 'application/vnd.hmrc.1.0+json');

  result := IdHTTP1.Get('https://test-api.service.hmrc.gov.uk/hello/world');
except
  on E: Exception do
    memo1.lines.add (E.ClassName + ': ' + E.message);
end;

1 Ответ

0 голосов
/ 19 января 2019

Ошибка «Требуется порт» связана с тем, что свойству Port еще не присвоено значение при вызове Connect().

Но, в отличие от других клиентских компонентов TCP, дело в том,вы НЕ должны вызывать Connect() напрямую вообще при использовании TIdHTTP.Его Get() метод (и другие методы запроса) будут обрабатывать это внутри вас.Итак, вам нужно удалить вызов Connect() из вашего кода.

HTTP - это протокол без сохранения состояния.Базовое TCP-соединение может быть постоянным или может быть отключено между несколькими запросами к одному и тому же серверу.Клиент и сервер согласовывают это на основе запроса.TIdHTTP обрабатывает эту информацию для вас внутренне, анализируя URL-адреса для информации о хосте и порте (как я объяснил в другом сообщении, которое вы упомянули) и отключая / повторно подключая TCP-соединение по мере необходимости.

Все, что вам нужно сделатьэто предоставить действительный URL-адрес Get() (и другим) и позволить TIdHTTP управлять TCP-соединением для вас.

В отдельном примечании не следует использовать свойство Request.CustomHeaders для установки Accept заголовок запроса.Вместо этого используйте свойство Request.Accept.

Попробуйте это:

IdHttp1.Request.Accept := 'application/vnd.hmrc.1.0+json';
try
  Result := IdHTTP1.Get('https://test-api.service.hmrc.gov.uk/hello/world');
except
  on E: Exception do
    Memo1.Lines.Add(E.ClassName + ': ' + E.message);
end;

Что касается кода ответа 406, то, что вы получаете любой ответ вообще, означает, что у вас есть действующее соединение HTTP ссервер.Но 406 НЕ означает, что соединение небезопасно, как вы утверждаете (на самом деле, это не может быть, так как вы запрашиваете HTTPS-URL).406 фактически означает, что сервер не может доставить вам свои данные ответа в формате, который вы явно запросили как приемлемый.В этом случае ответ не может быть предоставлен в желаемом формате JSON.

Итак, вам нужно выяснить, почему сервер не отправляет JSON, и исправить это, или вам нужно изменить свой Accept заголовок запроса для включения формата, который сервер хочет использовать вместо этого.

My думаю, сервер, вероятно, пытается отправить сообщение об ошибке в формате, отличном от JSON (возможно, вHTML), поэтому попробуйте временно удалить заголовок запроса Accept, чтобы вы могли посмотреть фактический ответ, а затем обновить код запроса по мере необходимости.

...