Issue #5180 has been updated by mame (Yusuke Endoh).

Status changed from Open to Assigned
Assignee set to naruse (Yui NARUSE)

成瀬さん

微妙に反対意見が出てますが、net/http のメンテナの裁量で
好きにやっていい範囲だと思います。
しかし現在 net/http にはメンテナがいません。

成瀬さんがメンテナになりませんか?
おまけで、net/http 関係の issue が憑いてきます。
メンテナになるのってまつもとさんの了解が必要でしたっけ。

成瀬さんがメンテナやりたくないなら reject の方向で。
その場合は Eric Hodel あたりに声かけてみますか。

-- 
Yusuke Endoh <mame / tsg.ne.jp>
----------------------------------------
Feature #5180: net/http の接続時に用いる IP アドレスの指定
https://bugs.ruby-lang.org/issues/5180#change-25204

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: naruse (Yui NARUSE)
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://bugs.ruby-lang.org/