зеркало из https://github.com/github/ruby.git
[ruby/uri] Add proper Ractor support to URI
* Using a module to map scheme name to scheme class, which also works with Ractor. * No constant redefinition, no ObjectSpace, still fast lookup for initial schemes. https://github.com/ruby/uri/commit/883567fd81
This commit is contained in:
Родитель
090d799c24
Коммит
1cf111774f
|
@ -30,7 +30,7 @@
|
|||
# class RSYNC < Generic
|
||||
# DEFAULT_PORT = 873
|
||||
# end
|
||||
# @@schemes['RSYNC'] = RSYNC
|
||||
# register_scheme 'RSYNC', RSYNC
|
||||
# end
|
||||
# #=> URI::RSYNC
|
||||
#
|
||||
|
@ -100,3 +100,9 @@ require_relative 'uri/https'
|
|||
require_relative 'uri/ldap'
|
||||
require_relative 'uri/ldaps'
|
||||
require_relative 'uri/mailto'
|
||||
|
||||
module URI
|
||||
INITIAL_SCHEMES = scheme_list
|
||||
private_constant :INITIAL_SCHEMES
|
||||
Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ module URI
|
|||
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
|
||||
|
@ -27,6 +28,7 @@ module URI
|
|||
DEFAULT_PARSER.regexp.each_pair do |sym, str|
|
||||
const_set(sym, str)
|
||||
end
|
||||
Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor)
|
||||
|
||||
module Util # :nodoc:
|
||||
def make_components_hash(klass, array_hash)
|
||||
|
@ -62,10 +64,19 @@ module URI
|
|||
|
||||
include REGEXP
|
||||
|
||||
@@schemes = {}
|
||||
module Schemes
|
||||
end
|
||||
private_constant :Schemes
|
||||
|
||||
def self.register_scheme(scheme, klass)
|
||||
Schemes.const_set(scheme, klass)
|
||||
end
|
||||
|
||||
# Returns a Hash of the defined schemes.
|
||||
def self.scheme_list
|
||||
@@schemes
|
||||
Schemes.constants.map { |name|
|
||||
[name.to_s.upcase, Schemes.const_get(name)]
|
||||
}.to_h
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -73,11 +84,13 @@ module URI
|
|||
# from +URI.scheme_list+.
|
||||
#
|
||||
def self.for(scheme, *arguments, default: Generic)
|
||||
if scheme
|
||||
uri_class = @@schemes[scheme.upcase] || default
|
||||
else
|
||||
uri_class = default
|
||||
const_name = scheme.to_s.upcase
|
||||
|
||||
uri_class = INITIAL_SCHEMES[const_name]
|
||||
if !uri_class && !const_name.empty? && Schemes.const_defined?(const_name, false)
|
||||
uri_class = Schemes.const_get(const_name, false)
|
||||
end
|
||||
uri_class ||= default
|
||||
|
||||
return uri_class.new(scheme, *arguments)
|
||||
end
|
||||
|
@ -653,6 +666,7 @@ module URI
|
|||
"utf-16"=>"utf-16le",
|
||||
"utf-16le"=>"utf-16le",
|
||||
} # :nodoc:
|
||||
Ractor.make_shareable(WEB_ENCODINGS_) if defined?(Ractor)
|
||||
|
||||
# :nodoc:
|
||||
# return encoding or nil
|
||||
|
|
|
@ -90,5 +90,5 @@ module URI
|
|||
end
|
||||
end
|
||||
|
||||
@@schemes['FILE'] = File
|
||||
register_scheme 'FILE', File
|
||||
end
|
||||
|
|
|
@ -262,5 +262,6 @@ module URI
|
|||
return str
|
||||
end
|
||||
end
|
||||
@@schemes['FTP'] = FTP
|
||||
|
||||
register_scheme 'FTP', FTP
|
||||
end
|
||||
|
|
|
@ -82,6 +82,5 @@ module URI
|
|||
end
|
||||
end
|
||||
|
||||
@@schemes['HTTP'] = HTTP
|
||||
|
||||
register_scheme 'HTTP', HTTP
|
||||
end
|
||||
|
|
|
@ -18,5 +18,6 @@ module URI
|
|||
# A Default port of 443 for URI::HTTPS
|
||||
DEFAULT_PORT = 443
|
||||
end
|
||||
@@schemes['HTTPS'] = HTTPS
|
||||
|
||||
register_scheme 'HTTPS', HTTPS
|
||||
end
|
||||
|
|
|
@ -257,5 +257,5 @@ module URI
|
|||
end
|
||||
end
|
||||
|
||||
@@schemes['LDAP'] = LDAP
|
||||
register_scheme 'LDAP', LDAP
|
||||
end
|
||||
|
|
|
@ -17,5 +17,6 @@ module URI
|
|||
# A Default port of 636 for URI::LDAPS
|
||||
DEFAULT_PORT = 636
|
||||
end
|
||||
@@schemes['LDAPS'] = LDAPS
|
||||
|
||||
register_scheme 'LDAPS', LDAPS
|
||||
end
|
||||
|
|
|
@ -289,5 +289,5 @@ module URI
|
|||
alias to_rfc822text to_mailtext
|
||||
end
|
||||
|
||||
@@schemes['MAILTO'] = MailTo
|
||||
register_scheme 'MAILTO', MailTo
|
||||
end
|
||||
|
|
|
@ -79,6 +79,5 @@ module URI
|
|||
end
|
||||
end
|
||||
|
||||
@@schemes['WS'] = WS
|
||||
|
||||
register_scheme 'WS', WS
|
||||
end
|
||||
|
|
|
@ -18,5 +18,6 @@ module URI
|
|||
# A Default port of 443 for URI::WSS
|
||||
DEFAULT_PORT = 443
|
||||
end
|
||||
@@schemes['WSS'] = WSS
|
||||
|
||||
register_scheme 'WSS', WSS
|
||||
end
|
||||
|
|
|
@ -33,6 +33,26 @@ class TestCommon < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_ractor
|
||||
return unless defined?(Ractor)
|
||||
r = Ractor.new { URI.parse("https://ruby-lang.org/").inspect }
|
||||
assert_equal(URI.parse("https://ruby-lang.org/").inspect, r.take)
|
||||
end
|
||||
|
||||
def test_register_scheme
|
||||
assert_equal(["FILE", "FTP", "HTTP", "HTTPS", "LDAP", "LDAPS", "MAILTO", "WS"].sort, 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)
|
||||
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)
|
||||
end
|
||||
|
||||
def test_regexp
|
||||
EnvUtil.suppress_warning do
|
||||
assert_instance_of Regexp, URI.regexp
|
||||
|
|
Загрузка…
Ссылка в новой задаче