diff --git a/spec/std/uri_spec.cr b/spec/std/uri_spec.cr index 26812abaf94f..01be27c4677a 100644 --- a/spec/std/uri_spec.cr +++ b/spec/std/uri_spec.cr @@ -172,6 +172,42 @@ describe "URI" do it { URI.new(path: "/foo").hostname.should be_nil } end + describe "#host" do + it "works with IPv6 address literals" do + uri = URI.new("http", "[::1]", path: "foo") + uri.hostname.should eq("::1") + uri.host.should eq("[::1]") + uri.to_s.should eq "http://[::1]/foo" + uri.host = "[::1]" + uri.to_s.should eq "http://[::1]/foo" + + uri = URI.new("http", "::1", path: "foo") + uri.hostname.should eq("::1") + uri.host.should eq("[::1]") + uri.to_s.should eq "http://[::1]/foo" + uri.host = "::1" + uri.to_s.should eq "http://[::1]/foo" + end + + it "works with IPv4 addresses" do + uri = URI.new("http", "192.168.0.2", path: "foo") + uri.hostname.should eq("192.168.0.2") + uri.host.should eq("192.168.0.2") + uri.to_s.should eq "http://192.168.0.2/foo" + uri.host = "192.168.0.2" + uri.to_s.should eq "http://192.168.0.2/foo" + end + + it "works with domain names" do + uri = URI.new("http", "test.domain", path: "foo") + uri.hostname.should eq("test.domain") + uri.host.should eq("test.domain") + uri.to_s.should eq "http://test.domain/foo" + uri.host = "test.domain" + uri.to_s.should eq "http://test.domain/foo" + end + end + describe "#authority" do it { URI.new.authority.should be_nil } it { URI.new(scheme: "scheme").authority.should be_nil } diff --git a/src/uri.cr b/src/uri.cr index dfdf26f9f419..dc818acf895b 100644 --- a/src/uri.cr +++ b/src/uri.cr @@ -99,7 +99,9 @@ class URI getter host : String? # Sets the host component of the URI. - setter host : String? + def host=(host : String?) + @host = host && !host.starts_with?('[') && host.includes?(':') ? "[#{host}]" : host + end # Returns the port component of the URI. # @@ -175,7 +177,9 @@ class URI def_equals_and_hash scheme, host, port, path, query, user, password, fragment - def initialize(@scheme = nil, @host = nil, @port = nil, @path = "", query : String | Params | Nil = nil, @user = nil, @password = nil, @fragment = nil) + def initialize(@scheme = nil, host = nil, @port = nil, @path = "", query : String | Params | Nil = nil, @user = nil, @password = nil, @fragment = nil) + # wrap IPv6 addresses + self.host = host @query = query.try(&.to_s) end