diff options
author | NARUSE, Yui <naruse@airemix.jp> | 2019-12-09 20:19:11 +0900 |
---|---|---|
committer | NARUSE, Yui <naruse@airemix.jp> | 2019-12-09 20:21:49 +0900 |
commit | 54072e329cab7207fba133caba4fc12b45add8f9 (patch) | |
tree | 89cc3dca25a16017330c81cf5dc13243894c2313 /lib | |
parent | 194327942690a7997c7b48d34cc105c6ec8b8d40 (diff) | |
download | ruby-54072e329cab7207fba133caba4fc12b45add8f9.tar.gz |
Add ipaddr optional parameter to Net::HTTP#start
to replace the address for TCP/IP connection [Feature #5180]
There're 3 layers of hostname:
* host address for TCP/IP
* TLS server name
* HTTP Host header value
To test DNS round robin or check server certificate from server local,
people sometimes want to connect server with given IP address but keep
TLS server name and HTTP Host header value.
closes [Feature #15215]
closes https://github.com/ruby/ruby/pull/1893
closes https://github.com/ruby/ruby/pull/1977
Diffstat (limited to 'lib')
-rw-r--r-- | lib/net/http.rb | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb index 663b901a96..283263b323 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -571,7 +571,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, write_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 @@ -590,6 +590,7 @@ module Net #:nodoc: p_addr = :ENV if arg.size < 2 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] @@ -660,6 +661,7 @@ module Net #:nodoc: def initialize(address, port = nil) @address = address @port = (port || HTTP.default_port) + @ipaddr = nil @local_host = nil @local_port = nil @curr_http_version = HTTPVersion @@ -727,6 +729,17 @@ module Net #:nodoc: attr_writer :proxy_user attr_writer :proxy_pass + # 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 @@ -934,20 +947,20 @@ module Net #:nodoc: def connect if proxy? then - conn_address = proxy_address + conn_addr = proxy_address conn_port = proxy_port else - conn_address = address + conn_addr = conn_address conn_port = port end - D "opening connection to #{conn_address}:#{conn_port}..." + D "opening connection to #{conn_addr}:#{conn_port}..." s = Timeout.timeout(@open_timeout, Net::OpenTimeout) { begin - TCPSocket.open(conn_address, conn_port, @local_host, @local_port) + TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) rescue => e raise e, "Failed to open TCP connection to " + - "#{conn_address}:#{conn_port} (#{e.message})" + "#{conn_addr}:#{conn_port} (#{e.message})" end } s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) @@ -984,7 +997,7 @@ module Net #:nodoc: OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT | OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess } - D "starting SSL for #{conn_address}:#{conn_port}..." + D "starting SSL for #{conn_addr}:#{conn_port}..." s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context) s.sync_close = true # Server Name Indication (SNI) RFC 3546 @@ -1161,7 +1174,7 @@ module Net #:nodoc: # without proxy, obsolete def conn_address # :nodoc: - address() + @ipaddr || address() end def conn_port # :nodoc: |