addressable 2.3.8 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of addressable might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42b16f73eeb6e9fe31be8acca16028ec89e5a083
4
- data.tar.gz: 988538325db6737260f2ac394e84d349fdbe2f79
3
+ metadata.gz: 77783a5c4c07f7a0862f0efaeb2619a278e32391
4
+ data.tar.gz: 8edbb65fa242ce03cf2403c192d2358da64a095b
5
5
  SHA512:
6
- metadata.gz: be930a660ee582f6d780ab759085489652f9c5a68d51177247b1aff10e06df0e95a2d149f0c37206e1d5e4b2dc63fca24b6e46aaed3082c26e3b2ee9e3c718d8
7
- data.tar.gz: 03eba1032a368e484693085431a5890cbec4c09290c69d06b71a5c59d088bd1be11632d9d32581f2f20d37939b466bcbc98dcfc1a870f086feb6267a8755eacf
6
+ metadata.gz: b3345827151e1d04e5c532cca1e8e63337b0ce9d9f0e276861ed6be95b114827f68d5f74e5bea857db1faaf7a70a928159436f5e51cbbecc4a6db64145d28ea2
7
+ data.tar.gz: 86e4d5c946972502c8ac79bf2582d0d6894db23fa2e285c69b8dae0d1e16fcad447e7f8f393eeb9e9891f0a30e0971f864449b6dfaf4104bee080cfb3dfe4af4
@@ -1,3 +1,15 @@
1
+ # Addressable 2.4.0
2
+ - support for 1.8.x dropped
3
+ - double quotes in a host now raises an error
4
+ - newlines in host will no longer get unescaped during normalization
5
+ - stricter handling of bogus scheme values
6
+ - stricter handling of encoded port values
7
+ - calling `require 'addressable'` will now load both the URI and Template files
8
+ - assigning to the `hostname` component with an `IPAddr` object is now supported
9
+ - assigning to the `origin` component is now supported
10
+ - fixed minor bug where an exception would be thrown for a missing ACE suffix
11
+ - better partial expansion of URI templates
12
+
1
13
  # Addressable 2.3.8
2
14
  - fix warnings
3
15
  - update dependency gems
data/Gemfile CHANGED
@@ -2,26 +2,26 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'rake', '~> 10.4', '>= 10.4.2'
6
+
7
+ group :test do
8
+ gem 'rspec', '~> 3.0'
9
+ gem 'rspec-its', '~> 1.1'
10
+ end
11
+
5
12
  group :development do
6
- gem 'yard'
13
+ gem 'launchy', '~> 2.4', '>= 2.4.3'
7
14
  gem 'redcarpet', :platform => :mri_19
8
- gem 'rubyforge'
15
+ gem 'yard'
9
16
  end
10
17
 
11
18
  group :test, :development do
19
+ gem 'simplecov', :require => false
12
20
  gem 'coveralls', :require => false, :platforms => [
13
21
  :ruby_19, :ruby_20, :ruby_21, :rbx, :jruby
14
22
  ]
23
+ # Used to test compatibility.
24
+ gem 'rack-mount', git: 'https://github.com/sporkmonger/rack-mount.git', require: 'rack/mount'
15
25
  end
16
26
 
17
- gem 'idn', :platform => :mri_18
18
- gem 'idn-ruby', :platform => :mri_19
19
-
20
- platforms :ruby_18 do
21
- gem 'mime-types', '~> 1.25'
22
- gem 'rest-client', '~> 1.6.8'
23
- end
24
-
25
- platforms :rbx do
26
- gem 'rubysl-openssl', '2.2.1'
27
- end
27
+ gem 'idn-ruby', :platform => [:mri_19, :mri_20, :mri_21, :mri_22]
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Addressable
2
2
 
3
3
  <dl>
4
- <dt>Homepage</dt><dd><a href="http://addressable.rubyforge.org/">addressable.rubyforge.org</a></dd>
4
+ <dt>Homepage</dt><dd><a href="https://github.com/sporkmonger/addressable">github.com/sporkmonger/addressable</a></dd>
5
5
  <dt>Author</dt><dd><a href="mailto:bob@sporkmonger.com">Bob Aman</a></dd>
6
6
  <dt>Copyright</dt><dd>Copyright © 2006-2015 Bob Aman</dd>
7
7
  <dt>License</dt><dd>Apache 2.0</dd>
@@ -68,7 +68,7 @@ template.expand({
68
68
  })
69
69
  #=> #<Addressable::URI:0xc9d95c URI:http://example.com/?foo=bar&color=red>
70
70
 
71
- template = Addressable::Template.new("http://example.com/{?one,two,three}/")
71
+ template = Addressable::Template.new("http://example.com/{?one,two,three}")
72
72
  template.partial_expand({"one" => "1", "three" => 3}).pattern
73
73
  #=> "http://example.com/?one=1{&two}&three=3"
74
74
 
@@ -100,6 +100,6 @@ idn gem:
100
100
 
101
101
  ```console
102
102
  $ sudo apt-get install idn # Debian/Ubuntu
103
- $ sudo brew install libidn # OS X
104
- $ sudo gem install idn-ruby
103
+ $ brew install libidn # OS X
104
+ $ gem install idn-ruby
105
105
  ```
data/Rakefile CHANGED
@@ -19,11 +19,11 @@ TEXT
19
19
 
20
20
  PKG_FILES = FileList[
21
21
  "lib/**/*", "spec/**/*", "vendor/**/*", "data/**/*",
22
- "tasks/**/*", "website/**/*",
22
+ "tasks/**/*",
23
23
  "[A-Z]*", "Rakefile"
24
- ].exclude(/database\.yml/).exclude(/Gemfile\.lock/).exclude(/[_\.]git$/)
24
+ ].exclude(/pkg/).exclude(/database\.yml/).
25
+ exclude(/Gemfile\.lock/).exclude(/[_\.]git$/)
25
26
 
26
- RCOV_ENABLED = (RUBY_PLATFORM != "java" && RUBY_VERSION =~ /^1\.8/)
27
27
  task :default => "spec"
28
28
 
29
29
  WINDOWS = (RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/) rescue false
@@ -1,42 +1,34 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: addressable 2.3.8 ruby lib
2
+ # stub: addressable 2.4.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "addressable"
6
- s.version = "2.3.8"
6
+ s.version = "2.4.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["Bob Aman"]
11
- s.date = "2015-03-27"
11
+ s.date = "2015-12-07"
12
12
  s.description = "Addressable is a replacement for the URI implementation that is part of\nRuby's standard library. It more closely conforms to the relevant RFCs and\nadds support for IRIs and URI templates.\n"
13
13
  s.email = "bob@sporkmonger.com"
14
14
  s.extra_rdoc_files = ["README.md"]
15
- s.files = ["CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "addressable.gemspec", "data/unicode.data", "lib/addressable/idna.rb", "lib/addressable/idna/native.rb", "lib/addressable/idna/pure.rb", "lib/addressable/template.rb", "lib/addressable/uri.rb", "lib/addressable/version.rb", "spec/addressable/idna_spec.rb", "spec/addressable/net_http_compat_spec.rb", "spec/addressable/template_spec.rb", "spec/addressable/uri_spec.rb", "spec/spec_helper.rb", "tasks/clobber.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rspec.rake", "tasks/yard.rake", "website/index.html"]
15
+ s.files = ["CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "addressable.gemspec", "data/unicode.data", "lib/addressable.rb", "lib/addressable/idna.rb", "lib/addressable/idna/native.rb", "lib/addressable/idna/pure.rb", "lib/addressable/template.rb", "lib/addressable/uri.rb", "lib/addressable/version.rb", "spec/addressable/idna_spec.rb", "spec/addressable/net_http_compat_spec.rb", "spec/addressable/rack_mount_compat_spec.rb", "spec/addressable/security_spec.rb", "spec/addressable/template_spec.rb", "spec/addressable/uri_spec.rb", "spec/spec_helper.rb", "tasks/clobber.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rspec.rake", "tasks/yard.rake"]
16
16
  s.homepage = "https://github.com/sporkmonger/addressable"
17
- s.licenses = ["Apache License 2.0"]
17
+ s.licenses = ["Apache-2.0"]
18
18
  s.rdoc_options = ["--main", "README.md"]
19
- s.rubygems_version = "2.4.6"
19
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.0")
20
+ s.rubygems_version = "2.5.0"
20
21
  s.summary = "URI Implementation"
21
22
 
22
23
  if s.respond_to? :specification_version then
23
24
  s.specification_version = 4
24
25
 
25
26
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
- s.add_development_dependency(%q<rake>, [">= 10.4.2", "~> 10.4"])
27
- s.add_development_dependency(%q<rspec>, ["~> 3.0"])
28
- s.add_development_dependency(%q<rspec-its>, ["~> 1.1"])
29
- s.add_development_dependency(%q<launchy>, [">= 2.4.3", "~> 2.4"])
27
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
30
28
  else
31
- s.add_dependency(%q<rake>, [">= 10.4.2", "~> 10.4"])
32
- s.add_dependency(%q<rspec>, ["~> 3.0"])
33
- s.add_dependency(%q<rspec-its>, ["~> 1.1"])
34
- s.add_dependency(%q<launchy>, [">= 2.4.3", "~> 2.4"])
29
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
35
30
  end
36
31
  else
37
- s.add_dependency(%q<rake>, [">= 10.4.2", "~> 10.4"])
38
- s.add_dependency(%q<rspec>, ["~> 3.0"])
39
- s.add_dependency(%q<rspec-its>, ["~> 1.1"])
40
- s.add_dependency(%q<launchy>, [">= 2.4.3", "~> 2.4"])
32
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
41
33
  end
42
34
  end
@@ -0,0 +1,2 @@
1
+ require 'addressable/uri'
2
+ require 'addressable/template'
@@ -93,7 +93,7 @@ module Addressable
93
93
  input = input.to_s unless input.is_a?(String)
94
94
  parts = input.split('.')
95
95
  parts.map! do |part|
96
- if part =~ /^#{ACE_PREFIX}/
96
+ if part =~ /^#{ACE_PREFIX}(.+)/
97
97
  punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1])
98
98
  else
99
99
  part
@@ -175,7 +175,6 @@ module Addressable
175
175
 
176
176
  p = []
177
177
  ucs4_to_utf8 = lambda do |ch|
178
- # For some reason, rcov likes to drop BUS errors here.
179
178
  if ch < 128
180
179
  p << ch
181
180
  elsif ch < 2048
@@ -488,7 +487,7 @@ module Addressable
488
487
  outlen.times do |j|
489
488
  c = output[j]
490
489
  unless c >= 0 && c <= 127
491
- raise Exception, "Invalid output char."
490
+ raise StandardError, "Invalid output char."
492
491
  end
493
492
  unless PUNYCODE_PRINT_ASCII[c]
494
493
  raise PunycodeBadInput, "Input is invalid."
@@ -234,7 +234,18 @@ module Addressable
234
234
  if !pattern.respond_to?(:to_str)
235
235
  raise TypeError, "Can't convert #{pattern.class} into String."
236
236
  end
237
- @pattern = pattern.to_str.freeze
237
+ @pattern = pattern.to_str.dup.freeze
238
+ end
239
+
240
+ ##
241
+ # Freeze URI, initializing instance variables.
242
+ #
243
+ # @return [Addressable::URI] The frozen URI object.
244
+ def freeze
245
+ self.variables
246
+ self.variable_defaults
247
+ self.named_captures
248
+ super
238
249
  end
239
250
 
240
251
  ##
@@ -592,6 +603,7 @@ module Addressable
592
603
  @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq
593
604
  end
594
605
  alias_method :keys, :variables
606
+ alias_method :names, :variables
595
607
 
596
608
  ##
597
609
  # Returns a mapping of variables to their default values specified
@@ -603,9 +615,75 @@ module Addressable
603
615
  Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten]
604
616
  end
605
617
 
618
+ ##
619
+ # Coerces a template into a `Regexp` object. This regular expression will
620
+ # behave very similarly to the actual template, and should match the same
621
+ # URI values, but it cannot fully handle, for example, values that would
622
+ # extract to an `Array`.
623
+ #
624
+ # @return [Regexp] A regular expression which should match the template.
625
+ def to_regexp
626
+ _, source = parse_template_pattern(pattern)
627
+ Regexp.new(source)
628
+ end
629
+
630
+ ##
631
+ # Returns the source of the coerced `Regexp`.
632
+ #
633
+ # @return [String] The source of the `Regexp` given by {#to_regexp}.
634
+ #
635
+ # @api private
636
+ def source
637
+ self.to_regexp.source
638
+ end
639
+
640
+ ##
641
+ # Returns the named captures of the coerced `Regexp`.
642
+ #
643
+ # @return [Hash] The named captures of the `Regexp` given by {#to_regexp}.
644
+ #
645
+ # @api private
646
+ def named_captures
647
+ self.to_regexp.named_captures
648
+ end
649
+
650
+ ##
651
+ # Generates a route result for a given set of parameters.
652
+ # Should only be used by rack-mount.
653
+ #
654
+ # @param params [Hash] The set of parameters used to expand the template.
655
+ # @param recall [Hash] Default parameters used to expand the template.
656
+ # @param options [Hash] Either a `:processor` or a `:parameterize` block.
657
+ #
658
+ # @api private
659
+ def generate(params={}, recall={}, options={})
660
+ merged = recall.merge(params)
661
+ if options[:processor]
662
+ processor = options[:processor]
663
+ elsif options[:parameterize]
664
+ # TODO: This is sending me into fits trying to shoe-horn this into
665
+ # the existing API. I think I've got this backwards and processors
666
+ # should be a set of 4 optional blocks named :validate, :transform,
667
+ # :match, and :restore. Having to use a singleton here is a huge
668
+ # code smell.
669
+ processor = Object.new
670
+ class <<processor
671
+ attr_accessor :block
672
+ def transform(name, value)
673
+ block.call(name, value)
674
+ end
675
+ end
676
+ processor.block = options[:parameterize]
677
+ else
678
+ processor = nil
679
+ end
680
+ result = self.expand(merged, processor)
681
+ result.to_s if result
682
+ end
683
+
606
684
  private
607
685
  def ordered_variable_defaults
608
- @ordered_variable_defaults ||= (
686
+ @ordered_variable_defaults ||= begin
609
687
  expansions, _ = parse_template_pattern(pattern)
610
688
  expansions.map do |capture|
611
689
  _, _, varlist = *capture.match(EXPRESSION)
@@ -613,7 +691,7 @@ module Addressable
613
691
  varspec[VARSPEC, 1]
614
692
  end
615
693
  end.flatten
616
- )
694
+ end
617
695
  end
618
696
 
619
697
 
@@ -642,19 +720,54 @@ module Addressable
642
720
  # @return [String] The expanded expression
643
721
  def transform_partial_capture(mapping, capture, processor = nil)
644
722
  _, operator, varlist = *capture.match(EXPRESSION)
645
- is_first = true
646
- varlist.split(',').inject('') do |acc, varspec|
647
- _, name, _ = *varspec.match(VARSPEC)
648
- value = mapping[name]
649
- if value
650
- operator = '&' if !is_first && operator == '?'
651
- acc << transform_capture(mapping, "{#{operator}#{varspec}}", processor)
652
- else
653
- operator = '&' if !is_first && operator == '?'
654
- acc << "{#{operator}#{varspec}}"
723
+
724
+ vars = varlist.split(',')
725
+
726
+ if '?' == operator
727
+ # partial expansion of form style query variables sometimes requires a
728
+ # slight reordering of the variables to produce a valid url.
729
+ first_to_expand = vars.find { |varspec|
730
+ _, name, _ = *varspec.match(VARSPEC)
731
+ mapping.key? name
732
+ }
733
+
734
+ vars = [first_to_expand] + vars.reject {|varspec| varspec == first_to_expand} if first_to_expand
735
+ end
736
+
737
+ vars
738
+ .zip(operator_sequence(operator).take(vars.length))
739
+ .reduce("") do |acc, (varspec, op)|
740
+ _, name, _ = *varspec.match(VARSPEC)
741
+
742
+ acc << if mapping.key? name
743
+ transform_capture(mapping, "{#{op}#{varspec}}", processor)
744
+ else
745
+ "{#{op}#{varspec}}"
746
+ end
747
+ end
748
+ end
749
+
750
+ ##
751
+ # Creates a lazy Enumerator of the operators that should be used to expand
752
+ # variables in a varlist starting with `operator`. For example, an operator
753
+ # `"?"` results in the sequence `"?","&","&"...`
754
+ #
755
+ # @param [String] operator from which to generate a sequence
756
+ #
757
+ # @return [Enumerator] sequence of operators
758
+ def operator_sequence(operator)
759
+ rest_operator = if "?" == operator
760
+ "&"
761
+ else
762
+ operator
763
+ end
764
+ head_operator = operator
765
+
766
+ Enumerator.new do |y|
767
+ y << head_operator.to_s
768
+ while true
769
+ y << rest_operator.to_s
655
770
  end
656
- is_first = false
657
- acc
658
771
  end
659
772
  end
660
773
 
@@ -899,7 +1012,7 @@ module Addressable
899
1012
 
900
1013
  result = processor && processor.respond_to?(:match) ? processor.match(name) : nil
901
1014
  if result
902
- "(#{ result })"
1015
+ "(?<#{name}>#{ result })"
903
1016
  else
904
1017
  group = case operator
905
1018
  when '+'
@@ -920,9 +1033,9 @@ module Addressable
920
1033
  "#{ UNRESERVED }*?"
921
1034
  end
922
1035
  if modifier == '*'
923
- "(#{group}(?:#{joiner}?#{group})*)?"
1036
+ "(?<#{name}>#{group}(?:#{joiner}?#{group})*)?"
924
1037
  else
925
- "(#{group})?"
1038
+ "(?<#{name}>#{group})?"
926
1039
  end
927
1040
  end
928
1041
  end.join("#{joiner}?")
@@ -19,10 +19,6 @@
19
19
  require "addressable/version"
20
20
  require "addressable/idna"
21
21
 
22
- if RUBY_VERSION =~ /^1.8/
23
- warn('Support for Ruby 1.8.x in Addressable is deprecated.')
24
- end
25
-
26
22
  ##
27
23
  # Addressable is a library for processing links and URIs.
28
24
  module Addressable
@@ -48,6 +44,7 @@ module Addressable
48
44
  UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
49
45
  PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
50
46
  SCHEME = ALPHA + DIGIT + "\\-\\+\\."
47
+ HOST = ALPHA + DIGIT + "\\-\\.\\[\\:\\]"
51
48
  AUTHORITY = PCHAR
52
49
  PATH = PCHAR + "\\/"
53
50
  QUERY = PCHAR + "\\/\\?"
@@ -724,9 +721,9 @@ module Addressable
724
721
  ).gsub("%20", "+")
725
722
  ]
726
723
  end
727
- return (escaped_form_values.map do |(key, value)|
724
+ return escaped_form_values.map do |(key, value)|
728
725
  "#{key}=#{value}"
729
- end).join("&")
726
+ end.join("&")
730
727
  end
731
728
 
732
729
  ##
@@ -835,7 +832,7 @@ module Addressable
835
832
  #
836
833
  # @return [String] The scheme component.
837
834
  def scheme
838
- return instance_variable_defined?(:@scheme) ? @scheme : nil
835
+ return defined?(@scheme) ? @scheme : nil
839
836
  end
840
837
 
841
838
  ##
@@ -843,7 +840,8 @@ module Addressable
843
840
  #
844
841
  # @return [String] The scheme component, normalized.
845
842
  def normalized_scheme
846
- self.scheme && @normalized_scheme ||= (begin
843
+ return nil unless self.scheme
844
+ @normalized_scheme ||= begin
847
845
  if self.scheme =~ /^\s*ssh\+svn\s*$/i
848
846
  "svn+ssh"
849
847
  else
@@ -852,7 +850,7 @@ module Addressable
852
850
  Addressable::URI::CharacterClasses::SCHEME
853
851
  )
854
852
  end
855
- end)
853
+ end
856
854
  end
857
855
 
858
856
  ##
@@ -865,16 +863,15 @@ module Addressable
865
863
  elsif new_scheme
866
864
  new_scheme = new_scheme.to_str
867
865
  end
868
- if new_scheme && new_scheme !~ /[a-z][a-z0-9\.\+\-]*/i
869
- raise InvalidURIError, "Invalid scheme format."
866
+ if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i
867
+ raise InvalidURIError, "Invalid scheme format: #{new_scheme}"
870
868
  end
871
869
  @scheme = new_scheme
872
870
  @scheme = nil if @scheme.to_s.strip.empty?
873
871
 
874
- # Reset dependant values
875
- @normalized_scheme = nil
876
- @uri_string = nil
877
- @hash = nil
872
+ # Reset dependent values
873
+ remove_instance_variable(:@normalized_scheme) if defined?(@normalized_scheme)
874
+ remove_composite_values
878
875
 
879
876
  # Ensure we haven't created an invalid URI
880
877
  validate()
@@ -885,7 +882,7 @@ module Addressable
885
882
  #
886
883
  # @return [String] The user component.
887
884
  def user
888
- return instance_variable_defined?(:@user) ? @user : nil
885
+ return defined?(@user) ? @user : nil
889
886
  end
890
887
 
891
888
  ##
@@ -893,7 +890,9 @@ module Addressable
893
890
  #
894
891
  # @return [String] The user component, normalized.
895
892
  def normalized_user
896
- self.user && @normalized_user ||= (begin
893
+ return nil unless self.user
894
+ return @normalized_user if defined?(@normalized_user)
895
+ @normalized_user ||= begin
897
896
  if normalized_scheme =~ /https?/ && self.user.strip.empty? &&
898
897
  (!self.password || self.password.strip.empty?)
899
898
  nil
@@ -903,7 +902,7 @@ module Addressable
903
902
  Addressable::URI::CharacterClasses::UNRESERVED
904
903
  )
905
904
  end
906
- end)
905
+ end
907
906
  end
908
907
 
909
908
  ##
@@ -921,13 +920,12 @@ module Addressable
921
920
  @user = EMPTY_STR if @user.nil?
922
921
  end
923
922
 
924
- # Reset dependant values
925
- @userinfo = nil
926
- @normalized_userinfo = nil
927
- @authority = nil
928
- @normalized_user = nil
929
- @uri_string = nil
930
- @hash = nil
923
+ # Reset dependent values
924
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
925
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
926
+ remove_instance_variable(:@authority) if defined?(@authority)
927
+ remove_instance_variable(:@normalized_user) if defined?(@normalized_user)
928
+ remove_composite_values
931
929
 
932
930
  # Ensure we haven't created an invalid URI
933
931
  validate()
@@ -938,7 +936,7 @@ module Addressable
938
936
  #
939
937
  # @return [String] The password component.
940
938
  def password
941
- return instance_variable_defined?(:@password) ? @password : nil
939
+ return defined?(@password) ? @password : nil
942
940
  end
943
941
 
944
942
  ##
@@ -946,7 +944,9 @@ module Addressable
946
944
  #
947
945
  # @return [String] The password component, normalized.
948
946
  def normalized_password
949
- self.password && @normalized_password ||= (begin
947
+ return nil unless self.password
948
+ return @normalized_password if defined?(@normalized_password)
949
+ @normalized_password ||= begin
950
950
  if self.normalized_scheme =~ /https?/ && self.password.strip.empty? &&
951
951
  (!self.user || self.user.strip.empty?)
952
952
  nil
@@ -956,7 +956,7 @@ module Addressable
956
956
  Addressable::URI::CharacterClasses::UNRESERVED
957
957
  )
958
958
  end
959
- end)
959
+ end
960
960
  end
961
961
 
962
962
  ##
@@ -976,13 +976,12 @@ module Addressable
976
976
  @user = EMPTY_STR if @user.nil?
977
977
  end
978
978
 
979
- # Reset dependant values
980
- @userinfo = nil
981
- @normalized_userinfo = nil
982
- @authority = nil
983
- @normalized_password = nil
984
- @uri_string = nil
985
- @hash = nil
979
+ # Reset dependent values
980
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
981
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
982
+ remove_instance_variable(:@authority) if defined?(@authority)
983
+ remove_instance_variable(:@normalized_password) if defined?(@normalized_password)
984
+ remove_composite_values
986
985
 
987
986
  # Ensure we haven't created an invalid URI
988
987
  validate()
@@ -996,13 +995,13 @@ module Addressable
996
995
  def userinfo
997
996
  current_user = self.user
998
997
  current_password = self.password
999
- (current_user || current_password) && @userinfo ||= (begin
998
+ (current_user || current_password) && @userinfo ||= begin
1000
999
  if current_user && current_password
1001
1000
  "#{current_user}:#{current_password}"
1002
1001
  elsif current_user && !current_password
1003
1002
  "#{current_user}"
1004
1003
  end
1005
- end)
1004
+ end
1006
1005
  end
1007
1006
 
1008
1007
  ##
@@ -1010,7 +1009,9 @@ module Addressable
1010
1009
  #
1011
1010
  # @return [String] The userinfo component, normalized.
1012
1011
  def normalized_userinfo
1013
- self.userinfo && @normalized_userinfo ||= (begin
1012
+ return nil unless self.userinfo
1013
+ return @normalized_userinfo if defined?(@normalized_userinfo)
1014
+ @normalized_userinfo ||= begin
1014
1015
  current_user = self.normalized_user
1015
1016
  current_password = self.normalized_password
1016
1017
  if !current_user && !current_password
@@ -1020,7 +1021,7 @@ module Addressable
1020
1021
  elsif current_user && !current_password
1021
1022
  "#{current_user}"
1022
1023
  end
1023
- end)
1024
+ end
1024
1025
  end
1025
1026
 
1026
1027
  ##
@@ -1044,10 +1045,9 @@ module Addressable
1044
1045
  self.password = new_password
1045
1046
  self.user = new_user
1046
1047
 
1047
- # Reset dependant values
1048
- @authority = nil
1049
- @uri_string = nil
1050
- @hash = nil
1048
+ # Reset dependent values
1049
+ remove_instance_variable(:@authority) if defined?(@authority)
1050
+ remove_composite_values
1051
1051
 
1052
1052
  # Ensure we haven't created an invalid URI
1053
1053
  validate()
@@ -1058,7 +1058,7 @@ module Addressable
1058
1058
  #
1059
1059
  # @return [String] The host component.
1060
1060
  def host
1061
- return instance_variable_defined?(:@host) ? @host : nil
1061
+ return defined?(@host) ? @host : nil
1062
1062
  end
1063
1063
 
1064
1064
  ##
@@ -1066,7 +1066,8 @@ module Addressable
1066
1066
  #
1067
1067
  # @return [String] The host component, normalized.
1068
1068
  def normalized_host
1069
- self.host && @normalized_host ||= (begin
1069
+ return nil unless self.host
1070
+ @normalized_host ||= begin
1070
1071
  if !self.host.strip.empty?
1071
1072
  result = ::Addressable::IDNA.to_ascii(
1072
1073
  URI.unencode_component(self.host.strip.downcase)
@@ -1075,11 +1076,14 @@ module Addressable
1075
1076
  # Single trailing dots are unnecessary.
1076
1077
  result = result[0...-1]
1077
1078
  end
1079
+ result = Addressable::URI.normalize_component(
1080
+ result,
1081
+ CharacterClasses::HOST)
1078
1082
  result
1079
1083
  else
1080
1084
  EMPTY_STR
1081
1085
  end
1082
- end)
1086
+ end
1083
1087
  end
1084
1088
 
1085
1089
  ##
@@ -1094,17 +1098,16 @@ module Addressable
1094
1098
 
1095
1099
  unreserved = CharacterClasses::UNRESERVED
1096
1100
  sub_delims = CharacterClasses::SUB_DELIMS
1097
- if @host != nil && (@host =~ /[<>{}\/\?\#\@]/ ||
1101
+ if !@host.nil? && (@host =~ /[<>{}\/\?\#\@"[[:space:]]]/ ||
1098
1102
  (@host[/^\[(.*)\]$/, 1] != nil && @host[/^\[(.*)\]$/, 1] !~
1099
1103
  Regexp.new("^[#{unreserved}#{sub_delims}:]*$")))
1100
1104
  raise InvalidURIError, "Invalid character in host: '#{@host.to_s}'"
1101
1105
  end
1102
1106
 
1103
- # Reset dependant values
1104
- @authority = nil
1105
- @normalized_host = nil
1106
- @uri_string = nil
1107
- @hash = nil
1107
+ # Reset dependent values
1108
+ remove_instance_variable(:@authority) if defined?(@authority)
1109
+ remove_instance_variable(:@normalized_host) if defined?(@normalized_host)
1110
+ remove_composite_values
1108
1111
 
1109
1112
  # Ensure we haven't created an invalid URI
1110
1113
  validate()
@@ -1130,7 +1133,10 @@ module Addressable
1130
1133
  #
1131
1134
  # @param [String, #to_str] new_hostname The new hostname for this URI.
1132
1135
  def hostname=(new_hostname)
1133
- if new_hostname && !new_hostname.respond_to?(:to_str)
1136
+ if new_hostname &&
1137
+ (new_hostname.respond_to?(:ipv4?) || new_hostname.respond_to?(:ipv6?))
1138
+ new_hostname = new_hostname.to_s
1139
+ elsif new_hostname && !new_hostname.respond_to?(:to_str)
1134
1140
  raise TypeError, "Can't convert #{new_hostname.class} into String."
1135
1141
  end
1136
1142
  v = new_hostname ? new_hostname.to_str : nil
@@ -1144,7 +1150,7 @@ module Addressable
1144
1150
  #
1145
1151
  # @return [String] The authority component.
1146
1152
  def authority
1147
- self.host && @authority ||= (begin
1153
+ self.host && @authority ||= begin
1148
1154
  authority = ""
1149
1155
  if self.userinfo != nil
1150
1156
  authority << "#{self.userinfo}@"
@@ -1154,7 +1160,7 @@ module Addressable
1154
1160
  authority << ":#{self.port}"
1155
1161
  end
1156
1162
  authority
1157
- end)
1163
+ end
1158
1164
  end
1159
1165
 
1160
1166
  ##
@@ -1162,7 +1168,8 @@ module Addressable
1162
1168
  #
1163
1169
  # @return [String] The authority component, normalized.
1164
1170
  def normalized_authority
1165
- self.authority && @normalized_authority ||= (begin
1171
+ return nil unless self.authority
1172
+ @normalized_authority ||= begin
1166
1173
  authority = ""
1167
1174
  if self.normalized_userinfo != nil
1168
1175
  authority << "#{self.normalized_userinfo}@"
@@ -1172,7 +1179,7 @@ module Addressable
1172
1179
  authority << ":#{self.normalized_port}"
1173
1180
  end
1174
1181
  authority
1175
- end)
1182
+ end
1176
1183
  end
1177
1184
 
1178
1185
  ##
@@ -1205,11 +1212,10 @@ module Addressable
1205
1212
  self.host = defined?(new_host) ? new_host : nil
1206
1213
  self.port = defined?(new_port) ? new_port : nil
1207
1214
 
1208
- # Reset dependant values
1209
- @userinfo = nil
1210
- @normalized_userinfo = nil
1211
- @uri_string = nil
1212
- @hash = nil
1215
+ # Reset dependent values
1216
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
1217
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1218
+ remove_composite_values
1213
1219
 
1214
1220
  # Ensure we haven't created an invalid URI
1215
1221
  validate()
@@ -1221,18 +1227,55 @@ module Addressable
1221
1227
  #
1222
1228
  # @return [String] The serialized origin.
1223
1229
  def origin
1224
- return (if self.scheme && self.authority
1230
+ if self.scheme && self.authority
1225
1231
  if self.normalized_port
1226
- (
1227
- "#{self.normalized_scheme}://#{self.normalized_host}" +
1228
- ":#{self.normalized_port}"
1229
- )
1232
+ "#{self.normalized_scheme}://#{self.normalized_host}" +
1233
+ ":#{self.normalized_port}"
1230
1234
  else
1231
1235
  "#{self.normalized_scheme}://#{self.normalized_host}"
1232
1236
  end
1233
1237
  else
1234
1238
  "null"
1235
- end)
1239
+ end
1240
+ end
1241
+
1242
+ ##
1243
+ # Sets the origin for this URI, serialized to ASCII, as per
1244
+ # RFC 6454, section 6.2. This assignment will reset the `userinfo`
1245
+ # component.
1246
+ #
1247
+ # @param [String, #to_str] new_origin The new origin component.
1248
+ def origin=(new_origin)
1249
+ if new_origin
1250
+ if !new_origin.respond_to?(:to_str)
1251
+ raise TypeError, "Can't convert #{new_origin.class} into String."
1252
+ end
1253
+ new_origin = new_origin.to_str
1254
+ new_scheme = new_origin[/^([^:\/?#]+):\/\//, 1]
1255
+ unless new_scheme
1256
+ raise InvalidURIError, 'An origin cannot omit the scheme.'
1257
+ end
1258
+ new_host = new_origin[/:\/\/([^\/?#:]+)/, 1]
1259
+ unless new_host
1260
+ raise InvalidURIError, 'An origin cannot omit the host.'
1261
+ end
1262
+ new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1]
1263
+ end
1264
+
1265
+ self.scheme = defined?(new_scheme) ? new_scheme : nil
1266
+ self.host = defined?(new_host) ? new_host : nil
1267
+ self.port = defined?(new_port) ? new_port : nil
1268
+ self.userinfo = nil
1269
+
1270
+ # Reset dependent values
1271
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
1272
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1273
+ remove_instance_variable(:@authority) if defined?(@authority)
1274
+ remove_instance_variable(:@normalized_authority) if defined?(@normalized_authority)
1275
+ remove_composite_values
1276
+
1277
+ # Ensure we haven't created an invalid URI
1278
+ validate()
1236
1279
  end
1237
1280
 
1238
1281
  # Returns an array of known ip-based schemes. These schemes typically
@@ -1256,7 +1299,7 @@ module Addressable
1256
1299
  #
1257
1300
  # @return [Integer] The port component.
1258
1301
  def port
1259
- return instance_variable_defined?(:@port) ? @port : nil
1302
+ return defined?(@port) ? @port : nil
1260
1303
  end
1261
1304
 
1262
1305
  ##
@@ -1264,10 +1307,14 @@ module Addressable
1264
1307
  #
1265
1308
  # @return [Integer] The port component, normalized.
1266
1309
  def normalized_port
1267
- if URI.port_mapping[self.normalized_scheme] == self.port
1268
- nil
1269
- else
1270
- self.port
1310
+ return nil unless self.port
1311
+ return @normalized_port if defined?(@normalized_port)
1312
+ @normalized_port ||= begin
1313
+ if URI.port_mapping[self.normalized_scheme] == self.port
1314
+ nil
1315
+ else
1316
+ self.port
1317
+ end
1271
1318
  end
1272
1319
  end
1273
1320
 
@@ -1279,6 +1326,11 @@ module Addressable
1279
1326
  if new_port != nil && new_port.respond_to?(:to_str)
1280
1327
  new_port = Addressable::URI.unencode_component(new_port.to_str)
1281
1328
  end
1329
+
1330
+ if new_port.respond_to?(:valid_encoding?) && !new_port.valid_encoding?
1331
+ raise InvalidURIError, "Invalid encoding in port"
1332
+ end
1333
+
1282
1334
  if new_port != nil && !(new_port.to_s =~ /^\d+$/)
1283
1335
  raise InvalidURIError,
1284
1336
  "Invalid port number: #{new_port.inspect}"
@@ -1287,11 +1339,10 @@ module Addressable
1287
1339
  @port = new_port.to_s.to_i
1288
1340
  @port = nil if @port == 0
1289
1341
 
1290
- # Reset dependant values
1291
- @authority = nil
1292
- @normalized_port = nil
1293
- @uri_string = nil
1294
- @hash = nil
1342
+ # Reset dependent values
1343
+ remove_instance_variable(:@authority) if defined?(@authority)
1344
+ remove_instance_variable(:@normalized_port) if defined?(@normalized_port)
1345
+ remove_composite_values
1295
1346
 
1296
1347
  # Ensure we haven't created an invalid URI
1297
1348
  validate()
@@ -1331,12 +1382,12 @@ module Addressable
1331
1382
  #
1332
1383
  # @return [String] The components that identify a site.
1333
1384
  def site
1334
- (self.scheme || self.authority) && @site ||= (begin
1385
+ (self.scheme || self.authority) && @site ||= begin
1335
1386
  site_string = ""
1336
1387
  site_string << "#{self.scheme}:" if self.scheme != nil
1337
1388
  site_string << "//#{self.authority}" if self.authority != nil
1338
1389
  site_string
1339
- end)
1390
+ end
1340
1391
  end
1341
1392
 
1342
1393
  ##
@@ -1349,7 +1400,8 @@ module Addressable
1349
1400
  #
1350
1401
  # @return [String] The normalized components that identify a site.
1351
1402
  def normalized_site
1352
- self.site && @normalized_site ||= (begin
1403
+ return nil unless self.site
1404
+ @normalized_site ||= begin
1353
1405
  site_string = ""
1354
1406
  if self.normalized_scheme != nil
1355
1407
  site_string << "#{self.normalized_scheme}:"
@@ -1358,7 +1410,7 @@ module Addressable
1358
1410
  site_string << "//#{self.normalized_authority}"
1359
1411
  end
1360
1412
  site_string
1361
- end)
1413
+ end
1362
1414
  end
1363
1415
 
1364
1416
  ##
@@ -1388,7 +1440,7 @@ module Addressable
1388
1440
  #
1389
1441
  # @return [String] The path component.
1390
1442
  def path
1391
- return instance_variable_defined?(:@path) ? @path : EMPTY_STR
1443
+ return defined?(@path) ? @path : EMPTY_STR
1392
1444
  end
1393
1445
 
1394
1446
  NORMPATH = /^(?!\/)[^\/:]*:.*$/
@@ -1397,7 +1449,7 @@ module Addressable
1397
1449
  #
1398
1450
  # @return [String] The path component, normalized.
1399
1451
  def normalized_path
1400
- @normalized_path ||= (begin
1452
+ @normalized_path ||= begin
1401
1453
  path = self.path.to_s
1402
1454
  if self.scheme == nil && path =~ NORMPATH
1403
1455
  # Relative paths with colons in the first segment are ambiguous.
@@ -1405,12 +1457,12 @@ module Addressable
1405
1457
  end
1406
1458
  # String#split(delimeter, -1) uses the more strict splitting behavior
1407
1459
  # found by default in Python.
1408
- result = (path.strip.split(SLASH, -1).map do |segment|
1460
+ result = path.strip.split(SLASH, -1).map do |segment|
1409
1461
  Addressable::URI.normalize_component(
1410
1462
  segment,
1411
1463
  Addressable::URI::CharacterClasses::PCHAR
1412
1464
  )
1413
- end).join(SLASH)
1465
+ end.join(SLASH)
1414
1466
 
1415
1467
  result = URI.normalize_path(result)
1416
1468
  if result.empty? &&
@@ -1418,7 +1470,7 @@ module Addressable
1418
1470
  result = SLASH
1419
1471
  end
1420
1472
  result
1421
- end)
1473
+ end
1422
1474
  end
1423
1475
 
1424
1476
  ##
@@ -1434,10 +1486,9 @@ module Addressable
1434
1486
  @path = "/#{@path}"
1435
1487
  end
1436
1488
 
1437
- # Reset dependant values
1438
- @normalized_path = nil
1439
- @uri_string = nil
1440
- @hash = nil
1489
+ # Reset dependent values
1490
+ remove_instance_variable(:@normalized_path) if defined?(@normalized_path)
1491
+ remove_composite_values
1441
1492
  end
1442
1493
 
1443
1494
  ##
@@ -1464,7 +1515,7 @@ module Addressable
1464
1515
  #
1465
1516
  # @return [String] The query component.
1466
1517
  def query
1467
- return instance_variable_defined?(:@query) ? @query : nil
1518
+ return defined?(@query) ? @query : nil
1468
1519
  end
1469
1520
 
1470
1521
  ##
@@ -1472,15 +1523,19 @@ module Addressable
1472
1523
  #
1473
1524
  # @return [String] The query component, normalized.
1474
1525
  def normalized_query(*flags)
1475
- modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
1476
- # Make sure possible key-value pair delimiters are escaped.
1477
- modified_query_class.sub!("\\&", "").sub!("\\;", "")
1478
- pairs = (self.query || "").split("&", -1)
1479
- pairs.sort! if flags.include?(:sorted)
1480
- component = (pairs.map do |pair|
1481
- Addressable::URI.normalize_component(pair, modified_query_class, "+")
1482
- end).join("&")
1483
- component == "" ? nil : component
1526
+ return nil unless self.query
1527
+ return @normalized_query if defined?(@normalized_query)
1528
+ @normalized_query ||= begin
1529
+ modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
1530
+ # Make sure possible key-value pair delimiters are escaped.
1531
+ modified_query_class.sub!("\\&", "").sub!("\\;", "")
1532
+ pairs = (self.query || "").split("&", -1)
1533
+ pairs.sort! if flags.include?(:sorted)
1534
+ component = pairs.map do |pair|
1535
+ Addressable::URI.normalize_component(pair, modified_query_class, "+")
1536
+ end.join("&")
1537
+ component == "" ? nil : component
1538
+ end
1484
1539
  end
1485
1540
 
1486
1541
  ##
@@ -1493,10 +1548,9 @@ module Addressable
1493
1548
  end
1494
1549
  @query = new_query ? new_query.to_str : nil
1495
1550
 
1496
- # Reset dependant values
1497
- @normalized_query = nil
1498
- @uri_string = nil
1499
- @hash = nil
1551
+ # Reset dependent values
1552
+ remove_instance_variable(:@normalized_query) if defined?(@normalized_query)
1553
+ remove_composite_values
1500
1554
  end
1501
1555
 
1502
1556
  ##
@@ -1525,9 +1579,9 @@ module Addressable
1525
1579
  raise ArgumentError, "Invalid return type. Must be Hash or Array."
1526
1580
  end
1527
1581
  return nil if self.query == nil
1528
- split_query = (self.query.split("&").map do |pair|
1582
+ split_query = self.query.split("&").map do |pair|
1529
1583
  pair.split("=", 2) if pair && !pair.empty?
1530
- end).compact
1584
+ end.compact
1531
1585
  return split_query.inject(empty_accumulator.dup) do |accu, pair|
1532
1586
  # I'd rather use key/value identifiers instead of array lookups,
1533
1587
  # but in this case I really want to maintain the exact pair structure,
@@ -1647,9 +1701,8 @@ module Addressable
1647
1701
  self.path = path_component
1648
1702
  self.query = query_component
1649
1703
 
1650
- # Reset dependant values
1651
- @uri_string = nil
1652
- @hash = nil
1704
+ # Reset dependent values
1705
+ remove_composite_values
1653
1706
  end
1654
1707
 
1655
1708
  ##
@@ -1657,7 +1710,7 @@ module Addressable
1657
1710
  #
1658
1711
  # @return [String] The fragment component.
1659
1712
  def fragment
1660
- return instance_variable_defined?(:@fragment) ? @fragment : nil
1713
+ return defined?(@fragment) ? @fragment : nil
1661
1714
  end
1662
1715
 
1663
1716
  ##
@@ -1665,13 +1718,15 @@ module Addressable
1665
1718
  #
1666
1719
  # @return [String] The fragment component, normalized.
1667
1720
  def normalized_fragment
1668
- self.fragment && @normalized_fragment ||= (begin
1721
+ return nil unless self.fragment
1722
+ return @normalized_fragment if defined?(@normalized_fragment)
1723
+ @normalized_fragment ||= begin
1669
1724
  component = Addressable::URI.normalize_component(
1670
1725
  self.fragment,
1671
1726
  Addressable::URI::CharacterClasses::FRAGMENT
1672
1727
  )
1673
1728
  component == "" ? nil : component
1674
- end)
1729
+ end
1675
1730
  end
1676
1731
 
1677
1732
  ##
@@ -1684,10 +1739,9 @@ module Addressable
1684
1739
  end
1685
1740
  @fragment = new_fragment ? new_fragment.to_str : nil
1686
1741
 
1687
- # Reset dependant values
1688
- @normalized_fragment = nil
1689
- @uri_string = nil
1690
- @hash = nil
1742
+ # Reset dependent values
1743
+ remove_instance_variable(:@normalized_fragment) if defined?(@normalized_fragment)
1744
+ remove_composite_values
1691
1745
 
1692
1746
  # Ensure we haven't created an invalid URI
1693
1747
  validate()
@@ -2108,7 +2162,7 @@ module Addressable
2108
2162
  #
2109
2163
  # @return [Integer] A hash of the URI.
2110
2164
  def hash
2111
- return @hash ||= (self.to_s.hash * -1)
2165
+ @hash ||= self.to_s.hash * -1
2112
2166
  end
2113
2167
 
2114
2168
  ##
@@ -2191,7 +2245,7 @@ module Addressable
2191
2245
  raise InvalidURIError,
2192
2246
  "Cannot assemble URI string with ambiguous path: '#{self.path}'"
2193
2247
  end
2194
- @uri_string ||= (begin
2248
+ @uri_string ||= begin
2195
2249
  uri_string = ""
2196
2250
  uri_string << "#{self.scheme}:" if self.scheme != nil
2197
2251
  uri_string << "//#{self.authority}" if self.authority != nil
@@ -2202,7 +2256,7 @@ module Addressable
2202
2256
  uri_string.force_encoding(Encoding::UTF_8)
2203
2257
  end
2204
2258
  uri_string
2205
- end)
2259
+ end
2206
2260
  end
2207
2261
 
2208
2262
  ##
@@ -2251,7 +2305,7 @@ module Addressable
2251
2305
  return nil
2252
2306
  end
2253
2307
 
2254
- private
2308
+ protected
2255
2309
  SELF_REF = '.'
2256
2310
  PARENT = '..'
2257
2311
 
@@ -2328,9 +2382,9 @@ module Addressable
2328
2382
  #
2329
2383
  # @return [Addressable::URI] <code>self</code>.
2330
2384
  def replace_self(uri)
2331
- # Reset dependant values
2385
+ # Reset dependent values
2332
2386
  instance_variables.each do |var|
2333
- instance_variable_set(var, nil)
2387
+ remove_instance_variable(var) if instance_variable_defined?(var)
2334
2388
  end
2335
2389
 
2336
2390
  @scheme = uri.scheme
@@ -2345,7 +2399,7 @@ module Addressable
2345
2399
  end
2346
2400
 
2347
2401
  ##
2348
- # Splits path string with "/"(slash).
2402
+ # Splits path string with "/" (slash).
2349
2403
  # It is considered that there is empty string after last slash when
2350
2404
  # path ends with slash.
2351
2405
  #
@@ -2357,5 +2411,14 @@ module Addressable
2357
2411
  splitted << EMPTY_STR if path.end_with? SLASH
2358
2412
  splitted
2359
2413
  end
2414
+
2415
+ ##
2416
+ # Resets composite values for the entire URI
2417
+ #
2418
+ # @api private
2419
+ def remove_composite_values
2420
+ remove_instance_variable(:@uri_string) if defined?(@uri_string)
2421
+ remove_instance_variable(:@hash) if defined?(@hash)
2422
+ end
2360
2423
  end
2361
2424
  end