honkster-addressable 2.1.2 → 2.2.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/CHANGELOG CHANGED
@@ -1,86 +1,109 @@
1
+ === Addressable 2.2.5
2
+ - 'parsing' a pre-parsed URI object is now a dup operation
3
+
4
+ === Addressable 2.2.4
5
+ - added origin support from draft-ietf-websec-origin-00
6
+ - resolved issue with attempting to navigate below root
7
+ - fixed bug with string splitting in query strings
8
+
9
+ === Addressable 2.2.3
10
+ - added :flat_array notation for query strings
11
+
12
+ === Addressable 2.2.2
13
+ - fixed issue with percent escaping of '+' character in query strings
14
+
15
+ === Addressable 2.2.1
16
+ - added support for application/x-www-form-urlencoded.
17
+
18
+ === Addressable 2.2.0
19
+ - added site methods
20
+ - improved documentation
21
+
1
22
  === Addressable 2.1.2
2
- * added HTTP request URI methods
3
- * better handling of Windows file paths
4
- * validation_deferred boolean replaced with defer_validation block
5
- * normalization of percent-encoded paths should now be correct
23
+ - added HTTP request URI methods
24
+ - better handling of Windows file paths
25
+ - validation_deferred boolean replaced with defer_validation block
26
+ - normalization of percent-encoded paths should now be correct
27
+ - fixed issue with constructing URIs with relative paths
28
+ - fixed warnings
6
29
 
7
30
  === Addressable 2.1.1
8
- * more type checking changes
9
- * fixed issue with unicode normalization
10
- * added method to find template defaults
11
- * symbolic keys are now allowed in template mappings
12
- * numeric values and symbolic values are now allowed in template mappings
31
+ - more type checking changes
32
+ - fixed issue with unicode normalization
33
+ - added method to find template defaults
34
+ - symbolic keys are now allowed in template mappings
35
+ - numeric values and symbolic values are now allowed in template mappings
13
36
 
14
37
  === Addressable 2.1.0
15
- * refactored URI template support out into its own class
16
- * removed extract method due to being useless and unreliable
17
- * removed Addressable::URI.expand_template
18
- * removed Addressable::URI#extract_mapping
19
- * added partial template expansion
20
- * fixed minor bugs in the parse and heuristic_parse methods
21
- * fixed incompatibility with Ruby 1.9.1
22
- * fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s
23
- * fixed unicode normalization exception
24
- * updated query_values methods to better handle subscript notation
25
- * worked around issue with freezing URIs
26
- * improved specs
38
+ - refactored URI template support out into its own class
39
+ - removed extract method due to being useless and unreliable
40
+ - removed Addressable::URI.expand_template
41
+ - removed Addressable::URI#extract_mapping
42
+ - added partial template expansion
43
+ - fixed minor bugs in the parse and heuristic_parse methods
44
+ - fixed incompatibility with Ruby 1.9.1
45
+ - fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s
46
+ - fixed unicode normalization exception
47
+ - updated query_values methods to better handle subscript notation
48
+ - worked around issue with freezing URIs
49
+ - improved specs
27
50
 
28
51
  === Addressable 2.0.2
29
- * fixed issue with URI template expansion
30
- * fixed issue with percent escaping characters 0-15
52
+ - fixed issue with URI template expansion
53
+ - fixed issue with percent escaping characters 0-15
31
54
 
32
55
  === Addressable 2.0.1
33
- * fixed issue with query string assignment
34
- * fixed issue with improperly encoded components
56
+ - fixed issue with query string assignment
57
+ - fixed issue with improperly encoded components
35
58
 
36
59
  === Addressable 2.0.0
37
- * the initialize method now takes an options hash as its only parameter
38
- * added query_values method to URI class
39
- * completely replaced IDNA implementation with pure Ruby
40
- * renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION
41
- * completely reworked the Rakefile
42
- * changed the behavior of the port method significantly
43
- * Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed
44
- * documentation is now in YARD format
45
- * more rigorous type checking
46
- * to_str method implemented, implicit conversion to Strings now allowed
47
- * Addressable::URI#omit method added, Addressable::URI#merge method replaced
48
- * updated URI Template code to match v 03 of the draft spec
49
- * added a bunch of new specifications
60
+ - the initialize method now takes an options hash as its only parameter
61
+ - added query_values method to URI class
62
+ - completely replaced IDNA implementation with pure Ruby
63
+ - renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION
64
+ - completely reworked the Rakefile
65
+ - changed the behavior of the port method significantly
66
+ - Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed
67
+ - documentation is now in YARD format
68
+ - more rigorous type checking
69
+ - to_str method implemented, implicit conversion to Strings now allowed
70
+ - Addressable::URI#omit method added, Addressable::URI#merge method replaced
71
+ - updated URI Template code to match v 03 of the draft spec
72
+ - added a bunch of new specifications
50
73
 
51
74
  === Addressable 1.0.4
52
- * switched to using RSpec's pending system for specs that rely on IDN
53
- * fixed issue with creating URIs with paths that are not prefixed with '/'
75
+ - switched to using RSpec's pending system for specs that rely on IDN
76
+ - fixed issue with creating URIs with paths that are not prefixed with '/'
54
77
 
55
78
  === Addressable 1.0.3
56
- * implemented a hash method
79
+ - implemented a hash method
57
80
 
58
81
  === Addressable 1.0.2
59
- * fixed minor bug with the extract_mapping method
82
+ - fixed minor bug with the extract_mapping method
60
83
 
61
84
  === Addressable 1.0.1
62
- * fixed minor bug with the extract_mapping method
85
+ - fixed minor bug with the extract_mapping method
63
86
 
64
87
  === Addressable 1.0.0
65
- * heuristic parse method added
66
- * parsing is slightly more strict
67
- * replaced to_h with to_hash
68
- * fixed routing methods
69
- * improved specifications
70
- * improved heckle rake task
71
- * no surviving heckle mutations
88
+ - heuristic parse method added
89
+ - parsing is slightly more strict
90
+ - replaced to_h with to_hash
91
+ - fixed routing methods
92
+ - improved specifications
93
+ - improved heckle rake task
94
+ - no surviving heckle mutations
72
95
 
73
96
  === Addressable 0.1.2
74
- * improved normalization
75
- * fixed bug in joining algorithm
76
- * updated specifications
97
+ - improved normalization
98
+ - fixed bug in joining algorithm
99
+ - updated specifications
77
100
 
78
101
  === Addressable 0.1.1
79
- * updated documentation
80
- * added URI Template variable extraction
102
+ - updated documentation
103
+ - added URI Template variable extraction
81
104
 
82
105
  === Addressable 0.1.0
83
- * initial release
84
- * implementation based on RFC 3986, 3987
85
- * support for IRIs via libidn
86
- * support for the URI Template draft spec
106
+ - initial release
107
+ - implementation based on RFC 3986, 3987
108
+ - support for IRIs via libidn
109
+ - support for the URI Template draft spec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Addressable, Copyright (c) 2006-2008 Bob Aman
1
+ Addressable, Copyright (c) 2006-2010 Bob Aman
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README CHANGED
@@ -1,10 +1,20 @@
1
+ == About
2
+
3
+ Homepage:: Addressable[http://addressable.rubyforge.org/]
4
+ Authors:: Bob Aman (mailto:bob@sporkmonger.com)
5
+ Copyright:: Copyright 2010 Bob Aman
6
+ License:: MIT
7
+
1
8
  Addressable is a replacement for the URI implementation that is part of
2
9
  Ruby's standard library. It more closely conforms to the relevant RFCs and
3
10
  adds support for IRIs and URI templates. Additionally, it provides extensive
4
11
  support for URI templates.
5
12
 
6
- Example usage:
7
-
13
+ == Classes
14
+ - {Addressable::URI}
15
+ - {Addressable::Template}
16
+
17
+ == Example usage
8
18
  require "addressable/uri"
9
19
 
10
20
  uri = Addressable::URI.parse("http://example.com/path/to/resource/")
data/Rakefile CHANGED
@@ -27,38 +27,6 @@ Ruby's standard library. It more closely conforms to the relevant RFCs and
27
27
  adds support for IRIs and URI templates.
28
28
  TEXT
29
29
 
30
- desc "generates .gemspec file"
31
- task :gemspec do
32
- spec = Gem::Specification.new do |p|
33
- p.name = ENV["GEM_PREFIX"] ? "#{ENV["GEM_PREFIX"]}-addressable" : 'addressable'
34
- p.version = PKG_VERSION
35
-
36
- p.summary = PKG_SUMMARY
37
- p.description = PKG_DESCRIPTION
38
-
39
- p.author = 'Bob Aman'
40
- p.email = 'bob@sporkmonger.com'
41
- p.homepage = 'http://github.com/mislav/addressable'
42
- p.rubyforge_project = nil
43
-
44
- p.files = FileList['Rakefile', '{bin,lib,tasks,spec}/**/*', 'README*', 'LICENSE*', 'CHANGELOG*'] & `git ls-files`.split
45
-
46
- p.executables = Dir['bin/*'].map { |f| File.basename(f) }
47
-
48
- p.has_rdoc = true
49
- end
50
-
51
- spec_string = spec.to_ruby
52
-
53
- begin
54
- Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
55
- rescue
56
- abort "unsafe gemspec: #{$!}"
57
- else
58
- File.open("#{spec.name}.gemspec", 'w') { |file| file.write spec_string }
59
- end
60
- end
61
-
62
30
  PKG_FILES = FileList[
63
31
  "lib/**/*", "spec/**/*", "vendor/**/*",
64
32
  "tasks/**/*", "website/**/*",
@@ -1,6 +1,6 @@
1
1
  # encoding:utf-8
2
2
  #--
3
- # Addressable, Copyright (c) 2006-2008 Bob Aman
3
+ # Addressable, Copyright (c) 2006-2010 Bob Aman
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining
6
6
  # a copy of this software and associated documentation files (the
@@ -1,6 +1,6 @@
1
1
  # encoding:utf-8
2
2
  #--
3
- # Addressable, Copyright (c) 2006-2008 Bob Aman
3
+ # Addressable, Copyright (c) 2006-2010 Bob Aman
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining
6
6
  # a copy of this software and associated documentation files (the
@@ -59,15 +59,15 @@ module Addressable
59
59
  #
60
60
  # @param [String, Addressable::URI, #to_str] uri
61
61
  # The URI string to parse.
62
- # No parsing is performed if the object is already an
63
- # <tt>Addressable::URI</tt>.
62
+ # No parsing is performed if the object is already an
63
+ # <code>Addressable::URI</code>.
64
64
  #
65
65
  # @return [Addressable::URI] The parsed URI.
66
66
  def self.parse(uri)
67
67
  # If we were given nil, return nil.
68
68
  return nil unless uri
69
69
  # If a URI object is passed, just return itself.
70
- return uri if uri.kind_of?(self)
70
+ return uri.dup if uri.kind_of?(self)
71
71
 
72
72
  # If a URI object of the Ruby standard library variety is passed,
73
73
  # convert it to a string, then parse the string.
@@ -130,18 +130,18 @@ module Addressable
130
130
  #
131
131
  # @param [String, Addressable::URI, #to_str] uri
132
132
  # The URI string to parse.
133
- # No parsing is performed if the object is already an
134
- # <tt>Addressable::URI</tt>.
133
+ # No parsing is performed if the object is already an
134
+ # <code>Addressable::URI</code>.
135
135
  # @param [Hash] hints
136
- # A <tt>Hash</tt> of hints to the heuristic parser.
137
- # Defaults to <tt>{:scheme => "http"}</tt>.
136
+ # A <code>Hash</code> of hints to the heuristic parser.
137
+ # Defaults to <code>{:scheme => "http"}</code>.
138
138
  #
139
139
  # @return [Addressable::URI] The parsed URI.
140
140
  def self.heuristic_parse(uri, hints={})
141
141
  # If we were given nil, return nil.
142
142
  return nil unless uri
143
143
  # If a URI object is passed, just return itself.
144
- return uri if uri.kind_of?(self)
144
+ return uri.dup if uri.kind_of?(self)
145
145
  if !uri.respond_to?(:to_str)
146
146
  raise TypeError, "Can't convert #{uri.class} into String."
147
147
  end
@@ -167,11 +167,13 @@ module Addressable
167
167
  if parsed.path.include?(".")
168
168
  new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
169
169
  if new_host
170
- new_path = parsed.path.gsub(
171
- Regexp.new("^" + Regexp.escape(new_host)), "")
172
- parsed.host = new_host
173
- parsed.path = new_path
174
- parsed.scheme = hints[:scheme] unless parsed.scheme
170
+ parsed.defer_validation do
171
+ new_path = parsed.path.gsub(
172
+ Regexp.new("^" + Regexp.escape(new_host)), "")
173
+ parsed.host = new_host
174
+ parsed.path = new_path
175
+ parsed.scheme = hints[:scheme] unless parsed.scheme
176
+ end
175
177
  end
176
178
  end
177
179
  return parsed
@@ -181,13 +183,13 @@ module Addressable
181
183
  # Converts a path to a file scheme URI. If the path supplied is
182
184
  # relative, it will be returned as a relative URI. If the path supplied
183
185
  # is actually a non-file URI, it will parse the URI as if it had been
184
- # parsed with <tt>Addressable::URI.parse</tt>. Handles all of the
186
+ # parsed with <code>Addressable::URI.parse</code>. Handles all of the
185
187
  # various Microsoft-specific formats for specifying paths.
186
188
  #
187
189
  # @param [String, Addressable::URI, #to_str] path
188
- #
189
- # Typically a <tt>String</tt> path to a file or directory, but will return
190
- # a sensible return value if an absolute URI is supplied instead.
190
+ # Typically a <code>String</code> path to a file or directory, but
191
+ # will return a sensible return value if an absolute URI is supplied
192
+ # instead.
191
193
  #
192
194
  # @return [Addressable::URI]
193
195
  # The parsed file scheme URI or the original URI if some other URI
@@ -277,17 +279,17 @@ module Addressable
277
279
  # @param [String, #to_str] component The URI component to encode.
278
280
  #
279
281
  # @param [String, Regexp] character_class
280
- #
281
- # The characters which are not percent encoded. If a <tt>String</tt> is
282
- # passed, the <tt>String</tt> must be formatted as a regular expression
283
- # character class. (Do not include the surrounding square brackets.) For
284
- # example, <tt>"b-zB-Z0-9"</tt> would cause everything but the letters 'b'
285
- # through 'z' and the numbers '0' through '9' to be percent encoded. If a
286
- # <tt>Regexp</tt> is passed, the value <tt>/[^b-zB-Z0-9]/</tt> would have
287
- # the same effect. A set of useful <tt>String</tt> values may be found in
288
- # the <tt>Addressable::URI::CharacterClasses</tt> module. The default
289
- # value is the reserved plus unreserved character classes specified in <a
290
- # href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
282
+ # The characters which are not percent encoded. If a <code>String</code>
283
+ # is passed, the <code>String</code> must be formatted as a regular
284
+ # expression character class. (Do not include the surrounding square
285
+ # brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
286
+ # everything but the letters 'b' through 'z' and the numbers '0' through
287
+ # '9' to be percent encoded. If a <code>Regexp</code> is passed, the
288
+ # value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
289
+ # useful <code>String</code> values may be found in the
290
+ # <code>Addressable::URI::CharacterClasses</code> module. The default
291
+ # value is the reserved plus unreserved character classes specified in
292
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
291
293
  #
292
294
  # @return [String] The encoded component.
293
295
  #
@@ -332,21 +334,21 @@ module Addressable
332
334
  ##
333
335
  # Unencodes any percent encoded characters within a URI component.
334
336
  # This method may be used for unencoding either components or full URIs,
335
- # however, it is recommended to use the <tt>unencode_component</tt> alias
336
- # when unencoding components.
337
+ # however, it is recommended to use the <code>unencode_component</code>
338
+ # alias when unencoding components.
337
339
  #
338
340
  # @param [String, Addressable::URI, #to_str] uri
339
341
  # The URI or component to unencode.
340
342
  #
341
343
  # @param [Class] returning
342
344
  # The type of object to return.
343
- # This value may only be set to <tt>String</tt> or
344
- # <tt>Addressable::URI</tt>. All other values are invalid. Defaults to
345
- # <tt>String</tt>.
345
+ # This value may only be set to <code>String</code> or
346
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
347
+ # to <code>String</code>.
346
348
  #
347
349
  # @return [String, Addressable::URI]
348
350
  # The unencoded component or URI.
349
- # The return type is determined by the <tt>returning</tt> parameter.
351
+ # The return type is determined by the <code>returning</code> parameter.
350
352
  def self.unencode(uri, returning=String)
351
353
  return nil if uri.nil?
352
354
  if !uri.respond_to?(:to_str)
@@ -381,17 +383,17 @@ module Addressable
381
383
  # @param [String, #to_str] component The URI component to encode.
382
384
  #
383
385
  # @param [String, Regexp] character_class
384
- #
385
- # The characters which are not percent encoded. If a <tt>String</tt> is
386
- # passed, the <tt>String</tt> must be formatted as a regular expression
387
- # character class. (Do not include the surrounding square brackets.) For
388
- # example, <tt>"b-zB-Z0-9"</tt> would cause everything but the letters 'b'
389
- # through 'z' and the numbers '0' through '9' to be percent encoded. If a
390
- # <tt>Regexp</tt> is passed, the value <tt>/[^b-zB-Z0-9]/</tt> would have
391
- # the same effect. A set of useful <tt>String</tt> values may be found in
392
- # the <tt>Addressable::URI::CharacterClasses</tt> module. The default
393
- # value is the reserved plus unreserved character classes specified in <a
394
- # href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
386
+ # The characters which are not percent encoded. If a <code>String</code>
387
+ # is passed, the <code>String</code> must be formatted as a regular
388
+ # expression character class. (Do not include the surrounding square
389
+ # brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
390
+ # everything but the letters 'b' through 'z' and the numbers '0' through
391
+ # '9' to be percent encoded. If a <code>Regexp</code> is passed, the
392
+ # value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
393
+ # useful <code>String</code> values may be found in the
394
+ # <code>Addressable::URI::CharacterClasses</code> module. The default
395
+ # value is the reserved plus unreserved character classes specified in
396
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
395
397
  #
396
398
  # @return [String] The normalized component.
397
399
  #
@@ -447,13 +449,13 @@ module Addressable
447
449
  #
448
450
  # @param [Class] returning
449
451
  # The type of object to return.
450
- # This value may only be set to <tt>String</tt> or
451
- # <tt>Addressable::URI</tt>. All other values are invalid. Defaults to
452
- # <tt>String</tt>.
452
+ # This value may only be set to <code>String</code> or
453
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
454
+ # to <code>String</code>.
453
455
  #
454
456
  # @return [String, Addressable::URI]
455
457
  # The encoded URI.
456
- # The return type is determined by the <tt>returning</tt> parameter.
458
+ # The return type is determined by the <code>returning</code> parameter.
457
459
  def self.encode(uri, returning=String)
458
460
  return nil if uri.nil?
459
461
  if !uri.respond_to?(:to_str)
@@ -497,13 +499,13 @@ module Addressable
497
499
  #
498
500
  # @param [Class] returning
499
501
  # The type of object to return.
500
- # This value may only be set to <tt>String</tt> or
501
- # <tt>Addressable::URI</tt>. All other values are invalid. Defaults to
502
- # <tt>String</tt>.
502
+ # This value may only be set to <code>String</code> or
503
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
504
+ # to <code>String</code>.
503
505
  #
504
506
  # @return [String, Addressable::URI]
505
507
  # The encoded URI.
506
- # The return type is determined by the <tt>returning</tt> parameter.
508
+ # The return type is determined by the <code>returning</code> parameter.
507
509
  def self.normalized_encode(uri, returning=String)
508
510
  if !uri.respond_to?(:to_str)
509
511
  raise TypeError, "Can't convert #{uri.class} into String."
@@ -558,6 +560,81 @@ module Addressable
558
560
  end
559
561
  end
560
562
 
563
+ ##
564
+ # Encodes a set of key/value pairs according to the rules for the
565
+ # <code>application/x-www-form-urlencoded</code> MIME type.
566
+ #
567
+ # @param [#to_hash, #to_ary] form_values
568
+ # The form values to encode.
569
+ #
570
+ # @param [TrueClass, FalseClass] sort
571
+ # Sort the key/value pairs prior to encoding.
572
+ # Defaults to <code>false</code>.
573
+ #
574
+ # @return [String]
575
+ # The encoded value.
576
+ def self.form_encode(form_values, sort=false)
577
+ if form_values.respond_to?(:to_hash)
578
+ form_values = form_values.to_hash.to_a
579
+ elsif form_values.respond_to?(:to_ary)
580
+ form_values = form_values.to_ary
581
+ else
582
+ raise TypeError, "Can't convert #{form_values.class} into Array."
583
+ end
584
+ form_values = form_values.map do |(key, value)|
585
+ [key.to_s, value.to_s]
586
+ end
587
+ if sort
588
+ # Useful for OAuth and optimizing caching systems
589
+ form_values = form_values.sort
590
+ end
591
+ escaped_form_values = form_values.map do |(key, value)|
592
+ # Line breaks are CRLF pairs
593
+ [
594
+ self.encode_component(
595
+ key.gsub(/(\r\n|\n|\r)/, "\r\n"),
596
+ CharacterClasses::UNRESERVED
597
+ ).gsub("%20", "+"),
598
+ self.encode_component(
599
+ value.gsub(/(\r\n|\n|\r)/, "\r\n"),
600
+ CharacterClasses::UNRESERVED
601
+ ).gsub("%20", "+")
602
+ ]
603
+ end
604
+ return (escaped_form_values.map do |(key, value)|
605
+ "#{key}=#{value}"
606
+ end).join("&")
607
+ end
608
+
609
+ ##
610
+ # Decodes a <code>String</code> according to the rules for the
611
+ # <code>application/x-www-form-urlencoded</code> MIME type.
612
+ #
613
+ # @param [String, #to_str] encoded_value
614
+ # The form values to decode.
615
+ #
616
+ # @return [Array]
617
+ # The decoded values.
618
+ # This is not a <code>Hash</code> because of the possibility for
619
+ # duplicate keys.
620
+ def self.form_unencode(encoded_value)
621
+ if !encoded_value.respond_to?(:to_str)
622
+ raise TypeError, "Can't convert #{encoded_value.class} into String."
623
+ end
624
+ encoded_value = encoded_value.to_str
625
+ split_values = encoded_value.split("&").map do |pair|
626
+ pair.split("=", 2)
627
+ end
628
+ return split_values.map do |(key, value)|
629
+ [
630
+ key ? self.unencode_component(
631
+ key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil,
632
+ value ? (self.unencode_component(
633
+ value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil
634
+ ]
635
+ end
636
+ end
637
+
561
638
  ##
562
639
  # Creates a new uri object from component parts.
563
640
  #
@@ -647,13 +724,19 @@ module Addressable
647
724
 
648
725
  if new_scheme && !new_scheme.respond_to?(:to_str)
649
726
  raise TypeError, "Can't convert #{new_scheme.class} into String."
727
+ elsif new_scheme
728
+ new_scheme = new_scheme.to_str
729
+ end
730
+ if new_scheme && new_scheme !~ /[a-z][a-z0-9\.\+\-]*/i
731
+ raise InvalidURIError, "Invalid scheme format."
650
732
  end
651
- @scheme = new_scheme ? new_scheme.to_str : nil
733
+ @scheme = new_scheme
652
734
  @scheme = nil if @scheme.to_s.strip == ""
653
735
 
654
736
  # Reset dependant values
655
737
  @normalized_scheme = nil
656
738
  @uri_string = nil
739
+ @hash = nil
657
740
 
658
741
  # Ensure we haven't created an invalid URI
659
742
  validate()
@@ -714,6 +797,7 @@ module Addressable
714
797
  @authority = nil
715
798
  @normalized_user = nil
716
799
  @uri_string = nil
800
+ @hash = nil
717
801
 
718
802
  # Ensure we haven't created an invalid URI
719
803
  validate()
@@ -775,6 +859,7 @@ module Addressable
775
859
  @authority = nil
776
860
  @normalized_password = nil
777
861
  @uri_string = nil
862
+ @hash = nil
778
863
 
779
864
  # Ensure we haven't created an invalid URI
780
865
  validate()
@@ -844,6 +929,7 @@ module Addressable
844
929
  # Reset dependant values
845
930
  @authority = nil
846
931
  @uri_string = nil
932
+ @hash = nil
847
933
 
848
934
  # Ensure we haven't created an invalid URI
849
935
  validate()
@@ -899,6 +985,7 @@ module Addressable
899
985
  @authority = nil
900
986
  @normalized_host = nil
901
987
  @uri_string = nil
988
+ @hash = nil
902
989
 
903
990
  # Ensure we haven't created an invalid URI
904
991
  validate()
@@ -984,14 +1071,35 @@ module Addressable
984
1071
  @userinfo = nil
985
1072
  @normalized_userinfo = nil
986
1073
  @uri_string = nil
1074
+ @hash = nil
987
1075
 
988
1076
  # Ensure we haven't created an invalid URI
989
1077
  validate()
990
1078
  end
991
1079
 
1080
+ ##
1081
+ # The origin for this URI, serialized to ASCII, as per
1082
+ # draft-ietf-websec-origin-00, section 5.2.
1083
+ #
1084
+ # @return [String] The serialized origin.
1085
+ def origin
1086
+ return (if self.scheme && self.authority
1087
+ if self.normalized_port
1088
+ (
1089
+ "#{self.normalized_scheme}://#{self.normalized_host}" +
1090
+ ":#{self.normalized_port}"
1091
+ )
1092
+ else
1093
+ "#{self.normalized_scheme}://#{self.normalized_host}"
1094
+ end
1095
+ else
1096
+ "null"
1097
+ end)
1098
+ end
1099
+
992
1100
  # Returns an array of known ip-based schemes. These schemes typically
993
1101
  # use a similar URI form:
994
- # //<user>:<password>@<host>:<port>/<url-path>
1102
+ # <code>//<user>:<password>@<host>:<port>/<url-path></code>
995
1103
  def self.ip_based_schemes
996
1104
  return self.port_mapping.keys
997
1105
  end
@@ -1065,6 +1173,7 @@ module Addressable
1065
1173
  @inferred_port = nil
1066
1174
  @normalized_port = nil
1067
1175
  @uri_string = nil
1176
+ @hash = nil
1068
1177
 
1069
1178
  # Ensure we haven't created an invalid URI
1070
1179
  validate()
@@ -1090,6 +1199,76 @@ module Addressable
1090
1199
  end)
1091
1200
  end
1092
1201
 
1202
+ ##
1203
+ # The combination of components that represent a site.
1204
+ # Combines the scheme, user, password, host, and port components.
1205
+ # Primarily useful for HTTP and HTTPS.
1206
+ #
1207
+ # For example, <code>"http://example.com/path?query"</code> would have a
1208
+ # <code>site</code> value of <code>"http://example.com"</code>.
1209
+ #
1210
+ # @return [String] The components that identify a site.
1211
+ def site
1212
+ @site ||= (begin
1213
+ if self.scheme || self.authority
1214
+ site_string = ""
1215
+ site_string << "#{self.scheme}:" if self.scheme != nil
1216
+ site_string << "//#{self.authority}" if self.authority != nil
1217
+ site_string
1218
+ else
1219
+ nil
1220
+ end
1221
+ end)
1222
+ end
1223
+
1224
+ ##
1225
+ # The normalized combination of components that represent a site.
1226
+ # Combines the scheme, user, password, host, and port components.
1227
+ # Primarily useful for HTTP and HTTPS.
1228
+ #
1229
+ # For example, <code>"http://example.com/path?query"</code> would have a
1230
+ # <code>site</code> value of <code>"http://example.com"</code>.
1231
+ #
1232
+ # @return [String] The normalized components that identify a site.
1233
+ def normalized_site
1234
+ @site ||= (begin
1235
+ if self.normalized_scheme || self.normalized_authority
1236
+ site_string = ""
1237
+ if self.normalized_scheme != nil
1238
+ site_string << "#{self.normalized_scheme}:"
1239
+ end
1240
+ if self.normalized_authority != nil
1241
+ site_string << "//#{self.normalized_authority}"
1242
+ end
1243
+ site_string
1244
+ else
1245
+ nil
1246
+ end
1247
+ end)
1248
+ end
1249
+
1250
+ ##
1251
+ # Sets the site value for this URI.
1252
+ #
1253
+ # @param [String, #to_str] new_site The new site value.
1254
+ def site=(new_site)
1255
+ if new_site
1256
+ if !new_site.respond_to?(:to_str)
1257
+ raise TypeError, "Can't convert #{new_site.class} into String."
1258
+ end
1259
+ new_site = new_site.to_str
1260
+ # These two regular expressions derived from the primary parsing
1261
+ # expression
1262
+ self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1]
1263
+ self.authority = new_site[
1264
+ /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1
1265
+ ]
1266
+ else
1267
+ self.scheme = nil
1268
+ self.authority = nil
1269
+ end
1270
+ end
1271
+
1093
1272
  ##
1094
1273
  # The path component for this URI.
1095
1274
  #
@@ -1105,8 +1284,13 @@ module Addressable
1105
1284
  # @return [String] The path component, normalized.
1106
1285
  def normalized_path
1107
1286
  @normalized_path ||= (begin
1287
+ if self.scheme == nil && self.path != nil && self.path != "" &&
1288
+ self.path =~ /^(?!\/)[^\/:]*:.*$/
1289
+ # Relative paths with colons in the first segment are ambiguous.
1290
+ self.path.sub!(":", "%2F")
1291
+ end
1108
1292
  # String#split(delimeter, -1) uses the more strict splitting behavior
1109
- # found in Python.
1293
+ # found by default in Python.
1110
1294
  result = (self.path.strip.split("/", -1).map do |segment|
1111
1295
  Addressable::URI.normalize_component(
1112
1296
  segment,
@@ -1141,6 +1325,7 @@ module Addressable
1141
1325
  # Reset dependant values
1142
1326
  @normalized_path = nil
1143
1327
  @uri_string = nil
1328
+ @hash = nil
1144
1329
  end
1145
1330
 
1146
1331
  ##
@@ -1203,17 +1388,18 @@ module Addressable
1203
1388
  # Reset dependant values
1204
1389
  @normalized_query = nil
1205
1390
  @uri_string = nil
1391
+ @hash = nil
1206
1392
  end
1207
1393
 
1208
1394
  ##
1209
1395
  # Converts the query component to a Hash value.
1210
1396
  #
1211
1397
  # @option [Symbol] notation
1212
- # May be one of <tt>:flat</tt>, <tt>:dot</tt>, or <tt>:subscript</tt>.
1213
- # The <tt>:dot</tt> notation is not supported for assignment. Default
1214
- # value is <tt>:subscript</tt>.
1398
+ # May be one of <code>:flat</code>, <code>:dot</code>, or
1399
+ # <code>:subscript</code>. The <code>:dot</code> notation is not
1400
+ # supported for assignment. Default value is <code>:subscript</code>.
1215
1401
  #
1216
- # @return [Hash] The query string parsed as a Hash object.
1402
+ # @return [Hash, Array] The query string parsed as a Hash or Array object.
1217
1403
  #
1218
1404
  # @example
1219
1405
  # Addressable::URI.parse("?one=1&two=2&three=3").query_values
@@ -1236,12 +1422,16 @@ module Addressable
1236
1422
  # "?one[two][three][]=four&one[two][three][]=five"
1237
1423
  # ).query_values
1238
1424
  # #=> {"one" => {"two" => {"three" => ["four", "five"]}}}
1425
+ # Addressable::URI.parse(
1426
+ # "?one=two&one=three").query_values(:notation => :flat_array)
1427
+ # #=> [['one', 'two'], ['one', 'three']]
1239
1428
  def query_values(options={})
1240
1429
  defaults = {:notation => :subscript}
1241
1430
  options = defaults.merge(options)
1242
- if ![:flat, :dot, :subscript].include?(options[:notation])
1431
+ if ![:flat, :dot, :subscript, :flat_array].include?(options[:notation])
1243
1432
  raise ArgumentError,
1244
- "Invalid notation. Must be one of: [:flat, :dot, :subscript]."
1433
+ "Invalid notation. Must be one of: " +
1434
+ "[:flat, :dot, :subscript, :flat_array]."
1245
1435
  end
1246
1436
  dehash = lambda do |hash|
1247
1437
  hash.each do |(key, value)|
@@ -1258,19 +1448,22 @@ module Addressable
1258
1448
  end
1259
1449
  end
1260
1450
  return nil if self.query == nil
1451
+ empty_accumulator = :flat_array == options[:notation] ? [] : {}
1261
1452
  return ((self.query.split("&").map do |pair|
1262
- pair.split("=")
1263
- end).inject({}) do |accumulator, (key, value)|
1453
+ pair.split("=", 2) if pair && pair != ""
1454
+ end).compact.inject(empty_accumulator.dup) do |accumulator, (key, value)|
1264
1455
  value = true if value.nil?
1265
1456
  key = self.class.unencode_component(key)
1266
1457
  if value != true
1267
- value = self.class.unencode_component(value).gsub(/\+/, " ")
1458
+ value = self.class.unencode_component(value.gsub(/\+/, " "))
1268
1459
  end
1269
1460
  if options[:notation] == :flat
1270
1461
  if accumulator[key]
1271
1462
  raise ArgumentError, "Key was repeated: #{key.inspect}"
1272
1463
  end
1273
1464
  accumulator[key] = value
1465
+ elsif options[:notation] == :flat_array
1466
+ accumulator << [key, value]
1274
1467
  else
1275
1468
  if options[:notation] == :dot
1276
1469
  array_value = false
@@ -1293,8 +1486,12 @@ module Addressable
1293
1486
  end
1294
1487
  end
1295
1488
  accumulator
1296
- end).inject({}) do |accumulator, (key, value)|
1297
- accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1489
+ end).inject(empty_accumulator.dup) do |accumulator, (key, value)|
1490
+ if options[:notation] == :flat_array
1491
+ accumulator << [key, value]
1492
+ else
1493
+ accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1494
+ end
1298
1495
  accumulator
1299
1496
  end
1300
1497
  end
@@ -1302,15 +1499,32 @@ module Addressable
1302
1499
  ##
1303
1500
  # Sets the query component for this URI from a Hash object.
1304
1501
  # This method produces a query string using the :subscript notation.
1502
+ # An empty Hash will result in a nil query.
1305
1503
  #
1306
- # @param [Hash, #to_hash] new_query_values The new query values.
1504
+ # @param [Hash, #to_hash, Array] new_query_values The new query values.
1307
1505
  def query_values=(new_query_values)
1308
1506
  # Check for frozenness
1309
1507
  raise TypeError, "Can't modify frozen URI." if self.frozen?
1310
- if !new_query_values.respond_to?(:to_hash)
1311
- raise TypeError, "Can't convert #{new_query_values.class} into Hash."
1508
+ if new_query_values == nil
1509
+ self.query = nil
1510
+ return nil
1511
+ end
1512
+
1513
+ if !new_query_values.is_a?(Array)
1514
+ if !new_query_values.respond_to?(:to_hash)
1515
+ raise TypeError,
1516
+ "Can't convert #{new_query_values.class} into Hash."
1517
+ end
1518
+ new_query_values = new_query_values.to_hash
1519
+ new_query_values = new_query_values.map do |key, value|
1520
+ key = key.to_s if key.kind_of?(Symbol)
1521
+ [key, value]
1522
+ end
1523
+ # Useful default for OAuth and caching.
1524
+ # Only to be used for non-Array inputs. Arrays should preserve order.
1525
+ new_query_values.sort!
1312
1526
  end
1313
- new_query_values = new_query_values.to_hash
1527
+ # new_query_values have form [['key1', 'value1'], ['key2', 'value2']]
1314
1528
 
1315
1529
  # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
1316
1530
  buffer = ""
@@ -1344,11 +1558,7 @@ module Addressable
1344
1558
  end
1345
1559
  end
1346
1560
  end
1347
- @query = buffer.chop
1348
-
1349
- # Reset dependant values
1350
- @normalized_query = nil
1351
- @uri_string = nil
1561
+ self.query = buffer.chop
1352
1562
  end
1353
1563
 
1354
1564
  ##
@@ -1386,6 +1596,7 @@ module Addressable
1386
1596
 
1387
1597
  # Reset dependant values
1388
1598
  @uri_string = nil
1599
+ @hash = nil
1389
1600
  end
1390
1601
 
1391
1602
  ##
@@ -1429,6 +1640,7 @@ module Addressable
1429
1640
  # Reset dependant values
1430
1641
  @normalized_fragment = nil
1431
1642
  @uri_string = nil
1643
+ @hash = nil
1432
1644
 
1433
1645
  # Ensure we haven't created an invalid URI
1434
1646
  validate()
@@ -1438,8 +1650,8 @@ module Addressable
1438
1650
  # Determines if the scheme indicates an IP-based protocol.
1439
1651
  #
1440
1652
  # @return [TrueClass, FalseClass]
1441
- # <tt>true</tt> if the scheme indicates an IP-based protocol.
1442
- # <tt>false</tt> otherwise.
1653
+ # <code>true</code> if the scheme indicates an IP-based protocol.
1654
+ # <code>false</code> otherwise.
1443
1655
  def ip_based?
1444
1656
  if self.scheme
1445
1657
  return self.class.ip_based_schemes.include?(
@@ -1452,7 +1664,8 @@ module Addressable
1452
1664
  # Determines if the URI is relative.
1453
1665
  #
1454
1666
  # @return [TrueClass, FalseClass]
1455
- # <tt>true</tt> if the URI is relative. <tt>false</tt> otherwise.
1667
+ # <code>true</code> if the URI is relative. <code>false</code>
1668
+ # otherwise.
1456
1669
  def relative?
1457
1670
  return self.scheme.nil?
1458
1671
  end
@@ -1461,7 +1674,8 @@ module Addressable
1461
1674
  # Determines if the URI is absolute.
1462
1675
  #
1463
1676
  # @return [TrueClass, FalseClass]
1464
- # <tt>true</tt> if the URI is absolute. <tt>false</tt> otherwise.
1677
+ # <code>true</code> if the URI is absolute. <code>false</code>
1678
+ # otherwise.
1465
1679
  def absolute?
1466
1680
  return !relative?
1467
1681
  end
@@ -1568,7 +1782,7 @@ module Addressable
1568
1782
  alias_method :+, :join
1569
1783
 
1570
1784
  ##
1571
- # Destructive form of <tt>join</tt>.
1785
+ # Destructive form of <code>join</code>.
1572
1786
  #
1573
1787
  # @param [String, Addressable::URI, #to_str] The URI to join with.
1574
1788
  #
@@ -1580,10 +1794,10 @@ module Addressable
1580
1794
  end
1581
1795
 
1582
1796
  ##
1583
- # Merges a URI with a <tt>Hash</tt> of components.
1584
- # This method has different behavior from <tt>join</tt>. Any components
1585
- # present in the <tt>hash</tt> parameter will override the original
1586
- # components. The path component is not treated specially.
1797
+ # Merges a URI with a <code>Hash</code> of components.
1798
+ # This method has different behavior from <code>join</code>. Any
1799
+ # components present in the <code>hash</code> parameter will override the
1800
+ # original components. The path component is not treated specially.
1587
1801
  #
1588
1802
  # @param [Hash, Addressable::URI, #to_hash] The components to merge with.
1589
1803
  #
@@ -1648,7 +1862,7 @@ module Addressable
1648
1862
  end
1649
1863
 
1650
1864
  ##
1651
- # Destructive form of <tt>merge</tt>.
1865
+ # Destructive form of <code>merge</code>.
1652
1866
  #
1653
1867
  # @param [Hash, Addressable::URI, #to_hash] The components to merge with.
1654
1868
  #
@@ -1662,7 +1876,7 @@ module Addressable
1662
1876
  ##
1663
1877
  # Returns the shortest normalized relative form of this URI that uses the
1664
1878
  # supplied URI as a base for resolution. Returns an absolute URI if
1665
- # necessary. This is effectively the opposite of <tt>route_to</tt>.
1879
+ # necessary. This is effectively the opposite of <code>route_to</code>.
1666
1880
  #
1667
1881
  # @param [String, Addressable::URI, #to_str] uri The URI to route from.
1668
1882
  #
@@ -1720,7 +1934,7 @@ module Addressable
1720
1934
  ##
1721
1935
  # Returns the shortest normalized relative form of the supplied URI that
1722
1936
  # uses this URI as a base for resolution. Returns an absolute URI if
1723
- # necessary. This is effectively the opposite of <tt>route_from</tt>.
1937
+ # necessary. This is effectively the opposite of <code>route_from</code>.
1724
1938
  #
1725
1939
  # @param [String, Addressable::URI, #to_str] uri The URI to route to.
1726
1940
  #
@@ -1784,14 +1998,15 @@ module Addressable
1784
1998
  end
1785
1999
 
1786
2000
  ##
1787
- # Returns <tt>true</tt> if the URI objects are equal. This method
2001
+ # Returns <code>true</code> if the URI objects are equal. This method
1788
2002
  # normalizes both URIs before doing the comparison, and allows comparison
1789
- # against <tt>Strings</tt>.
2003
+ # against <code>Strings</code>.
1790
2004
  #
1791
2005
  # @param [Object] uri The URI to compare.
1792
2006
  #
1793
2007
  # @return [TrueClass, FalseClass]
1794
- # <tt>true</tt> if the URIs are equivalent, <tt>false</tt> otherwise.
2008
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2009
+ # otherwise.
1795
2010
  def ===(uri)
1796
2011
  if uri.respond_to?(:normalize)
1797
2012
  uri_string = uri.normalize.to_s
@@ -1806,26 +2021,28 @@ module Addressable
1806
2021
  end
1807
2022
 
1808
2023
  ##
1809
- # Returns <tt>true</tt> if the URI objects are equal. This method
2024
+ # Returns <code>true</code> if the URI objects are equal. This method
1810
2025
  # normalizes both URIs before doing the comparison.
1811
2026
  #
1812
2027
  # @param [Object] uri The URI to compare.
1813
2028
  #
1814
2029
  # @return [TrueClass, FalseClass]
1815
- # <tt>true</tt> if the URIs are equivalent, <tt>false</tt> otherwise.
2030
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2031
+ # otherwise.
1816
2032
  def ==(uri)
1817
2033
  return false unless uri.kind_of?(self.class)
1818
2034
  return self.normalize.to_s == uri.normalize.to_s
1819
2035
  end
1820
2036
 
1821
2037
  ##
1822
- # Returns <tt>true</tt> if the URI objects are equal. This method
2038
+ # Returns <code>true</code> if the URI objects are equal. This method
1823
2039
  # does NOT normalize either URI before doing the comparison.
1824
2040
  #
1825
2041
  # @param [Object] uri The URI to compare.
1826
2042
  #
1827
2043
  # @return [TrueClass, FalseClass]
1828
- # <tt>true</tt> if the URIs are equivalent, <tt>false</tt> otherwise.
2044
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2045
+ # otherwise.
1829
2046
  def eql?(uri)
1830
2047
  return false unless uri.kind_of?(self.class)
1831
2048
  return self.to_s == uri.to_s
@@ -1875,7 +2092,7 @@ module Addressable
1875
2092
  # Determines if the URI is frozen.
1876
2093
  #
1877
2094
  # @return [TrueClass, FalseClass]
1878
- # True if the URI is frozen, false otherwise.
2095
+ # <code>true</code> if the URI is frozen, <code>false</code> otherwise.
1879
2096
  def frozen?
1880
2097
  self.to_s.frozen?
1881
2098
  end
@@ -1924,9 +2141,9 @@ module Addressable
1924
2141
  end
1925
2142
 
1926
2143
  ##
1927
- # Converts the URI to a <tt>String</tt>.
2144
+ # Converts the URI to a <code>String</code>.
1928
2145
  #
1929
- # @return [String] The URI's <tt>String</tt> representation.
2146
+ # @return [String] The URI's <code>String</code> representation.
1930
2147
  def to_s
1931
2148
  @uri_string ||= (begin
1932
2149
  uri_string = ""
@@ -1943,13 +2160,13 @@ module Addressable
1943
2160
  end
1944
2161
 
1945
2162
  ##
1946
- # URI's are glorified <tt>Strings</tt>. Allow implicit conversion.
2163
+ # URI's are glorified <code>Strings</code>. Allow implicit conversion.
1947
2164
  alias_method :to_str, :to_s
1948
2165
 
1949
2166
  ##
1950
2167
  # Returns a Hash of the URI components.
1951
2168
  #
1952
- # @return [Hash] The URI as a <tt>Hash</tt> of components.
2169
+ # @return [Hash] The URI as a <code>Hash</code> of components.
1953
2170
  def to_hash
1954
2171
  return {
1955
2172
  :scheme => self.scheme,
@@ -1964,9 +2181,9 @@ module Addressable
1964
2181
  end
1965
2182
 
1966
2183
  ##
1967
- # Returns a <tt>String</tt> representation of the URI object's state.
2184
+ # Returns a <code>String</code> representation of the URI object's state.
1968
2185
  #
1969
- # @return [String] The URI object's state, as a <tt>String</tt>.
2186
+ # @return [String] The URI object's state, as a <code>String</code>.
1970
2187
  def inspect
1971
2188
  sprintf("#<%s:%#0x URI:%s>", self.class.to_s, self.object_id, self.to_s)
1972
2189
  end
@@ -2015,6 +2232,9 @@ module Addressable
2015
2232
  end
2016
2233
  normalized_path.gsub!(/^\.\.?\/?/, "")
2017
2234
  normalized_path.gsub!(/^\/\.\.?\//, "/")
2235
+
2236
+ # Non-standard
2237
+ normalized_path.gsub!(/^(\/\.\.?)+\/?$/, "/")
2018
2238
  end until previous_state == normalized_path
2019
2239
  return normalized_path
2020
2240
  end
@@ -2036,6 +2256,11 @@ module Addressable
2036
2256
  raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'"
2037
2257
  end
2038
2258
  end
2259
+ if self.path != nil && self.path != "" && self.path[0..0] != "/" &&
2260
+ self.authority != nil
2261
+ raise InvalidURIError,
2262
+ "Cannot have a relative path with an authority set: '#{self.to_s}'"
2263
+ end
2039
2264
  return nil
2040
2265
  end
2041
2266
 
@@ -2043,9 +2268,9 @@ module Addressable
2043
2268
  # Replaces the internal state of self with the specified URI's state.
2044
2269
  # Used in destructive operations to avoid massive code repetition.
2045
2270
  #
2046
- # @param [Addressable::URI] uri The URI to replace <tt>self</tt> with.
2271
+ # @param [Addressable::URI] uri The URI to replace <code>self</code> with.
2047
2272
  #
2048
- # @return [Addressable::URI] <tt>self</tt>.
2273
+ # @return [Addressable::URI] <code>self</code>.
2049
2274
  def replace_self(uri)
2050
2275
  # Reset dependant values
2051
2276
  instance_variables.each do |var|