diff --git a/spec/integration/request_spec.rb b/spec/integration/request_spec.rb index 99bfefa..26919f1 100644 --- a/spec/integration/request_spec.rb +++ b/spec/integration/request_spec.rb @@ -1,4 +1,5 @@ require_relative '_lib' +require 'webrick' describe RestClient::Request do before(:all) do @@ -124,4 +125,62 @@ describe RestClient::Request do end end + class HostEchoServer < WEBrick::HTTPServlet::AbstractServlet + def do_GET request, response + response.status = 200 + response['Content-Type'] = 'text/plain' + response.body = "Host: #{request.header['host'].first}" + end + end + + def start_echo_server(bind_address, port) + server = WEBrick::HTTPServer.new(BindAddress: bind_address, Port: port) + server.mount('/', HostEchoServer) + server + end + + describe "requests by IP address" do + before(:all) do + port = 8080 + begin + @v6server = start_echo_server('::1', port) + @v6port = port + rescue Errno::EADDRINUSE + port += 1 + retry + end + + begin + @v4server = start_echo_server('127.0.0.1', port) + @v4port = port + rescue Errno::EADDRINUSE + port += 1 + retry + end + + @server_threads = [] + @server_threads << Thread.new { @v6server.start } + @server_threads << Thread.new { @v4server.start } + + puts "started HTTP servers" + end + + after(:all) do + puts 'stopping HTTP servers' + @v6server.shutdown + @v4server.shutdown + @server_threads.map(&:join) + puts 'stopped' + end + + it 'correctly set Host for IPv4 server' do + resp = RestClient.get("http://127.0.0.1:#{@v4port}") + expect(resp.body).to eq "Host: 127.0.0.1:#{@v4port}" + end + + it 'correctly set Host for IPv6 server' do + resp = RestClient.get("http://[::1]:#{@v6port}") + expect(resp.body).to eq "Host: [::1]:#{@v4port}" + end + end end diff --git a/spec/unit/request2_spec.rb b/spec/unit/request2_spec.rb index 71e5d6e..d7f13b3 100644 --- a/spec/unit/request2_spec.rb +++ b/spec/unit/request2_spec.rb @@ -32,6 +32,27 @@ describe RestClient::Request do end + context "IP addresses in Host header" do + it 'passes IPv4 Host header correctly' do + stub_request(:get, 'http://127.0.0.1'). + with(headers: {'Host' => '127.0.0.1'}). + to_return(body: 'foo', status: 200) + + expect(RestClient.get('http://127.0.0.1').body).to eq 'foo' + end + + # Cannot use webmock to test this because webmock itself handles IPv6 + # addresses incorrectly. (as of webmock 2.3.2) + # + # it 'passes IPv6 Host header correctly' do + # stub_request(:get, 'http://[::1]/'). + # with(headers: {'Host' => '[::1]'}). + # to_return(body: 'foo', status: 200) + # + # expect(RestClient.get('http://[::1]/').body).to eq 'foo' + # end + end + it "can use a block to process response" do response_value = nil block = proc do |http_response|