Skip to content

Commit

Permalink
Fix crystal-lang#5514. Allow HTTP::Client to use ipv6 addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
bcardiff committed May 31, 2018
1 parent 61da45f commit 673373c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
10 changes: 10 additions & 0 deletions spec/std/http/client/client_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ module HTTP
end
end

it "sends the host header ipv6 with brackets" do
server = HTTP::Server.new do |context|
context.response.print context.request.headers["Host"]
end
address = server.bind_unused_port "::1"
spawn { server.listen }

HTTP::Client.get("http://[::1]:#{address.port}/").body.should eq("[::1]:#{address.port}")
end

it "doesn't read the body if request was HEAD" do
resp_get = TestServer.open("localhost", 0, 0) do |server|
client = Client.new("localhost", server.local_address.port)
Expand Down
5 changes: 3 additions & 2 deletions spec/std/uri_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ end
describe "URI" do
assert_uri("http://www.example.com", scheme: "http", host: "www.example.com")
assert_uri("http://www.example.com:81", scheme: "http", host: "www.example.com", port: 81)
assert_uri("http://[::1]:81", scheme: "http", host: "[::1]", port: 81)
assert_uri("http://www.example.com/foo", scheme: "http", host: "www.example.com", path: "/foo")
assert_uri("http://www.example.com/foo?q=1", scheme: "http", host: "www.example.com", path: "/foo", query: "q=1")
assert_uri("http://www.example.com?q=1", scheme: "http", host: "www.example.com", query: "q=1")
Expand Down Expand Up @@ -207,7 +208,7 @@ describe "URI" do

it "does not unescape string when block returns true" do
URI.unescape("hello%26world") { |byte| URI.reserved? byte }
.should eq("hello%26world")
.should eq("hello%26world")
end
end

Expand Down Expand Up @@ -256,7 +257,7 @@ describe "URI" do

it "does not escape character when block returns true" do
URI.unescape("hello&world") { |byte| URI.reserved? byte }
.should eq("hello&world")
.should eq("hello&world")
end
end

Expand Down
6 changes: 5 additions & 1 deletion src/http/client.cr
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,11 @@ class HTTP::Client
socket = @socket
return socket if socket

socket = TCPSocket.new @host, @port, @dns_timeout, @connect_timeout
# URI host may have ipv6 enclosed by brackets and is fine according to
# rfc3986. The host http header must contains the brackets, ie: the same
# value as returned by URI#host
ip_host = @host[0] == '[' && @host[-1] == ']' ? @host[1..-2] : @host
socket = TCPSocket.new ip_host, @port, @dns_timeout, @connect_timeout
socket.read_timeout = @read_timeout if @read_timeout
socket.sync = false
@socket = socket
Expand Down

0 comments on commit 673373c

Please sign in to comment.