Как настроить Indy v10 для поддержки IPv4 + IPv6?

С помощью следующего кода я могу получить содержимое веб-сайта IPv4:

uses 
  IdHttp;

IdHttp1 := TIdHttp.Create(nil);
try
  Result := IdHttp1.Get('http://www.heise.de/')
finally
  IdHttp1.Free;
end;

но когда я пытаюсь подключиться к веб-сайту IPv6, я получаю ошибку сокета # 11004:

IdHttp1 := TIdHttp.Create(nil);
try
  Result := IdHttp1.Get('http://www.six.heise.de/')
finally
  IdHttp1.Free;
end;

Я могу нормально пинговать www.six.heise.de (IP 2a02:2e0:3fe:100::6:), и Firefox без проблем отображает сайт.

Что мне нужно изменить в Indy (последняя сборка V10 от SVN) для подключения к веб-сайтам IPv4 и IPv6?


person Casady    schedule 01.03.2013    source источник


Ответы (1)


TIdTCPClient необходимо указать, следует ли использовать IPv4 или IPv6 для разрешения сокета и имени хоста в IP. Это делается с помощью свойства TIdTCPClient.IPVersion. Однако TIdHTTP — это особый случай, поскольку он управляет свойствами и соединением TIdTCPClient внутри, включая IPVersion. TIdHTTP устанавливает IPVersion на основе запрашиваемого URL-адреса. Чтобы запросить URL-адрес, содержащий имя хоста IPv6, его необходимо заключить в квадратные скобки, например:

Result := IdHttp1.Get('http://[www.six.heise.de]/')
person Remy Lebeau    schedule 01.03.2013
comment
Это работает, но это довольно странное решение, так как веб-браузер не принимает http://[www.six.heise.de]/. Есть ли способ определить, является ли веб-сайт ipv4 или ipv6, и в случае ipv6 добавить скобки к URL-адресу? - person Casady; 02.03.2013
comment
Адреса IPv6, используемые в URL-адресах, должны быть заключены в квадратные скобки в соответствии с RFC 2732. Имена хостов — нет, но у TIdHTTP в настоящее время нет другого способа узнать заранее, когда использовать IPv4 или IPv6. Когда веб-браузер подключается к URL-адресу, он разрешает имя хоста через DNS, чтобы получить доступные адреса IPv4/IPv6, а затем пытается подключиться к ним, пока не добьется успеха. TIdTCPClient разрешает имя хоста после установки IPVersion и создания сокета IPv4/IPv6. Он не пытается подключиться к нескольким IP-адресам. Это, возможно, придется изменить в будущем. - person Remy Lebeau; 02.03.2013
comment
На данный момент вы можете использовать TIdDNSResolver для ручного поиска имени хоста в DNS, а затем использовать TIdHTTP с URL-адресом в соответствующем формате. - person Remy Lebeau; 02.03.2013