uri 0.12.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/uri/common.rb CHANGED
@@ -13,24 +13,51 @@ require_relative "rfc2396_parser"
13
13
  require_relative "rfc3986_parser"
14
14
 
15
15
  module URI
16
- include RFC2396_REGEXP
16
+ # The default parser instance for RFC 2396.
17
+ RFC2396_PARSER = RFC2396_Parser.new
18
+ Ractor.make_shareable(RFC2396_PARSER) if defined?(Ractor)
17
19
 
18
- REGEXP = RFC2396_REGEXP
19
- Parser = RFC2396_Parser
20
+ # The default parser instance for RFC 3986.
20
21
  RFC3986_PARSER = RFC3986_Parser.new
21
22
  Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
22
23
 
23
- # URI::Parser.new
24
- DEFAULT_PARSER = Parser.new
25
- DEFAULT_PARSER.pattern.each_pair do |sym, str|
26
- unless REGEXP::PATTERN.const_defined?(sym)
27
- REGEXP::PATTERN.const_set(sym, str)
24
+ # The default parser instance.
25
+ DEFAULT_PARSER = RFC3986_PARSER
26
+ Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor)
27
+
28
+ # Set the default parser instance.
29
+ def self.parser=(parser = RFC3986_PARSER)
30
+ remove_const(:Parser) if defined?(::URI::Parser)
31
+ const_set("Parser", parser.class)
32
+
33
+ remove_const(:REGEXP) if defined?(::URI::REGEXP)
34
+ remove_const(:PATTERN) if defined?(::URI::PATTERN)
35
+ if Parser == RFC2396_Parser
36
+ const_set("REGEXP", URI::RFC2396_REGEXP)
37
+ const_set("PATTERN", URI::RFC2396_REGEXP::PATTERN)
38
+ end
39
+
40
+ Parser.new.regexp.each_pair do |sym, str|
41
+ remove_const(sym) if const_defined?(sym, false)
42
+ const_set(sym, str)
28
43
  end
29
44
  end
30
- DEFAULT_PARSER.regexp.each_pair do |sym, str|
31
- const_set(sym, str)
45
+ self.parser = RFC3986_PARSER
46
+
47
+ def self.const_missing(const) # :nodoc:
48
+ if const == :REGEXP
49
+ warn "URI::REGEXP is obsolete. Use URI::RFC2396_REGEXP explicitly.", uplevel: 1 if $VERBOSE
50
+ URI::RFC2396_REGEXP
51
+ elsif value = RFC2396_PARSER.regexp[const]
52
+ warn "URI::#{const} is obsolete. Use RFC2396_PARSER.regexp[#{const.inspect}] explicitly.", uplevel: 1 if $VERBOSE
53
+ value
54
+ elsif value = RFC2396_Parser.const_get(const)
55
+ warn "URI::#{const} is obsolete. Use RFC2396_Parser::#{const} explicitly.", uplevel: 1 if $VERBOSE
56
+ value
57
+ else
58
+ super
59
+ end
32
60
  end
33
- Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor)
34
61
 
35
62
  module Util # :nodoc:
36
63
  def make_components_hash(klass, array_hash)
@@ -64,20 +91,36 @@ module URI
64
91
  module_function :make_components_hash
65
92
  end
66
93
 
67
- module Schemes
94
+ module Schemes # :nodoc:
68
95
  end
69
96
  private_constant :Schemes
70
97
 
98
+ # Registers the given +klass+ as the class to be instantiated
99
+ # when parsing a \URI with the given +scheme+:
71
100
  #
72
- # Register the given +klass+ to be instantiated when parsing URLs with the given +scheme+.
73
- # Note that currently only schemes which after .upcase are valid constant names
74
- # can be registered (no -/+/. allowed).
101
+ # URI.register_scheme('MS_SEARCH', URI::Generic) # => URI::Generic
102
+ # URI.scheme_list['MS_SEARCH'] # => URI::Generic
75
103
  #
104
+ # Note that after calling String#upcase on +scheme+, it must be a valid
105
+ # constant name.
76
106
  def self.register_scheme(scheme, klass)
77
107
  Schemes.const_set(scheme.to_s.upcase, klass)
78
108
  end
79
109
 
80
- # Returns a Hash of the defined schemes.
110
+ # Returns a hash of the defined schemes:
111
+ #
112
+ # URI.scheme_list
113
+ # # =>
114
+ # {"MAILTO"=>URI::MailTo,
115
+ # "LDAPS"=>URI::LDAPS,
116
+ # "WS"=>URI::WS,
117
+ # "HTTP"=>URI::HTTP,
118
+ # "HTTPS"=>URI::HTTPS,
119
+ # "LDAP"=>URI::LDAP,
120
+ # "FILE"=>URI::File,
121
+ # "FTP"=>URI::FTP}
122
+ #
123
+ # Related: URI.register_scheme.
81
124
  def self.scheme_list
82
125
  Schemes.constants.map { |name|
83
126
  [name.to_s.upcase, Schemes.const_get(name)]
@@ -88,9 +131,21 @@ module URI
88
131
  private_constant :INITIAL_SCHEMES
89
132
  Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
90
133
 
134
+ # Returns a new object constructed from the given +scheme+, +arguments+,
135
+ # and +default+:
136
+ #
137
+ # - The new object is an instance of <tt>URI.scheme_list[scheme.upcase]</tt>.
138
+ # - The object is initialized by calling the class initializer
139
+ # using +scheme+ and +arguments+.
140
+ # See URI::Generic.new.
91
141
  #
92
- # Construct a URI instance, using the scheme to detect the appropriate class
93
- # from +URI.scheme_list+.
142
+ # Examples:
143
+ #
144
+ # values = ['john.doe', 'www.example.com', '123', nil, '/forum/questions/', nil, 'tag=networking&order=newest', 'top']
145
+ # URI.for('https', *values)
146
+ # # => #<URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
147
+ # URI.for('foo', *values, default: URI::HTTP)
148
+ # # => #<URI::HTTP foo://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
94
149
  #
95
150
  def self.for(scheme, *arguments, default: Generic)
96
151
  const_name = scheme.to_s.upcase
@@ -121,95 +176,49 @@ module URI
121
176
  #
122
177
  class BadURIError < Error; end
123
178
 
124
- #
125
- # == Synopsis
126
- #
127
- # URI::split(uri)
128
- #
129
- # == Args
130
- #
131
- # +uri+::
132
- # String with URI.
133
- #
134
- # == Description
135
- #
136
- # Splits the string on following parts and returns array with result:
137
- #
138
- # * Scheme
139
- # * Userinfo
140
- # * Host
141
- # * Port
142
- # * Registry
143
- # * Path
144
- # * Opaque
145
- # * Query
146
- # * Fragment
147
- #
148
- # == Usage
149
- #
150
- # require 'uri'
151
- #
152
- # URI.split("http://www.ruby-lang.org/")
153
- # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
179
+ # Returns a 9-element array representing the parts of the \URI
180
+ # formed from the string +uri+;
181
+ # each array element is a string or +nil+:
182
+ #
183
+ # names = %w[scheme userinfo host port registry path opaque query fragment]
184
+ # values = URI.split('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
185
+ # names.zip(values)
186
+ # # =>
187
+ # [["scheme", "https"],
188
+ # ["userinfo", "john.doe"],
189
+ # ["host", "www.example.com"],
190
+ # ["port", "123"],
191
+ # ["registry", nil],
192
+ # ["path", "/forum/questions/"],
193
+ # ["opaque", nil],
194
+ # ["query", "tag=networking&order=newest"],
195
+ # ["fragment", "top"]]
154
196
  #
155
197
  def self.split(uri)
156
- RFC3986_PARSER.split(uri)
198
+ DEFAULT_PARSER.split(uri)
157
199
  end
158
200
 
201
+ # Returns a new \URI object constructed from the given string +uri+:
159
202
  #
160
- # == Synopsis
161
- #
162
- # URI::parse(uri_str)
163
- #
164
- # == Args
165
- #
166
- # +uri_str+::
167
- # String with URI.
168
- #
169
- # == Description
170
- #
171
- # Creates one of the URI's subclasses instance from the string.
172
- #
173
- # == Raises
174
- #
175
- # URI::InvalidURIError::
176
- # Raised if URI given is not a correct one.
177
- #
178
- # == Usage
179
- #
180
- # require 'uri'
203
+ # URI.parse('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
204
+ # # => #<URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
205
+ # URI.parse('http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
206
+ # # => #<URI::HTTP http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
181
207
  #
182
- # uri = URI.parse("http://www.ruby-lang.org/")
183
- # # => #<URI::HTTP http://www.ruby-lang.org/>
184
- # uri.scheme
185
- # # => "http"
186
- # uri.host
187
- # # => "www.ruby-lang.org"
188
- #
189
- # It's recommended to first ::escape the provided +uri_str+ if there are any
190
- # invalid URI characters.
208
+ # It's recommended to first ::escape string +uri+
209
+ # if it may contain invalid URI characters.
191
210
  #
192
211
  def self.parse(uri)
193
- RFC3986_PARSER.parse(uri)
212
+ DEFAULT_PARSER.parse(uri)
194
213
  end
195
214
 
215
+ # Merges the given URI strings +str+
216
+ # per {RFC 2396}[https://www.rfc-editor.org/rfc/rfc2396.html].
196
217
  #
197
- # == Synopsis
198
- #
199
- # URI::join(str[, str, ...])
200
- #
201
- # == Args
202
- #
203
- # +str+::
204
- # String(s) to work with, will be converted to RFC3986 URIs before merging.
218
+ # Each string in +str+ is converted to an
219
+ # {RFC3986 URI}[https://www.rfc-editor.org/rfc/rfc3986.html] before being merged.
205
220
  #
206
- # == Description
207
- #
208
- # Joins URIs.
209
- #
210
- # == Usage
211
- #
212
- # require 'uri'
221
+ # Examples:
213
222
  #
214
223
  # URI.join("http://example.com/","main.rbx")
215
224
  # # => #<URI::HTTP http://example.com/main.rbx>
@@ -227,7 +236,7 @@ module URI
227
236
  # # => #<URI::HTTP http://example.com/foo/bar>
228
237
  #
229
238
  def self.join(*str)
230
- RFC3986_PARSER.join(*str)
239
+ DEFAULT_PARSER.join(*str)
231
240
  end
232
241
 
233
242
  #
@@ -254,7 +263,7 @@ module URI
254
263
  # URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
255
264
  # # => ["http://foo.example.com/bla", "mailto:test@example.com"]
256
265
  #
257
- def self.extract(str, schemes = nil, &block)
266
+ def self.extract(str, schemes = nil, &block) # :nodoc:
258
267
  warn "URI.extract is obsolete", uplevel: 1 if $VERBOSE
259
268
  DEFAULT_PARSER.extract(str, schemes, &block)
260
269
  end
@@ -291,7 +300,7 @@ module URI
291
300
  # p $&
292
301
  # end
293
302
  #
294
- def self.regexp(schemes = nil)
303
+ def self.regexp(schemes = nil)# :nodoc:
295
304
  warn "URI.regexp is obsolete", uplevel: 1 if $VERBOSE
296
305
  DEFAULT_PARSER.make_regexp(schemes)
297
306
  end
@@ -300,7 +309,7 @@ module URI
300
309
  256.times do |i|
301
310
  TBLENCWWWCOMP_[-i.chr] = -('%%%02X' % i)
302
311
  end
303
- TBLENCURICOMP_ = TBLENCWWWCOMP_.dup.freeze
312
+ TBLENCURICOMP_ = TBLENCWWWCOMP_.dup.freeze # :nodoc:
304
313
  TBLENCWWWCOMP_[' '] = '+'
305
314
  TBLENCWWWCOMP_.freeze
306
315
  TBLDECWWWCOMP_ = {} # :nodoc:
@@ -314,40 +323,86 @@ module URI
314
323
  TBLDECWWWCOMP_['+'] = ' '
315
324
  TBLDECWWWCOMP_.freeze
316
325
 
317
- # Encodes given +str+ to URL-encoded form data.
326
+ # Returns a URL-encoded string derived from the given string +str+.
318
327
  #
319
- # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
320
- # (ASCII space) to + and converts others to %XX.
328
+ # The returned string:
321
329
  #
322
- # If +enc+ is given, convert +str+ to the encoding before percent encoding.
330
+ # - Preserves:
323
331
  #
324
- # This is an implementation of
325
- # https://www.w3.org/TR/2013/CR-html5-20130806/forms.html#url-encoded-form-data.
332
+ # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
333
+ # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
334
+ # and <tt>'0'..'9'</tt>.
326
335
  #
327
- # See URI.decode_www_form_component, URI.encode_www_form.
336
+ # Example:
337
+ #
338
+ # URI.encode_www_form_component('*.-_azAZ09')
339
+ # # => "*.-_azAZ09"
340
+ #
341
+ # - Converts:
342
+ #
343
+ # - Character <tt>' '</tt> to character <tt>'+'</tt>.
344
+ # - Any other character to "percent notation";
345
+ # the percent notation for character <i>c</i> is <tt>'%%%X' % c.ord</tt>.
346
+ #
347
+ # Example:
348
+ #
349
+ # URI.encode_www_form_component('Here are some punctuation characters: ,;?:')
350
+ # # => "Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A"
351
+ #
352
+ # Encoding:
353
+ #
354
+ # - If +str+ has encoding Encoding::ASCII_8BIT, argument +enc+ is ignored.
355
+ # - Otherwise +str+ is converted first to Encoding::UTF_8
356
+ # (with suitable character replacements),
357
+ # and then to encoding +enc+.
358
+ #
359
+ # In either case, the returned string has forced encoding Encoding::US_ASCII.
360
+ #
361
+ # Related: URI.encode_uri_component (encodes <tt>' '</tt> as <tt>'%20'</tt>).
328
362
  def self.encode_www_form_component(str, enc=nil)
329
363
  _encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_, str, enc)
330
364
  end
331
365
 
332
- # Decodes given +str+ of URL-encoded form data.
366
+ # Returns a string decoded from the given \URL-encoded string +str+.
367
+ #
368
+ # The given string is first encoded as Encoding::ASCII-8BIT (using String#b),
369
+ # then decoded (as below), and finally force-encoded to the given encoding +enc+.
370
+ #
371
+ # The returned string:
372
+ #
373
+ # - Preserves:
374
+ #
375
+ # - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
376
+ # - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
377
+ # and <tt>'0'..'9'</tt>.
378
+ #
379
+ # Example:
333
380
  #
334
- # This decodes + to SP.
381
+ # URI.decode_www_form_component('*.-_azAZ09')
382
+ # # => "*.-_azAZ09"
335
383
  #
336
- # See URI.encode_www_form_component, URI.decode_www_form.
384
+ # - Converts:
385
+ #
386
+ # - Character <tt>'+'</tt> to character <tt>' '</tt>.
387
+ # - Each "percent notation" to an ASCII character.
388
+ #
389
+ # Example:
390
+ #
391
+ # URI.decode_www_form_component('Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A')
392
+ # # => "Here are some punctuation characters: ,;?:"
393
+ #
394
+ # Related: URI.decode_uri_component (preserves <tt>'+'</tt>).
337
395
  def self.decode_www_form_component(str, enc=Encoding::UTF_8)
338
396
  _decode_uri_component(/\+|%\h\h/, str, enc)
339
397
  end
340
398
 
341
- # Encodes +str+ using URL encoding
342
- #
343
- # This encodes SP to %20 instead of +.
399
+ # Like URI.encode_www_form_component, except that <tt>' '</tt> (space)
400
+ # is encoded as <tt>'%20'</tt> (instead of <tt>'+'</tt>).
344
401
  def self.encode_uri_component(str, enc=nil)
345
402
  _encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCURICOMP_, str, enc)
346
403
  end
347
404
 
348
- # Decodes given +str+ of URL-encoded data.
349
- #
350
- # This does not decode + to SP.
405
+ # Like URI.decode_www_form_component, except that <tt>'+'</tt> is preserved.
351
406
  def self.decode_uri_component(str, enc=Encoding::UTF_8)
352
407
  _decode_uri_component(/%\h\h/, str, enc)
353
408
  end
@@ -372,33 +427,104 @@ module URI
372
427
  end
373
428
  private_class_method :_decode_uri_component
374
429
 
375
- # Generates URL-encoded form data from given +enum+.
430
+ # Returns a URL-encoded string derived from the given
431
+ # {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
432
+ # +enum+.
433
+ #
434
+ # The result is suitable for use as form data
435
+ # for an \HTTP request whose <tt>Content-Type</tt> is
436
+ # <tt>'application/x-www-form-urlencoded'</tt>.
437
+ #
438
+ # The returned string consists of the elements of +enum+,
439
+ # each converted to one or more URL-encoded strings,
440
+ # and all joined with character <tt>'&'</tt>.
441
+ #
442
+ # Simple examples:
443
+ #
444
+ # URI.encode_www_form([['foo', 0], ['bar', 1], ['baz', 2]])
445
+ # # => "foo=0&bar=1&baz=2"
446
+ # URI.encode_www_form({foo: 0, bar: 1, baz: 2})
447
+ # # => "foo=0&bar=1&baz=2"
448
+ #
449
+ # The returned string is formed using method URI.encode_www_form_component,
450
+ # which converts certain characters:
451
+ #
452
+ # URI.encode_www_form('f#o': '/', 'b-r': '$', 'b z': '@')
453
+ # # => "f%23o=%2F&b-r=%24&b+z=%40"
454
+ #
455
+ # When +enum+ is Array-like, each element +ele+ is converted to a field:
376
456
  #
377
- # This generates application/x-www-form-urlencoded data defined in HTML5
378
- # from given an Enumerable object.
457
+ # - If +ele+ is an array of two or more elements,
458
+ # the field is formed from its first two elements
459
+ # (and any additional elements are ignored):
379
460
  #
380
- # This internally uses URI.encode_www_form_component(str).
461
+ # name = URI.encode_www_form_component(ele[0], enc)
462
+ # value = URI.encode_www_form_component(ele[1], enc)
463
+ # "#{name}=#{value}"
381
464
  #
382
- # This method doesn't convert the encoding of given items, so convert them
383
- # before calling this method if you want to send data as other than original
384
- # encoding or mixed encoding data. (Strings which are encoded in an HTML5
385
- # ASCII incompatible encoding are converted to UTF-8.)
465
+ # Examples:
386
466
  #
387
- # This method doesn't handle files. When you send a file, use
388
- # multipart/form-data.
467
+ # URI.encode_www_form([%w[foo bar], %w[baz bat bah]])
468
+ # # => "foo=bar&baz=bat"
469
+ # URI.encode_www_form([['foo', 0], ['bar', :baz, 'bat']])
470
+ # # => "foo=0&bar=baz"
389
471
  #
390
- # This refers https://url.spec.whatwg.org/#concept-urlencoded-serializer
472
+ # - If +ele+ is an array of one element,
473
+ # the field is formed from <tt>ele[0]</tt>:
391
474
  #
392
- # URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
393
- # #=> "q=ruby&lang=en"
394
- # URI.encode_www_form("q" => "ruby", "lang" => "en")
395
- # #=> "q=ruby&lang=en"
396
- # URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
397
- # #=> "q=ruby&q=perl&lang=en"
398
- # URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
399
- # #=> "q=ruby&q=perl&lang=en"
475
+ # URI.encode_www_form_component(ele[0])
476
+ #
477
+ # Example:
478
+ #
479
+ # URI.encode_www_form([['foo'], [:bar], [0]])
480
+ # # => "foo&bar&0"
481
+ #
482
+ # - Otherwise the field is formed from +ele+:
483
+ #
484
+ # URI.encode_www_form_component(ele)
485
+ #
486
+ # Example:
487
+ #
488
+ # URI.encode_www_form(['foo', :bar, 0])
489
+ # # => "foo&bar&0"
490
+ #
491
+ # The elements of an Array-like +enum+ may be mixture:
492
+ #
493
+ # URI.encode_www_form([['foo', 0], ['bar', 1, 2], ['baz'], :bat])
494
+ # # => "foo=0&bar=1&baz&bat"
495
+ #
496
+ # When +enum+ is Hash-like,
497
+ # each +key+/+value+ pair is converted to one or more fields:
498
+ #
499
+ # - If +value+ is
500
+ # {Array-convertible}[https://docs.ruby-lang.org/en/master/implicit_conversion_rdoc.html#label-Array-Convertible+Objects],
501
+ # each element +ele+ in +value+ is paired with +key+ to form a field:
502
+ #
503
+ # name = URI.encode_www_form_component(key, enc)
504
+ # value = URI.encode_www_form_component(ele, enc)
505
+ # "#{name}=#{value}"
506
+ #
507
+ # Example:
508
+ #
509
+ # URI.encode_www_form({foo: [:bar, 1], baz: [:bat, :bam, 2]})
510
+ # # => "foo=bar&foo=1&baz=bat&baz=bam&baz=2"
511
+ #
512
+ # - Otherwise, +key+ and +value+ are paired to form a field:
513
+ #
514
+ # name = URI.encode_www_form_component(key, enc)
515
+ # value = URI.encode_www_form_component(value, enc)
516
+ # "#{name}=#{value}"
517
+ #
518
+ # Example:
519
+ #
520
+ # URI.encode_www_form({foo: 0, bar: 1, baz: 2})
521
+ # # => "foo=0&bar=1&baz=2"
522
+ #
523
+ # The elements of a Hash-like +enum+ may be mixture:
524
+ #
525
+ # URI.encode_www_form({foo: [0, 1], bar: 2})
526
+ # # => "foo=0&foo=1&bar=2"
400
527
  #
401
- # See URI.encode_www_form_component, URI.decode_www_form.
402
528
  def self.encode_www_form(enum, enc=nil)
403
529
  enum.map do |k,v|
404
530
  if v.nil?
@@ -419,22 +545,39 @@ module URI
419
545
  end.join('&')
420
546
  end
421
547
 
422
- # Decodes URL-encoded form data from given +str+.
548
+ # Returns name/value pairs derived from the given string +str+,
549
+ # which must be an ASCII string.
550
+ #
551
+ # The method may be used to decode the body of Net::HTTPResponse object +res+
552
+ # for which <tt>res['Content-Type']</tt> is <tt>'application/x-www-form-urlencoded'</tt>.
553
+ #
554
+ # The returned data is an array of 2-element subarrays;
555
+ # each subarray is a name/value pair (both are strings).
556
+ # Each returned string has encoding +enc+,
557
+ # and has had invalid characters removed via
558
+ # {String#scrub}[https://docs.ruby-lang.org/en/master/String.html#method-i-scrub].
423
559
  #
424
- # This decodes application/x-www-form-urlencoded data
425
- # and returns an array of key-value arrays.
560
+ # A simple example:
426
561
  #
427
- # This refers http://url.spec.whatwg.org/#concept-urlencoded-parser,
428
- # so this supports only &-separator, and doesn't support ;-separator.
562
+ # URI.decode_www_form('foo=0&bar=1&baz')
563
+ # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
429
564
  #
430
- # ary = URI.decode_www_form("a=1&a=2&b=3")
431
- # ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
432
- # ary.assoc('a').last #=> '1'
433
- # ary.assoc('b').last #=> '3'
434
- # ary.rassoc('a').last #=> '2'
435
- # Hash[ary] #=> {"a"=>"2", "b"=>"3"}
565
+ # The returned strings have certain conversions,
566
+ # similar to those performed in URI.decode_www_form_component:
567
+ #
568
+ # URI.decode_www_form('f%23o=%2F&b-r=%24&b+z=%40')
569
+ # # => [["f#o", "/"], ["b-r", "$"], ["b z", "@"]]
570
+ #
571
+ # The given string may contain consecutive separators:
572
+ #
573
+ # URI.decode_www_form('foo=0&&bar=1&&baz=2')
574
+ # # => [["foo", "0"], ["", ""], ["bar", "1"], ["", ""], ["baz", "2"]]
575
+ #
576
+ # A different separator may be specified:
577
+ #
578
+ # URI.decode_www_form('foo=0--bar=1--baz', separator: '--')
579
+ # # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
436
580
  #
437
- # See URI.decode_www_form_component, URI.encode_www_form.
438
581
  def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
439
582
  raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
440
583
  ary = []
@@ -713,7 +856,15 @@ end # module URI
713
856
  module Kernel
714
857
 
715
858
  #
716
- # Returns +uri+ converted to an URI object.
859
+ # Returns a \URI object derived from the given +uri+,
860
+ # which may be a \URI string or an existing \URI object:
861
+ #
862
+ # # Returns a new URI.
863
+ # uri = URI('http://github.com/ruby/ruby')
864
+ # # => #<URI::HTTP http://github.com/ruby/ruby>
865
+ # # Returns the given URI.
866
+ # URI(uri)
867
+ # # => #<URI::HTTP http://github.com/ruby/ruby>
717
868
  #
718
869
  def URI(uri)
719
870
  if uri.is_a?(URI::Generic)
data/lib/uri/file.rb CHANGED
@@ -70,17 +70,17 @@ module URI
70
70
 
71
71
  # raise InvalidURIError
72
72
  def check_userinfo(user)
73
- raise URI::InvalidURIError, "can not set userinfo for file URI"
73
+ raise URI::InvalidURIError, "cannot set userinfo for file URI"
74
74
  end
75
75
 
76
76
  # raise InvalidURIError
77
77
  def check_user(user)
78
- raise URI::InvalidURIError, "can not set user for file URI"
78
+ raise URI::InvalidURIError, "cannot set user for file URI"
79
79
  end
80
80
 
81
81
  # raise InvalidURIError
82
82
  def check_password(user)
83
- raise URI::InvalidURIError, "can not set password for file URI"
83
+ raise URI::InvalidURIError, "cannot set password for file URI"
84
84
  end
85
85
 
86
86
  # do nothing
data/lib/uri/ftp.rb CHANGED
@@ -17,7 +17,7 @@ module URI
17
17
  # This class will be redesigned because of difference of implementations;
18
18
  # the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it
19
19
  # is a good summary about the de facto spec.
20
- # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04
20
+ # https://datatracker.ietf.org/doc/html/draft-hoffman-ftp-uri-04
21
21
  #
22
22
  class FTP < Generic
23
23
  # A Default port of 21 for URI::FTP.