10

With the following code I can get the content of an IPv4 website:

uses 
  IdHttp;

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

but when I try to connect to an IPv6 website I get Socket Error # 11004:

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

I can ping www.six.heise.de just fine (IP 2a02:2e0:3fe:100::6:) and Firefox displays the website without problems.

What I need to change in Indy (latest V10 build from SVN) to connect to both IPv4 and IPv6 websites?

TLama
  • 75,147
  • 17
  • 214
  • 392
Casady
  • 1,426
  • 3
  • 19
  • 39

1 Answers1

12

TIdTCPClient needs to be told whether to use IPv4 or IPv6 for its socket and hostname-to-IP resolutions. That is done using the TIdTCPClient.IPVersion property. However, TIdHTTP is a special case because it manages the TIdTCPClient properties and connection internally, including the IPVersion. TIdHTTP sets the IPVersion based on the URL being requested. In order to request a URL containing an IPv6 hostname, it needs to be wrapped in brackets, eg:

Result := IdHttp1.Get('http://[www.six.heise.de]/')
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    This works, but is a rather strange solution, as a web browser will not accept http://[www.six.heise.de]/. Is there a way to derminate whether a website is ipv4 or ipv6, and in the case of the ipv6 add the brackets to the URL? – Casady Mar 01 '13 at 21:50
  • 2
    IPv6 addresses used in URLs must be bracketed, per [RFC 2732](http://tools.ietf.org/html/rfc2732). Hostnames do not, but `TIdHTTP` currently has no other means of knowing ahead of time when to use IPv4 vs IPv6. When a webbrowser connects to a URL, it resolves the hostname via DNS to get its available IPv4/IPv6 addresses and then attempts to connect to them until one succeeds. `TIdTCPClient` resolves the hostname after the `IPVersion` has been set and an IPv4/IPv6 socket has been created. It does not attempt to connect to multiple IPs. That may have to change in the future. – Remy Lebeau Mar 01 '13 at 22:08
  • 5
    For now, you can use `TIdDNSResolver` to do a manual DNS lookup of the hostname before then using `TIdHTTP` with an appropriately formatted URL. – Remy Lebeau Mar 01 '13 at 22:11