From: Kazuhiro NISHIYAMA Date: 2011-08-11T15:30:06+09:00 Subject: [ruby-dev:44378] [Ruby 1.9 - Feature #5180] net/http の接続時に用いる IP アドレスの指定 Issue #5180 has been updated by Kazuhiro NISHIYAMA. 匿名ユーザ wrote: > おおもとの問題は >  接続サーバの指定(IP/Hostname)、 >  HTTPのHostヘッダ(IP/Hostname、VirtualHostなどで利用) >  SSLのCN検証(IP/Hostnameとは別にCNAMEもあり得る) > と、レイヤを意識したパケットの組み立て方が必要なことでしょうか > すっきりした解決方法は浮かばないですね。。。 ホスト名は [ruby-dev:43164] の SNI のような部分でも使っているので 元の提案では IP アドレスの方を別途指定になっているのではないかと 思いました。 ---------------------------------------- Feature #5180: net/http の接続時に用いる IP アドレスの指定 http://redmine.ruby-lang.org/issues/5180 Author: Yui NARUSE Status: Open Priority: Normal Assignee: Category: lib Target version: 通常 net/http を使う時は、Net::HTTP.start("ruby-lang.org") などとホスト名を使います。 で、Socket がホスト名から IP アドレスを引いて、コネクションが張られます。 普通の人はこれで足りるわけですが、ふつうな人はしばしば DNS で引けない IP アドレスに接続したくなります。 例えば、ホスト名は "ruby-lang.org" としたいが、IP アドレスは 127.0.0.1 とか。 以下のパッチをあてると、 Net::HTTP.start("ruby-lang.org", ipaddr: '127.0.0.1') などとできるようになります。 diff --git a/lib/net/http.rb b/lib/net/http.rb index 7b9ec4f..6d034e0 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -524,7 +524,7 @@ module Net #:nodoc: # _opt_ :: optional hash # # _opt_ sets following values by its accessor. - # The keys are ca_file, ca_path, cert, cert_store, ciphers, + # The keys are ipaddr, ca_file, ca_path, cert, cert_store, ciphers, # close_on_empty_response, key, open_timeout, read_timeout, ssl_timeout, # ssl_version, use_ssl, verify_callback, verify_depth and verify_mode. # If you set :use_ssl as true, you can use https and default value of @@ -542,6 +542,7 @@ module Net #:nodoc: port, p_addr, p_port, p_user, p_pass = *arg port = https_default_port if !port && opt && opt[:use_ssl] http = new(address, port, p_addr, p_port, p_user, p_pass) + http.ipaddr = opt[:ipaddr] if opt[:ipaddr] if opt if opt[:use_ssl] @@ -575,6 +576,7 @@ module Net #:nodoc: def initialize(address, port = nil) @address = address @port = (port || HTTP.default_port) + @ipaddr = nil @curr_http_version = HTTPVersion @no_keepalive_server = false @close_on_empty_response = false @@ -620,6 +622,17 @@ module Net #:nodoc: # The port number to connect to. attr_reader :port + # The IP address to connect to/used to connect to + def ipaddr + started? ? @socket.io.peeraddr[3] : @ipaddr + end + + # Set the IP address to connect to + def ipaddr=(addr) + raise IOError, "ipaddr value changed, but session already started" if started? + @ipaddr = addr + end + # Number of seconds to wait for the connection to open. Any number # may be used, including Floats for fractional seconds. If the HTTP # object cannot open a connection in this many seconds, it raises a @@ -945,7 +958,7 @@ module Net #:nodoc: # without proxy def conn_address - address() + @ipaddr || address() end def conn_port -- http://redmine.ruby-lang.org