Skip to content

Commit

Permalink
Fix: Handle IPv6 hostname correctly (closes #806)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannaHartmann committed Mar 5, 2021
1 parent cb3d929 commit 3f7e7e5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
13 changes: 10 additions & 3 deletions lib/webmock/http_lib_adapters/net_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,6 @@ module WebMock
module NetHTTPUtility

def self.request_signature_from_request(net_http, request, body = nil)
protocol = net_http.use_ssl? ? "https" : "http"

path = request.path

if path.respond_to?(:request_uri) #https://github.com/bblimke/webmock/issues/288
Expand All @@ -323,7 +321,7 @@ def self.request_signature_from_request(net_http, request, body = nil)

path = WebMock::Util::URI.heuristic_parse(path).request_uri if path =~ /^http/

uri = "#{protocol}://#{net_http.address}:#{net_http.port}#{path}"
uri = get_uri(net_http, path)
method = request.method.downcase.to_sym

headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
Expand All @@ -343,6 +341,15 @@ def self.request_signature_from_request(net_http, request, body = nil)
WebMock::RequestSignature.new(method, uri, body: request.body, headers: headers)
end

def self.get_uri(net_http, path)
protocol = net_http.use_ssl? ? "https" : "http"

hostname = net_http.address
hostname = "[#{hostname}]" if /\A\[.*\]\z/ !~ hostname && /:/ =~ hostname

"#{protocol}://#{hostname}:#{net_http.port}#{path}"
end

def self.validate_headers(headers)
# For Ruby versions < 2.3.0, if you make a request with headers that are symbols
# Net::HTTP raises a NoMethodError
Expand Down
26 changes: 26 additions & 0 deletions spec/acceptance/net_http/net_http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,30 @@ def perform_get_with_returning_block
http.request(req, '')
end
end

describe "hostname handling" do
it "should set brackets around the hostname if it is an IPv6 address" do
net_http = Net::HTTP.new('b2dc:5bdf:4f0d::3014:e0ca', 80)
path = '/example.jpg'
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
end

it "should not set brackets around the hostname if it is already wrapped by brackets" do
net_http = Net::HTTP.new('[b2dc:5bdf:4f0d::3014:e0ca]', 80)
path = '/example.jpg'
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://[b2dc:5bdf:4f0d::3014:e0ca]:80/example.jpg')
end

it "should not set brackets around the hostname if it is an IPv4 address" do
net_http = Net::HTTP.new('181.152.137.168', 80)
path = '/example.jpg'
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://181.152.137.168:80/example.jpg')
end

it "should not set brackets around the hostname if it is a domain" do
net_http = Net::HTTP.new('www.example.com', 80)
path = '/example.jpg'
expect(WebMock::NetHTTPUtility.get_uri(net_http, path)).to eq('http://www.example.com:80/example.jpg')
end
end
end

0 comments on commit 3f7e7e5

Please sign in to comment.