Skip to content

Commit 8eea621

Browse files
taketo11130x1eefsorah
committed
Fix handling of IPv6 literal hosts in Net::HTTPGenericRequest
Co-authored-by: 0x1eef <0x1eef@users.noreply.github.com> Co-authored-by: Sorah Fukumori <sora134@gmail.com>
1 parent ec9c70a commit 8eea621

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

lib/net/http/generic_request.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc:
1919

2020
if URI === uri_or_path then
2121
raise ArgumentError, "not an HTTP URI" unless URI::HTTP === uri_or_path
22-
hostname = uri_or_path.hostname
22+
hostname = uri_or_path.host
2323
raise ArgumentError, "no host component for URI" unless (hostname && hostname.length > 0)
2424
@uri = uri_or_path.dup
25-
host = @uri.hostname.dup
26-
host << ":" << @uri.port.to_s if @uri.port != @uri.default_port
25+
@host = @uri.host.dup
26+
@port = @uri.port == @uri.default_port ? nil : @uri.port
2727
@path = uri_or_path.request_uri
2828
raise ArgumentError, "no HTTP request path given" unless @path
2929
else
3030
@uri = nil
31-
host = nil
31+
@host = nil
32+
@port = nil
3233
raise ArgumentError, "no HTTP request path given" unless uri_or_path
3334
raise ArgumentError, "HTTP request path is empty" if uri_or_path.empty?
3435
@path = uri_or_path.dup
@@ -51,7 +52,7 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc:
5152
initialize_http_header initheader
5253
self['Accept'] ||= '*/*'
5354
self['User-Agent'] ||= 'Ruby'
54-
self['Host'] ||= host if host
55+
self['Host'] ||= @port ? "#{@host}:#{@port}" : @host if @host
5556
@body = nil
5657
@body_stream = nil
5758
@body_data = nil
@@ -245,7 +246,7 @@ def update_uri(addr, port, ssl) # :nodoc: internal use only
245246
end
246247

247248
if host = self['host']
248-
host.sub!(/:.*/m, '')
249+
host = URI.parse("#{scheme}://#{host}").host # Remove a port component from the existing Host header
249250
elsif host = @uri.host
250251
else
251252
host = addr

test/net/http/test_http_request.rb

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ def test_initialize_GET_uri
7474
assert_equal "/foo", req.path
7575
assert_equal "example.com", req['Host']
7676

77+
req = Net::HTTP::Get.new(URI("https://203.0.113.1/foo"))
78+
assert_equal "/foo", req.path
79+
assert_equal "203.0.113.1", req['Host']
80+
81+
req = Net::HTTP::Get.new(URI("https://203.0.113.1:8000/foo"))
82+
assert_equal "/foo", req.path
83+
assert_equal "203.0.113.1:8000", req['Host']
84+
85+
req = Net::HTTP::Get.new(URI("https://[2001:db8::1]:8000/foo"))
86+
assert_equal "/foo", req.path
87+
assert_equal "[2001:db8::1]:8000", req['Host']
88+
7789
assert_raise(ArgumentError){ Net::HTTP::Get.new(URI("urn:ietf:rfc:7231")) }
7890
assert_raise(ArgumentError){ Net::HTTP::Get.new(URI("http://")) }
7991
end
@@ -89,5 +101,25 @@ def test_header_set
89101
'Bug #7831 - do not decode content if the user overrides'
90102
end if Net::HTTP::HAVE_ZLIB
91103

104+
def test_update_uri
105+
req = Net::HTTP::Get.new(URI.parse("http://203.0.113.1"))
106+
req.update_uri("test", 8080, false)
107+
assert_equal "203.0.113.1", req.uri.host
108+
assert_equal 8080, req.uri.port
109+
110+
req = Net::HTTP::Get.new(URI.parse("http://203.0.113.1:2020"))
111+
req.update_uri("test", 8080, false)
112+
assert_equal "203.0.113.1", req.uri.host
113+
assert_equal 8080, req.uri.port
114+
115+
req = Net::HTTP::Get.new(URI.parse("http://[2001:db8::1]"))
116+
req.update_uri("test", 8080, false)
117+
assert_equal "[2001:db8::1]", req.uri.host
118+
assert_equal 8080, req.uri.port
119+
120+
req = Net::HTTP::Get.new(URI.parse("http://[2001:db8::1]:2020"))
121+
req.update_uri("test", 8080, false)
122+
assert_equal "[2001:db8::1]", req.uri.host
123+
assert_equal 8080, req.uri.port
124+
end
92125
end
93-

0 commit comments

Comments
 (0)