Indy IPv6でアクセスできない (indy10)
カテゴリー: General
2018-07-22
Indy IPv6でアクセスできない (indy10)
IPv6のアドレスに
IdHTTP1.Get
すると
原因
URIでIPv6の形式でない場合は、IOHandlerの設定にかかわらず Id_IPv4 として扱われるため。
原因のコード部分
IdHTTP.pas : procedure TIdCustomHTTP.CheckAndConnect
この行を適切に修正することで、IPv6でアクセスできるようになります。
テストコード
(1) ipv6でサーバーを立ち上げ準備をする
php -S localhost:8000 Unit1.pas
(2) テストコードを実行する
IdHTTP1.Get('http://localhost:8000/');
2018/07/22でのリポジトリ最新バージョンでもこのバグは健在でした。
IdHTTP1.Get('http://[localhost]:8000/');
とすると ipv6でアクセスするが実用的ではない。
最後に
キーワード:
パッチ
workaround的なことをする場合は、
修正箇所が大幅に増えるので、直接ライブラリを修正したほうが無難である。
執筆:2018.07.22
編集:2018.07.22
編集:2018.07.22
IPv6のアドレスに
IdHTTP1.Get
すると
Socket Error # 10061
Connection refused.
と表示されるConnection refused.
原因
URIでIPv6の形式でない場合は、IOHandlerの設定にかかわらず Id_IPv4 として扱われるため。
原因のコード部分
IdHTTP.pas : procedure TIdCustomHTTP.CheckAndConnect
if not Connected then try
IPVersion := FURI.IPVersion;
IPVersion := FURI.IPVersion;
この行を適切に修正することで、IPv6でアクセスできるようになります。
テストコード
(1) ipv6でサーバーを立ち上げ準備をする
php -S localhost:8000 Unit1.pas
(2) テストコードを実行する
IdHTTP1.Get('http://localhost:8000/');
2018/07/22でのリポジトリ最新バージョンでもこのバグは健在でした。
IdHTTP1.Get('http://[localhost]:8000/');
とすると ipv6でアクセスするが実用的ではない。
最後に
Indyのhttpは昔からバグだらけなので
バグ報告したところで修正してくれるものでもないでしょうから
Dlephiをやめて C# や vb.net にいったほうが開発ツールのバグがなくていいですよ
- 自前でWinのapiでhttpアクセスするとか
- HTTP クライアントが実装されているらしいのそれを使ったコードに移行するとか
Dlephiをやめて C# や vb.net にいったほうが開発ツールのバグがなくていいですよ
キーワード:
indy indy10 IPv6 Socket Error # 10061
Socket Error # 10061 Connection refused.
パッチ
Index: Lib/Protocols/IdHTTP.pas =================================================================== --- Lib/Protocols/IdHTTP.pas (リビジョン 5469) +++ Lib/Protocols/IdHTTP.pas (作業コピー) @@ -341,7 +341,8 @@ IdException, IdExceptionCore, IdAssignedNumbers, IdHeaderList, IdHTTPHeaderInfo, IdReplyRFC, IdSSL, IdZLibCompressorBase, IdTCPClient, IdURI, IdCookie, IdCookieManager, IdAuthentication, IdAuthenticationManager, - IdMultipartFormData, IdGlobal, IdBaseComponent, IdUriUtils; + IdMultipartFormData, IdGlobal, IdBaseComponent, IdUriUtils, + IdStack; type // TO DOCUMENTATION TEAM @@ -1913,7 +1914,18 @@ end; end; - Connect; + if IPVersion = Id_IPv6 then + Connect + else + try + Connect; + except + on e : IdStack.EIdSocketError do + begin + IPVersion := Id_IPv6; + Connect; + end; + end; except on E: EIdSSLProtocolReplyError do begin Disconnect;応用: ipv6, ipv4, ipv6_only,ipv4_onlyみたいなプロパティを作って改良するといいかもしれない
workaround的なことをする場合は、
修正箇所が大幅に増えるので、直接ライブラリを修正したほうが無難である。