diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2023-02-07 16:22:16 +0900 |
---|---|---|
committer | nagachika <nagachika@ruby-lang.org> | 2023-03-26 14:22:38 +0900 |
commit | da27583cf364c0d69c085db4abf358c334a8eca1 (patch) | |
tree | bb2e5ff28214241b49e63c9f2dd28db0965dc257 | |
parent | 19af12ff195aba64bdca7a83f564f2c0e46061c0 (diff) | |
download | ruby-da27583cf364c0d69c085db4abf358c334a8eca1.tar.gz |
Merge URI-0.12.0
-rw-r--r-- | lib/uri.rb | 1 | ||||
-rw-r--r-- | lib/uri/common.rb | 52 | ||||
-rw-r--r-- | lib/uri/file.rb | 6 | ||||
-rw-r--r-- | lib/uri/generic.rb | 14 | ||||
-rw-r--r-- | lib/uri/mailto.rb | 2 | ||||
-rw-r--r-- | lib/uri/rfc3986_parser.rb | 5 | ||||
-rw-r--r-- | lib/uri/version.rb | 2 | ||||
-rw-r--r-- | test/uri/test_common.rb | 92 | ||||
-rw-r--r-- | test/uri/test_generic.rb | 9 | ||||
-rw-r--r-- | test/uri/test_ldap.rb | 6 | ||||
-rw-r--r-- | test/uri/test_parser.rb | 16 | ||||
-rw-r--r-- | test/uri/test_wss.rb | 71 |
12 files changed, 251 insertions, 25 deletions
diff --git a/lib/uri.rb b/lib/uri.rb index 394c156ac5..59a7c4ad28 100644 --- a/lib/uri.rb +++ b/lib/uri.rb @@ -101,3 +101,4 @@ require_relative 'uri/ldap' require_relative 'uri/ldaps' require_relative 'uri/mailto' require_relative 'uri/ws' +require_relative 'uri/wss' diff --git a/lib/uri/common.rb b/lib/uri/common.rb index 26b179add2..ca38bec7ec 100644 --- a/lib/uri/common.rb +++ b/lib/uri/common.rb @@ -13,6 +13,8 @@ require_relative "rfc2396_parser" require_relative "rfc3986_parser" module URI + include RFC2396_REGEXP + REGEXP = RFC2396_REGEXP Parser = RFC2396_Parser RFC3986_PARSER = RFC3986_Parser.new @@ -62,14 +64,17 @@ module URI module_function :make_components_hash end - include REGEXP - module Schemes end private_constant :Schemes + # + # Register the given +klass+ to be instantiated when parsing URLs with the given +scheme+. + # Note that currently only schemes which after .upcase are valid constant names + # can be registered (no -/+/. allowed). + # def self.register_scheme(scheme, klass) - Schemes.const_set(scheme, klass) + Schemes.const_set(scheme.to_s.upcase, klass) end # Returns a Hash of the defined schemes. @@ -295,6 +300,7 @@ module URI 256.times do |i| TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i) end + TBLENCURICOMP_ = TBLENCWWWCOMP_.dup.freeze TBLENCWWWCOMP_[' '] = '+' TBLENCWWWCOMP_.freeze TBLDECWWWCOMP_ = {} # :nodoc: @@ -320,6 +326,33 @@ module URI # # See URI.decode_www_form_component, URI.encode_www_form. def self.encode_www_form_component(str, enc=nil) + _encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_, str, enc) + end + + # Decodes given +str+ of URL-encoded form data. + # + # This decodes + to SP. + # + # See URI.encode_www_form_component, URI.decode_www_form. + def self.decode_www_form_component(str, enc=Encoding::UTF_8) + _decode_uri_component(/\+|%\h\h/, str, enc) + end + + # Encodes +str+ using URL encoding + # + # This encodes SP to %20 instead of +. + def self.encode_uri_component(str, enc=nil) + _encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCURICOMP_, str, enc) + end + + # Decodes given +str+ of URL-encoded data. + # + # This does not decode + to SP. + def self.decode_uri_component(str, enc=Encoding::UTF_8) + _decode_uri_component(/%\h\h/, str, enc) + end + + def self._encode_uri_component(regexp, table, str, enc) str = str.to_s.dup if str.encoding != Encoding::ASCII_8BIT if enc && enc != Encoding::ASCII_8BIT @@ -328,19 +361,16 @@ module URI end str.force_encoding(Encoding::ASCII_8BIT) end - str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_) + str.gsub!(regexp, table) str.force_encoding(Encoding::US_ASCII) end + private_class_method :_encode_uri_component - # Decodes given +str+ of URL-encoded form data. - # - # This decodes + to SP. - # - # See URI.encode_www_form_component, URI.decode_www_form. - def self.decode_www_form_component(str, enc=Encoding::UTF_8) + def self._decode_uri_component(regexp, str, enc) raise ArgumentError, "invalid %-encoding (#{str})" if /%(?!\h\h)/.match?(str) - str.b.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc) + str.b.gsub(regexp, TBLDECWWWCOMP_).force_encoding(enc) end + private_class_method :_decode_uri_component # Generates URL-encoded form data from given +enum+. # diff --git a/lib/uri/file.rb b/lib/uri/file.rb index 7671ad6470..4ff0bc097e 100644 --- a/lib/uri/file.rb +++ b/lib/uri/file.rb @@ -33,6 +33,9 @@ module URI # If an Array is used, the components must be passed in the # order <code>[host, path]</code>. # + # A path from e.g. the File class should be escaped before + # being passed. + # # Examples: # # require 'uri' @@ -44,6 +47,9 @@ module URI # :path => '/ruby/src'}) # uri2.to_s # => "file://host.example.com/ruby/src" # + # uri3 = URI::File.build({:path => URI::escape('/path/my file.txt')}) + # uri3.to_s # => "file:///path/my%20file.txt" + # def self.build(args) tmp = Util::make_components_hash(self, args) super(tmp) diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb index cfa0de6b74..69698c4e2d 100644 --- a/lib/uri/generic.rb +++ b/lib/uri/generic.rb @@ -564,16 +564,26 @@ module URI end end - # Returns the user component. + # Returns the user component (without URI decoding). def user @user end - # Returns the password component. + # Returns the password component (without URI decoding). def password @password end + # Returns the user component after URI decoding. + def decoded_user + URI.decode_uri_component(@user) if @user + end + + # Returns the password component after URI decoding. + def decoded_password + URI.decode_uri_component(@password) if @password + end + # # Checks the host +v+ component for RFC2396 compliance # and against the URI::Parser Regexp for :HOST. diff --git a/lib/uri/mailto.rb b/lib/uri/mailto.rb index 87cb99656f..cb8024f301 100644 --- a/lib/uri/mailto.rb +++ b/lib/uri/mailto.rb @@ -15,7 +15,7 @@ module URI # RFC6068, the mailto URL scheme. # class MailTo < Generic - include REGEXP + include RFC2396_REGEXP # A Default port of nil for URI::MailTo. DEFAULT_PORT = nil diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb index 3e07de4805..f3816d9ae5 100644 --- a/lib/uri/rfc3986_parser.rb +++ b/lib/uri/rfc3986_parser.rb @@ -2,9 +2,8 @@ module URI class RFC3986_Parser # :nodoc: # URI defined in RFC3986 - # this regexp is modified not to host is not empty string - RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ - RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+)\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ + RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ + RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/ attr_reader :regexp def initialize diff --git a/lib/uri/version.rb b/lib/uri/version.rb index 82188e25ad..a9643ef8bc 100644 --- a/lib/uri/version.rb +++ b/lib/uri/version.rb @@ -1,6 +1,6 @@ module URI # :stopdoc: - VERSION_CODE = '001100'.freeze + VERSION_CODE = '001200'.freeze VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze # :startdoc: end diff --git a/test/uri/test_common.rb b/test/uri/test_common.rb index 5e30cda41d..038f483a83 100644 --- a/test/uri/test_common.rb +++ b/test/uri/test_common.rb @@ -41,18 +41,52 @@ class TestCommon < Test::Unit::TestCase RUBY end + DEFAULT_SCHEMES = ["FILE", "FTP", "HTTP", "HTTPS", "LDAP", "LDAPS", "MAILTO", "WS", "WSS"].sort.freeze + def test_register_scheme - assert_equal(["FILE", "FTP", "HTTP", "HTTPS", "LDAP", "LDAPS", "MAILTO", "WS"].sort, URI.scheme_list.keys.sort) + assert_equal(DEFAULT_SCHEMES, URI.scheme_list.keys.sort) foobar = Class.new(URI::Generic) URI.register_scheme 'FOOBAR', foobar begin - assert_equal(["FILE", "FTP", "HTTP", "HTTPS", "LDAP", "LDAPS", "MAILTO", "WS", "FOOBAR"].sort, URI.scheme_list.keys.sort) + assert_include(URI.scheme_list.keys, "FOOBAR") + assert_equal foobar, URI.parse('foobar://localhost').class ensure URI.const_get(:Schemes).send(:remove_const, :FOOBAR) end - assert_equal(["FILE", "FTP", "HTTP", "HTTPS", "LDAP", "LDAPS", "MAILTO", "WS"].sort, URI.scheme_list.keys.sort) + assert_equal(DEFAULT_SCHEMES, URI.scheme_list.keys.sort) + end + + def test_register_scheme_lowercase + assert_equal(DEFAULT_SCHEMES, URI.scheme_list.keys.sort) + + foobar = Class.new(URI::Generic) + URI.register_scheme 'foobarlower', foobar + begin + assert_include(URI.scheme_list.keys, "FOOBARLOWER") + assert_equal foobar, URI.parse('foobarlower://localhost').class + ensure + URI.const_get(:Schemes).send(:remove_const, :FOOBARLOWER) + end + + assert_equal(DEFAULT_SCHEMES, URI.scheme_list.keys.sort) + end + + def test_register_scheme_with_symbols + # Valid schemes from https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml + some_uri_class = Class.new(URI::Generic) + assert_raise(NameError) { URI.register_scheme 'ms-search', some_uri_class } + assert_raise(NameError) { URI.register_scheme 'microsoft.windows.camera', some_uri_class } + assert_raise(NameError) { URI.register_scheme 'coaps+ws', some_uri_class } + + ms_search_class = Class.new(URI::Generic) + URI.register_scheme 'MS_SEARCH', ms_search_class + begin + assert_equal URI::Generic, URI.parse('ms-search://localhost').class + ensure + URI.const_get(:Schemes).send(:remove_const, :MS_SEARCH) + end end def test_regexp @@ -130,6 +164,58 @@ class TestCommon < Test::Unit::TestCase assert_nothing_raised(ArgumentError){URI.decode_www_form_component("x"*(1024*1024))} end + def test_encode_uri_component + assert_equal("%00%20%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \ + "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E", + URI.encode_uri_component("\x00 !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~")) + assert_equal("%95A", URI.encode_uri_component( + "\x95\x41".force_encoding(Encoding::Shift_JIS))) + assert_equal("0B", URI.encode_uri_component( + "\x30\x42".force_encoding(Encoding::UTF_16BE))) + assert_equal("%1B%24B%24%22%1B%28B", URI.encode_uri_component( + "\e$B$\"\e(B".force_encoding(Encoding::ISO_2022_JP))) + + assert_equal("%E3%81%82", URI.encode_uri_component( + "\u3042", Encoding::ASCII_8BIT)) + assert_equal("%82%A0", URI.encode_uri_component( + "\u3042", Encoding::Windows_31J)) + assert_equal("%E3%81%82", URI.encode_uri_component( + "\u3042", Encoding::UTF_8)) + + assert_equal("%82%A0", URI.encode_uri_component( + "\u3042".encode("sjis"), Encoding::ASCII_8BIT)) + assert_equal("%A4%A2", URI.encode_uri_component( + "\u3042".encode("sjis"), Encoding::EUC_JP)) + assert_equal("%E3%81%82", URI.encode_uri_component( + "\u3042".encode("sjis"), Encoding::UTF_8)) + assert_equal("B0", URI.encode_uri_component( + "\u3042".encode("sjis"), Encoding::UTF_16LE)) + assert_equal("%26%23730%3B", URI.encode_uri_component( + "\u02DA", Encoding::WINDOWS_1252)) + + # invalid + assert_equal("%EF%BF%BD%EF%BF%BD", URI.encode_uri_component( + "\xE3\x81\xFF", "utf-8")) + assert_equal("%E6%9F%8A%EF%BF%BD%EF%BF%BD", URI.encode_uri_component( + "\x95\x41\xff\xff".force_encoding(Encoding::Shift_JIS), "utf-8")) + end + + def test_decode_uri_component + assert_equal(" +!\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~", + URI.decode_uri_component( + "%20+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \ + "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E")) + assert_equal("\xA1\xA2".force_encoding(Encoding::EUC_JP), + URI.decode_uri_component("%A1%A2", "EUC-JP")) + assert_equal("\xE3\x81\x82\xE3\x81\x82".force_encoding("UTF-8"), + URI.decode_uri_component("\xE3\x81\x82%E3%81%82".force_encoding("UTF-8"))) + + assert_raise(ArgumentError){URI.decode_uri_component("%")} + assert_raise(ArgumentError){URI.decode_uri_component("%a")} + assert_raise(ArgumentError){URI.decode_uri_component("x%a_")} + assert_nothing_raised(ArgumentError){URI.decode_uri_component("x"*(1024*1024))} + end + def test_encode_www_form assert_equal("a=1", URI.encode_www_form("a" => "1")) assert_equal("a=1", URI.encode_www_form(a: 1)) diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb index fdb405e396..3897c3d6ee 100644 --- a/test/uri/test_generic.rb +++ b/test/uri/test_generic.rb @@ -24,7 +24,8 @@ class URI::TestGeneric < Test::Unit::TestCase assert_equal "file:///foo", URI("file:///foo").to_s assert_equal "postgres:///foo", URI("postgres:///foo").to_s - assert_equal "http:/foo", URI("http:///foo").to_s + assert_equal "http:///foo", URI("http:///foo").to_s + assert_equal "http:/foo", URI("http:/foo").to_s end def test_parse @@ -157,6 +158,12 @@ class URI::TestGeneric < Test::Unit::TestCase assert_equal(nil, url.user) assert_equal(nil, url.password) assert_equal(nil, url.userinfo) + + # sec-156615 + url = URI.parse('http:////example.com') + # must be empty string to identify as path-abempty, not path-absolute + assert_equal('', url.host) + assert_equal('http:////example.com', url.to_s) end def test_parse_scheme_with_symbols diff --git a/test/uri/test_ldap.rb b/test/uri/test_ldap.rb index 64845e487a..2625b24103 100644 --- a/test/uri/test_ldap.rb +++ b/test/uri/test_ldap.rb @@ -39,7 +39,7 @@ class TestLDAP < Test::Unit::TestCase # from RFC2255, section 6. { 'ldap:///o=University%20of%20Michigan,c=US' => - ['ldap', nil, URI::LDAP::DEFAULT_PORT, + ['ldap', '', URI::LDAP::DEFAULT_PORT, 'o=University%20of%20Michigan,c=US', nil, nil, nil, nil], @@ -74,12 +74,12 @@ class TestLDAP < Test::Unit::TestCase nil, '(int=%5c00%5c00%5c00%5c04)', nil, nil], 'ldap:///??sub??bindname=cn=Manager%2co=Foo' => - ['ldap', nil, URI::LDAP::DEFAULT_PORT, + ['ldap', '', URI::LDAP::DEFAULT_PORT, '', nil, 'sub', nil, 'bindname=cn=Manager%2co=Foo'], 'ldap:///??sub??!bindname=cn=Manager%2co=Foo' => - ['ldap', nil, URI::LDAP::DEFAULT_PORT, + ['ldap', '', URI::LDAP::DEFAULT_PORT, '', nil, 'sub', nil, '!bindname=cn=Manager%2co=Foo'], }.each do |url2, ary| diff --git a/test/uri/test_parser.rb b/test/uri/test_parser.rb index 03de137788..72fb5901d9 100644 --- a/test/uri/test_parser.rb +++ b/test/uri/test_parser.rb @@ -50,6 +50,15 @@ class URI::TestParser < Test::Unit::TestCase assert_raise(URI::InvalidURIError) { URI.parse('https://www.example.com/search?q=%XX') } end + def test_parse_auth + str = "http://al%40ice:p%40s%25sword@example.com/dir%2Fname/subdir?foo=bar%40example.com" + uri = URI.parse(str) + assert_equal "al%40ice", uri.user + assert_equal "p%40s%25sword", uri.password + assert_equal "al@ice", uri.decoded_user + assert_equal "p@s%sword", uri.decoded_password + end + def test_raise_bad_uri_for_integer assert_raise(URI::InvalidURIError) do URI.parse(1) @@ -63,4 +72,11 @@ class URI::TestParser < Test::Unit::TestCase assert_equal("\u3042", p1.unescape('%e3%81%82'.force_encoding(Encoding::US_ASCII))) assert_equal("\xe3\x83\x90\xe3\x83\x90", p1.unescape("\xe3\x83\x90%e3%83%90")) end + + def test_split + assert_equal(["http", nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("http://example.com")) + assert_equal(["http", nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("http://[0::0]")) + assert_equal([nil, nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("//example.com")) + assert_equal([nil, nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("//[0::0]")) + end end diff --git a/test/uri/test_wss.rb b/test/uri/test_wss.rb new file mode 100644 index 0000000000..2e8b9bc4b7 --- /dev/null +++ b/test/uri/test_wss.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: false +require 'test/unit' +require 'uri/https' +require 'uri/wss' + +module URI + + +class TestWSS < Test::Unit::TestCase + def setup + end + + def teardown + end + + def uri_to_ary(uri) + uri.class.component.collect {|c| uri.send(c)} + end + + def test_build + u = URI::WSS.build(host: 'www.example.com', path: '/foo/bar') + assert_kind_of(URI::WSS, u) + end + + def test_parse + u = URI.parse('wss://a') + assert_kind_of(URI::WSS, u) + assert_equal(['wss', + nil, 'a', URI::HTTPS.default_port, + '', nil], uri_to_ary(u)) + end + + def test_normalize + host = 'aBcD' + u1 = URI.parse('wss://' + host + '/eFg?HiJ') + u2 = URI.parse('wss://' + host.downcase + '/eFg?HiJ') + assert(u1.normalize.host == 'abcd') + assert(u1.normalize.path == u1.path) + assert(u1.normalize == u2.normalize) + assert(!u1.normalize.host.equal?(u1.host)) + assert( u2.normalize.host.equal?(u2.host)) + + assert_equal('wss://abc/', URI.parse('wss://abc').normalize.to_s) + end + + def test_equal + assert(URI.parse('wss://abc') == URI.parse('wss://ABC')) + assert(URI.parse('wss://abc/def') == URI.parse('wss://ABC/def')) + assert(URI.parse('wss://abc/def') != URI.parse('wss://ABC/DEF')) + end + + def test_request_uri + assert_equal('/', URI.parse('wss://a.b.c/').request_uri) + assert_equal('/?abc=def', URI.parse('wss://a.b.c/?abc=def').request_uri) + assert_equal('/', URI.parse('wss://a.b.c').request_uri) + assert_equal('/?abc=def', URI.parse('wss://a.b.c?abc=def').request_uri) + assert_equal(nil, URI.parse('wss:foo').request_uri) + end + + def test_select + assert_equal(['wss', 'a.b.c', 443], URI.parse('wss://a.b.c/').select(:scheme, :host, :port)) + u = URI.parse('wss://a.b.c/') + assert_equal(uri_to_ary(u), u.select(*u.component)) + assert_raise(ArgumentError) do + u.select(:scheme, :host, :not_exist, :port) + end + end +end + + +end |