@@ -92,6 +92,38 @@ def make_components_hash(klass, array_hash)
92
92
end
93
93
94
94
module Schemes # :nodoc:
95
+ class << self
96
+ ReservedChars = ".+-"
97
+ EscapedChars = "\uFE52 \uFE62 \uFE63 "
98
+
99
+ def escape ( name )
100
+ unless name and name . ascii_only?
101
+ return nil
102
+ end
103
+ name . upcase . tr ( ReservedChars , EscapedChars )
104
+ end
105
+
106
+ def unescape ( name )
107
+ name . tr ( EscapedChars , ReservedChars ) . encode ( Encoding ::US_ASCII ) . upcase
108
+ end
109
+
110
+ def find ( name )
111
+ const_get ( name , false ) if name and const_defined? ( name , false )
112
+ end
113
+
114
+ def register ( name , klass )
115
+ unless scheme = escape ( name )
116
+ raise ArgumentError , "invalid characater as scheme - #{ name } "
117
+ end
118
+ const_set ( scheme , klass )
119
+ end
120
+
121
+ def list
122
+ constants . map { |name |
123
+ [ unescape ( name . to_s ) , const_get ( name ) ]
124
+ } . to_h
125
+ end
126
+ end
95
127
end
96
128
private_constant :Schemes
97
129
@@ -104,7 +136,7 @@ module Schemes # :nodoc:
104
136
# Note that after calling String#upcase on +scheme+, it must be a valid
105
137
# constant name.
106
138
def self . register_scheme ( scheme , klass )
107
- Schemes . const_set ( scheme . to_s . upcase , klass )
139
+ Schemes . register ( scheme , klass )
108
140
end
109
141
110
142
# Returns a hash of the defined schemes:
@@ -122,9 +154,7 @@ def self.register_scheme(scheme, klass)
122
154
#
123
155
# Related: URI.register_scheme.
124
156
def self . scheme_list
125
- Schemes . constants . map { |name |
126
- [ name . to_s . upcase , Schemes . const_get ( name ) ]
127
- } . to_h
157
+ Schemes . list
128
158
end
129
159
130
160
INITIAL_SCHEMES = scheme_list
@@ -148,12 +178,10 @@ def self.scheme_list
148
178
# # => #<URI::HTTP foo://[email protected] :123/forum/questions/?tag=networking&order=newest#top>
149
179
#
150
180
def self . for ( scheme , *arguments , default : Generic )
151
- const_name = scheme . to_s . upcase
181
+ const_name = Schemes . escape ( scheme )
152
182
153
183
uri_class = INITIAL_SCHEMES [ const_name ]
154
- uri_class ||= if /\A [A-Z]\w *\z / . match? ( const_name ) && Schemes . const_defined? ( const_name , false )
155
- Schemes . const_get ( const_name , false )
156
- end
184
+ uri_class ||= Schemes . find ( const_name )
157
185
uri_class ||= default
158
186
159
187
return uri_class . new ( scheme , *arguments )
0 commit comments