diff --git a/lib/uri/common.rb b/lib/uri/common.rb index faf75f0..b5b6177 100644 --- a/lib/uri/common.rb +++ b/lib/uri/common.rb @@ -13,24 +13,37 @@ require_relative "rfc3986_parser" module URI - include RFC2396_REGEXP + RFC2396_PARSER = RFC2396_Parser.new + Ractor.make_shareable(RFC2396_PARSER) if defined?(Ractor) - REGEXP = RFC2396_REGEXP - Parser = RFC2396_Parser RFC3986_PARSER = RFC3986_Parser.new Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor) - # URI::Parser.new - DEFAULT_PARSER = Parser.new - DEFAULT_PARSER.pattern.each_pair do |sym, str| - unless REGEXP::PATTERN.const_defined?(sym) - REGEXP::PATTERN.const_set(sym, str) + DEFAULT_PARSER = RFC3986_PARSER + Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor) + + def self.parser=(parser = RFC3986_PARSER) + remove_const(:Parser) if defined?(Parser) + const_set("Parser", parser.class) + + remove_const(:REGEXP) if defined?(REGEXP) + remove_const(:PATTERN) if defined?(PATTERN) + if Parser == RFC2396_Parser + const_set("REGEXP", URI::RFC2396_REGEXP) + const_set("PATTERN", URI::RFC2396_REGEXP::PATTERN) + Parser.new.pattern.each_pair do |sym, str| + unless REGEXP::PATTERN.const_defined?(sym) + REGEXP::PATTERN.const_set(sym, str) + end + end + end + + Parser.new.regexp.each_pair do |sym, str| + remove_const(sym) if const_defined?(sym) + const_set(sym, str) end end - DEFAULT_PARSER.regexp.each_pair do |sym, str| - const_set(sym, str) - end - Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor) + self.parser = RFC3986_PARSER module Util # :nodoc: def make_components_hash(klass, array_hash) diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb index 092a1ac..529ecfa 100644 --- a/lib/uri/rfc3986_parser.rb +++ b/lib/uri/rfc3986_parser.rb @@ -135,12 +135,31 @@ def parse(uri) # :nodoc: URI.for(*self.split(uri), self) end - def join(*uris) # :nodoc: uris[0] = convert_to_uri(uris[0]) uris.inject :merge end + # Compatibility for RFC2396 parser + def extract(str, schemes = nil, &block) # :nodoc: + RFC2396_PARSER.extract(str, schemes, &block) + end + + # Compatibility for RFC2396 parser + def make_regexp(schemes = nil) # :nodoc: + RFC2396_PARSER.make_regexp(schemes) + end + + # Compatibility for RFC2396 parser + def escape(str, unsafe = nil) # :nodoc: + unsafe ? RFC2396_PARSER.escape(str, unsafe) : RFC2396_PARSER.escape(str) + end + + # Compatibility for RFC2396 parser + def unescape(str, escaped = nil) # :nodoc: + escaped ? RFC2396_PARSER.unescape(str, escaped) : RFC2396_PARSER.unescape(str) + end + @@to_s = Kernel.instance_method(:to_s) if @@to_s.respond_to?(:bind_call) def inspect diff --git a/test/uri/test_common.rb b/test/uri/test_common.rb index 1df19e6..aa9c689 100644 --- a/test/uri/test_common.rb +++ b/test/uri/test_common.rb @@ -10,6 +10,27 @@ def setup def teardown end + def test_parser_switch + assert_equal(URI::Parser, URI::RFC3986_Parser) + refute defined?(URI::REGEXP) + refute defined?(URI::PATTERN) + + URI.parser = URI::RFC2396_PARSER + + assert_equal(URI::Parser, URI::RFC2396_Parser) + assert defined?(URI::REGEXP) + assert defined?(URI::PATTERN) + assert defined?(URI::PATTERN::ESCAPED) + + URI.parser = URI::RFC3986_PARSER + + assert_equal(URI::Parser, URI::RFC3986_Parser) + refute defined?(URI::REGEXP) + refute defined?(URI::PATTERN) + ensure + URI.parser = URI::RFC3986_PARSER + end + def test_extract EnvUtil.suppress_warning do assert_equal(['http://example.com'], diff --git a/test/uri/test_parser.rb b/test/uri/test_parser.rb index 75c02fe..9105d47 100644 --- a/test/uri/test_parser.rb +++ b/test/uri/test_parser.rb @@ -8,8 +8,8 @@ def uri_to_ary(uri) end def test_inspect - assert_match(/URI::RFC2396_Parser/, URI::Parser.new.inspect) - assert_match(/URI::RFC3986_Parser/, URI::RFC3986_Parser.new.inspect) + assert_match(/URI::RFC2396_Parser/, URI::RFC2396_Parser.new.inspect) + assert_match(/URI::RFC3986_Parser/, URI::Parser.new.inspect) end def test_compare @@ -33,7 +33,9 @@ def test_compare assert(!u2.equal?(u3)) end - def test_parse + def test_parse_rfc2396_parser + URI.parser = URI::RFC2396_PARSER + escaped = URI::REGEXP::PATTERN::ESCAPED hex = URI::REGEXP::PATTERN::HEX p1 = URI::Parser.new(:ESCAPED => "(?:#{escaped}|%u[#{hex}]{4})") @@ -43,6 +45,8 @@ def test_parse u1.path = '/%uDCBA' assert_equal(['http', nil, 'a', URI::HTTP.default_port, '/%uDCBA', nil, nil], uri_to_ary(u1)) + ensure + URI.parser = URI::DEFAULT_PARSER end def test_parse_query_pct_encoded