Class Addressable::URI
In: lib/addressable/uri.rb
Parent: Object

This is an implementation of a URI parser based on <a href="RFC">www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>, <a href="RFC">www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>.

Methods

Classes and Modules

Module Addressable::URI::CharacterClasses
Class Addressable::URI::InvalidOptionError
Class Addressable::URI::InvalidURIError

External Aliases

encode_component -> encode_component
unencode -> unescape
unencode -> unencode_component
unencode -> unescape_component
encode -> escape

Public Class methods

Converts a path to a file scheme URI. If the path supplied is relative, it will be returned as a relative URI. If the path supplied is actually a non-file URI, it will parse the URI as if it had been parsed with Addressable::URI.parse. Handles all of the various Microsoft-specific formats for specifying paths.

@param [String, Addressable::URI, to_str] path

  Typically a <tt>String</tt> path to a file or directory, but
  will return a sensible return value if an absolute URI is supplied
  instead.

@return [Addressable::URI]

  The parsed file scheme URI or the original URI if some other URI
  scheme was provided.

@example

  base = Addressable::URI.convert_path("/absolute/path/")
  uri = Addressable::URI.convert_path("relative/path")
  (base + uri).to_s
  #=> "file:///absolute/path/relative/path"

  Addressable::URI.convert_path(
    "c:\\windows\\My Documents 100%20\\foo.txt"
  ).to_s
  #=> "file:///c:/windows/My%20Documents%20100%20/foo.txt"

  Addressable::URI.convert_path("http://example.com/").to_s
  #=> "http://example.com/"

[Source]

     # File lib/addressable/uri.rb, line 215
215:     def self.convert_path(path)
216:       # If we were given nil, return nil.
217:       return nil unless path
218:       # If a URI object is passed, just return itself.
219:       return path if path.kind_of?(self)
220:       if !path.respond_to?(:to_str)
221:         raise TypeError, "Can't convert #{path.class} into String."
222:       end
223:       # Otherwise, convert to a String
224:       path = path.to_str.strip
225: 
226:       path.gsub!(/^file:\/?\/?/, "") if path =~ /^file:\/?\/?/
227:       path = "/" + path if path =~ /^([a-zA-Z])(\||:)/
228:       uri = self.parse(path)
229: 
230:       if uri.scheme == nil
231:         # Adjust windows-style uris
232:         uri.path.gsub!(/^\/?([a-zA-Z])\|(\\|\/)/, "/\\1:/")
233:         uri.path.gsub!(/\\/, "/")
234:         if File.exists?(uri.path) &&
235:             File.stat(uri.path).directory?
236:           uri.path.gsub!(/\/$/, "")
237:           uri.path = uri.path + '/'
238:         end
239: 
240:         # If the path is absolute, set the scheme and host.
241:         if uri.path =~ /^\//
242:           uri.scheme = "file"
243:           uri.host = ""
244:         end
245:         uri.normalize!
246:       end
247: 
248:       return uri
249:     end

Percent encodes any special characters in the URI.

@param [String, Addressable::URI, to_str] uri

  The URI to encode.

@param [Class] returning

  The type of object to return.  This value may only be set to
  <tt>String</tt> or <tt>Addressable::URI</tt>.  All other values
  are invalid.  Defaults to <tt>String</tt>.

@return [String, Addressable::URI]

  The encoded URI.  The return type is determined by
  the <tt>returning</tt> parameter.

[Source]

     # File lib/addressable/uri.rb, line 394
394:     def self.encode(uri, returning=String)
395:       return nil if uri.nil?
396:       if !uri.respond_to?(:to_str)
397:         raise TypeError, "Can't convert #{uri.class} into String."
398:       end
399:       if ![String, ::Addressable::URI].include?(returning)
400:         raise TypeError,
401:           "Expected Class (String or Addressable::URI), " +
402:           "got #{returning.inspect}"
403:       end
404:       uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
405:       encoded_uri = Addressable::URI.new(
406:         :scheme => self.encode_component(uri_object.scheme,
407:           Addressable::URI::CharacterClasses::SCHEME),
408:         :authority => self.encode_component(uri_object.authority,
409:           Addressable::URI::CharacterClasses::AUTHORITY),
410:         :path => self.encode_component(uri_object.path,
411:           Addressable::URI::CharacterClasses::PATH),
412:         :query => self.encode_component(uri_object.query,
413:           Addressable::URI::CharacterClasses::QUERY),
414:         :fragment => self.encode_component(uri_object.fragment,
415:           Addressable::URI::CharacterClasses::FRAGMENT)
416:       )
417:       if returning == String
418:         return encoded_uri.to_s
419:       elsif returning == ::Addressable::URI
420:         return encoded_uri
421:       end
422:     end

Percent encodes a URI component.

@param [String, to_str] component The URI component to encode.

@param [String, Regexp] character_class

  The characters which are not percent encoded.  If a <tt>String</tt>
  is passed, the <tt>String</tt> must be formatted as a regular
  expression character class.  (Do not include the surrounding square
  brackets.)  For example, <tt>"b-zB-Z0-9"</tt> would cause everything
  but the letters 'b' through 'z' and the numbers '0' through '9' to be
  percent encoded.  If a <tt>Regexp</tt> is passed, the value
  <tt>/[^b-zB-Z0-9]/</tt> would have the same effect.
  A set of useful <tt>String</tt> values may be found in the
  <tt>Addressable::URI::CharacterClasses</tt> module.  The default value
  is the reserved plus unreserved character classes specified in
  <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.

@return [String] The encoded component.

@example

  Addressable::URI.encode_component("simple/example", "b-zB-Z0-9")
  => "simple%2Fex%61mple"
  Addressable::URI.encode_component("simple/example", /[^b-zB-Z0-9]/)
  => "simple%2Fex%61mple"
  Addressable::URI.encode_component(
    "simple/example", Addressable::URI::CharacterClasses::UNRESERVED
  )
  => "simple%2Fexample"

[Source]

     # File lib/addressable/uri.rb, line 307
307:     def self.encode_component(component, character_class=
308:         CharacterClasses::RESERVED + CharacterClasses::UNRESERVED)
309:       return nil if component.nil?
310:       if !component.respond_to?(:to_str)
311:         raise TypeError, "Can't convert #{component.class} into String."
312:       end
313:       component = component.to_str
314:       if ![String, Regexp].include?(character_class.class)
315:         raise TypeError,
316:           "Expected String or Regexp, got #{character_class.inspect}"
317:       end
318:       if character_class.kind_of?(String)
319:         character_class = /[^#{character_class}]/
320:       end
321:       if component.respond_to?(:force_encoding)
322:         # We can't perform regexps on invalid UTF sequences, but
323:         # here we need to, so switch to ASCII.
324:         component = component.dup
325:         component.force_encoding(Encoding::ASCII_8BIT)
326:       end
327:       return component.gsub(character_class) do |sequence|
328:         (sequence.unpack('C*').map { |c| "%" + ("%02x" % c).upcase }).join("")
329:       end
330:     end

Converts an input to a URI. The input does not have to be a valid URI — the method will use heuristics to guess what URI was intended. This is not standards-compliant, merely user-friendly.

@param [String, Addressable::URI, to_str] uri

  The URI string to parse.  No parsing is performed if the object is
  already an <tt>Addressable::URI</tt>.

@param [Hash] hints

  A <tt>Hash</tt> of hints to the heuristic parser.  Defaults to
  <tt>{:scheme => "http"}</tt>.

@return [Addressable::URI] The parsed URI.

[Source]

     # File lib/addressable/uri.rb, line 146
146:     def self.heuristic_parse(uri, hints={})
147:       # If we were given nil, return nil.
148:       return nil unless uri
149:       # If a URI object is passed, just return itself.
150:       return uri if uri.kind_of?(self)
151:       if !uri.respond_to?(:to_str)
152:         raise TypeError, "Can't convert #{uri.class} into String."
153:       end
154:       # Otherwise, convert to a String
155:       uri = uri.to_str.dup
156:       hints = {
157:         :scheme => "http"
158:       }.merge(hints)
159:       case uri
160:       when /^http:\/+/
161:         uri.gsub!(/^http:\/+/, "http://")
162:       when /^feed:\/+http:\/+/
163:         uri.gsub!(/^feed:\/+http:\/+/, "feed:http://")
164:       when /^feed:\/+/
165:         uri.gsub!(/^feed:\/+/, "feed://")
166:       when /^file:\/+/
167:         uri.gsub!(/^file:\/+/, "file:///")
168:       end
169:       parsed = self.parse(uri)
170:       if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/
171:         parsed = self.parse(hints[:scheme] + "://" + uri)
172:       end
173:       if parsed.path.include?(".")
174:         new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
175:         if new_host
176:           new_path = parsed.path.gsub(
177:             Regexp.new("^" + Regexp.escape(new_host)), "")
178:           parsed.host = new_host
179:           parsed.path = new_path
180:           parsed.scheme = hints[:scheme] unless parsed.scheme
181:         end
182:       end
183:       return parsed
184:     end

Returns an array of known ip-based schemes. These schemes typically use a similar URI form: //<user>:<password>@<host>:<port>/<url-path>

[Source]

     # File lib/addressable/uri.rb, line 915
915:     def self.ip_based_schemes
916:       return self.port_mapping.keys
917:     end

Joins several URIs together.

@param [String, Addressable::URI, to_str] *uris

  The URIs to join.

@return [Addressable::URI] The joined URI.

@example

  base = "http://example.com/"
  uri = Addressable::URI.parse("relative/path")
  Addressable::URI.join(base, uri)
  #=> #<Addressable::URI:0xcab390 URI:http://example.com/relative/path>

[Source]

     # File lib/addressable/uri.rb, line 264
264:     def self.join(*uris)
265:       uri_objects = uris.collect do |uri|
266:         if !uri.respond_to?(:to_str)
267:           raise TypeError, "Can't convert #{uri.class} into String."
268:         end
269:         uri.kind_of?(self) ? uri : self.parse(uri.to_str)
270:       end
271:       result = uri_objects.shift.dup
272:       for uri in uri_objects
273:         result.join!(uri)
274:       end
275:       return result
276:     end

Creates a new uri object from component parts.

@option [String, to_str] scheme The scheme component. @option [String, to_str] user The user component. @option [String, to_str] password The password component. @option [String, to_str] userinfo

  The userinfo component.  If this is supplied, the user and password
  components must be omitted.

@option [String, to_str] host The host component. @option [String, to_str] port The port component. @option [String, to_str] authority

  The authority component.  If this is supplied, the user, password,
  userinfo, host, and port components must be omitted.

@option [String, to_str] path The path component. @option [String, to_str] query The query component. @option [String, to_str] fragment The fragment component.

@return [Addressable::URI] The constructed URI object.

[Source]

     # File lib/addressable/uri.rb, line 516
516:     def initialize(options={})
517:       if options.has_key?(:authority)
518:         if (options.keys & [:userinfo, :user, :password, :host, :port]).any?
519:           raise ArgumentError,
520:             "Cannot specify both an authority and any of the components " +
521:             "within the authority."
522:         end
523:       end
524:       if options.has_key?(:userinfo)
525:         if (options.keys & [:user, :password]).any?
526:           raise ArgumentError,
527:             "Cannot specify both a userinfo and either the user or password."
528:         end
529:       end
530: 
531:       self.validation_deferred = true
532:       self.scheme = options[:scheme] if options[:scheme]
533:       self.user = options[:user] if options[:user]
534:       self.password = options[:password] if options[:password]
535:       self.userinfo = options[:userinfo] if options[:userinfo]
536:       self.host = options[:host] if options[:host]
537:       self.port = options[:port] if options[:port]
538:       self.authority = options[:authority] if options[:authority]
539:       self.path = options[:path] if options[:path]
540:       self.query = options[:query] if options[:query]
541:       self.fragment = options[:fragment] if options[:fragment]
542:       self.validation_deferred = false
543:     end

Normalizes the encoding of a URI. Characters within a hostname are not percent encoded to allow for internationalized domain names.

@param [String, Addressable::URI, to_str] uri

  The URI to encode.

@param [Class] returning

  The type of object to return.  This value may only be set to
  <tt>String</tt> or <tt>Addressable::URI</tt>.  All other values
  are invalid.  Defaults to <tt>String</tt>.

@return [String, Addressable::URI]

  The encoded URI.  The return type is determined by
  the <tt>returning</tt> parameter.

[Source]

     # File lib/addressable/uri.rb, line 443
443:     def self.normalized_encode(uri, returning=String)
444:       if !uri.respond_to?(:to_str)
445:         raise TypeError, "Can't convert #{uri.class} into String."
446:       end
447:       if ![String, ::Addressable::URI].include?(returning)
448:         raise TypeError,
449:           "Expected Class (String or Addressable::URI), " +
450:           "got #{returning.inspect}"
451:       end
452:       uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
453:       components = {
454:         :scheme => self.unencode_component(uri_object.scheme),
455:         :user => self.unencode_component(uri_object.user),
456:         :password => self.unencode_component(uri_object.password),
457:         :host => self.unencode_component(uri_object.host),
458:         :port => uri_object.port,
459:         :path => self.unencode_component(uri_object.path),
460:         :query => self.unencode_component(uri_object.query),
461:         :fragment => self.unencode_component(uri_object.fragment)
462:       }
463:       components.each do |key, value|
464:         if value != nil
465:           begin
466:             components[key] =
467:               Addressable::IDNA.unicode_normalize_kc(value.to_str)
468:           rescue ArgumentError
469:             # Likely a malformed UTF-8 character, skip unicode normalization
470:             components[key] = value.to_str
471:           end
472:         end
473:       end
474:       encoded_uri = Addressable::URI.new(
475:         :scheme => self.encode_component(components[:scheme],
476:           Addressable::URI::CharacterClasses::SCHEME),
477:         :user => self.encode_component(components[:user],
478:           Addressable::URI::CharacterClasses::UNRESERVED),
479:         :password => self.encode_component(components[:password],
480:           Addressable::URI::CharacterClasses::UNRESERVED),
481:         :host => components[:host],
482:         :port => components[:port],
483:         :path => self.encode_component(components[:path],
484:           Addressable::URI::CharacterClasses::PATH),
485:         :query => self.encode_component(components[:query],
486:           Addressable::URI::CharacterClasses::QUERY),
487:         :fragment => self.encode_component(components[:fragment],
488:           Addressable::URI::CharacterClasses::FRAGMENT)
489:       )
490:       if returning == String
491:         return encoded_uri.to_s
492:       elsif returning == ::Addressable::URI
493:         return encoded_uri
494:       end
495:     end

Returns a URI object based on the parsed string.

@param [String, Addressable::URI, to_str] uri

  The URI string to parse.  No parsing is performed if the object is
  already an <tt>Addressable::URI</tt>.

@return [Addressable::URI] The parsed URI.

[Source]

     # File lib/addressable/uri.rb, line 73
 73:     def self.parse(uri)
 74:       # If we were given nil, return nil.
 75:       return nil unless uri
 76:       # If a URI object is passed, just return itself.
 77:       return uri if uri.kind_of?(self)
 78: 
 79:       # If a URI object of the Ruby standard library variety is passed,
 80:       # convert it to a string, then parse the string.
 81:       # We do the check this way because we don't want to accidentally
 82:       # cause a missing constant exception to be thrown.
 83:       if uri.class.name =~ /^URI\b/
 84:         uri = uri.to_s
 85:       end
 86: 
 87:       if !uri.respond_to?(:to_str)
 88:         raise TypeError, "Can't convert #{uri.class} into String."
 89:       end
 90:       # Otherwise, convert to a String
 91:       uri = uri.to_str
 92: 
 93:       # This Regexp supplied as an example in RFC 3986, and it works great.
 94:       uri_regex =
 95:         /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/
 96:       scan = uri.scan(uri_regex)
 97:       fragments = scan[0]
 98:       scheme = fragments[1]
 99:       authority = fragments[3]
100:       path = fragments[4]
101:       query = fragments[6]
102:       fragment = fragments[8]
103:       user = nil
104:       password = nil
105:       host = nil
106:       port = nil
107:       if authority != nil
108:         # The Regexp above doesn't split apart the authority.
109:         userinfo = authority[/^([^\[\]]*)@/, 1]
110:         if userinfo != nil
111:           user = userinfo.strip[/^([^:]*):?/, 1]
112:           password = userinfo.strip[/:(.*)$/, 1]
113:         end
114:         host = authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
115:         port = authority[/:([^:@\[\]]*?)$/, 1]
116:       end
117:       if port == ""
118:         port = nil
119:       end
120: 
121:       return Addressable::URI.new(
122:         :scheme => scheme,
123:         :user => user,
124:         :password => password,
125:         :host => host,
126:         :port => port,
127:         :path => path,
128:         :query => query,
129:         :fragment => fragment
130:       )
131:     end

Returns a hash of common IP-based schemes and their default port numbers. Adding new schemes to this hash, as necessary, will allow for better URI normalization.

[Source]

     # File lib/addressable/uri.rb, line 922
922:     def self.port_mapping
923:       @port_mapping ||= {
924:         "http" => 80,
925:         "https" => 443,
926:         "ftp" => 21,
927:         "tftp" => 69,
928:         "sftp" => 22,
929:         "ssh" => 22,
930:         "svn+ssh" => 22,
931:         "telnet" => 23,
932:         "nntp" => 119,
933:         "gopher" => 70,
934:         "wais" => 210,
935:         "ldap" => 389,
936:         "prospero" => 1525
937:       }
938:     end

Unencodes any percent encoded characters within a URI component. This method may be used for unencoding either components or full URIs, however, it is recommended to use the unencode_component alias when unencoding components.

@param [String, Addressable::URI, to_str] uri

  The URI or component to unencode.

@param [Class] returning

  The type of object to return.  This value may only be set to
  <tt>String</tt> or <tt>Addressable::URI</tt>.  All other values
  are invalid.  Defaults to <tt>String</tt>.

@return [String, Addressable::URI]

  The unencoded component or URI.  The return type is determined by
  the <tt>returning</tt> parameter.

[Source]

     # File lib/addressable/uri.rb, line 353
353:     def self.unencode(uri, returning=String)
354:       return nil if uri.nil?
355:       if !uri.respond_to?(:to_str)
356:         raise TypeError, "Can't convert #{uri.class} into String."
357:       end
358:       if ![String, ::Addressable::URI].include?(returning)
359:         raise TypeError,
360:           "Expected Class (String or Addressable::URI), " +
361:           "got #{returning.inspect}"
362:       end
363:       result = uri.to_str.gsub(/%[0-9a-f]{2}/i) do |sequence|
364:         sequence[1..3].to_i(16).chr
365:       end
366:       result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
367:       if returning == String
368:         return result
369:       elsif returning == ::Addressable::URI
370:         return ::Addressable::URI.parse(result)
371:       end
372:     end

Public Instance methods

+(uri)

Alias for join

Returns true if the URI objects are equal. This method normalizes both URIs before doing the comparison.

@param [Object] uri The URI to compare.

@return [TrueClass, FalseClass]

  <tt>true</tt> if the URIs are equivalent, <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1696
1696:     def ==(uri)
1697:       return false unless uri.kind_of?(self.class)
1698:       return self.normalize.to_s == uri.normalize.to_s
1699:     end

Returns true if the URI objects are equal. This method normalizes both URIs before doing the comparison, and allows comparison against Strings.

@param [Object] uri The URI to compare.

@return [TrueClass, FalseClass]

  <tt>true</tt> if the URIs are equivalent, <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1675
1675:     def ===(uri)
1676:       if uri.respond_to?(:normalize)
1677:         uri_string = uri.normalize.to_s
1678:       else
1679:         begin
1680:           uri_string = ::Addressable::URI.parse(uri).normalize.to_s
1681:         rescue InvalidURIError, TypeError
1682:           return false
1683:         end
1684:       end
1685:       return self.normalize.to_s == uri_string
1686:     end

Determines if the URI is absolute.

@return [TrueClass, FalseClass]

  <tt>true</tt> if the URI is absolute.
  <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1347
1347:     def absolute?
1348:       return !relative?
1349:     end

The authority component for this URI. Combines the user, password, host, and port components.

@return [String] The authority component.

[Source]

     # File lib/addressable/uri.rb, line 835
835:     def authority
836:       @authority ||= (begin
837:         if self.host.nil?
838:           nil
839:         else
840:           authority = ""
841:           if self.userinfo != nil
842:             authority << "#{self.userinfo}@"
843:           end
844:           authority << self.host
845:           if self.port != nil
846:             authority << ":#{self.port}"
847:           end
848:           authority
849:         end
850:       end)
851:     end

Sets the authority component for this URI.

@param [String, to_str] new_authority The new authority component.

[Source]

     # File lib/addressable/uri.rb, line 879
879:     def authority=(new_authority)
880:       # Check for frozenness
881:       raise TypeError, "Can't modify frozen URI." if self.frozen?
882: 
883:       if new_authority
884:         new_authority = new_authority.to_str
885:         new_userinfo = new_authority[/^([^\[\]]*)@/, 1]
886:         if new_userinfo
887:           new_user = new_userinfo.strip[/^([^:]*):?/, 1]
888:           new_password = new_userinfo.strip[/:(.*)$/, 1]
889:         end
890:         new_host =
891:           new_authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
892:         new_port =
893:           new_authority[/:([^:@\[\]]*?)$/, 1]
894:       end
895: 
896:       # Password assigned first to ensure validity in case of nil
897:       self.password = new_password
898:       self.user = new_user
899:       self.host = new_host
900:       self.port = new_port
901: 
902:       # Reset dependant values
903:       @inferred_port = nil
904:       @userinfo = nil
905:       @normalized_userinfo = nil
906:       @uri_string = nil
907: 
908:       # Ensure we haven't created an invalid URI
909:       validate()
910:     end

The basename, if any, of the file in the path component.

@return [String] The path‘s basename.

[Source]

      # File lib/addressable/uri.rb, line 1071
1071:     def basename
1072:       # Path cannot be nil
1073:       return File.basename(self.path).gsub(/;[^\/]*$/, "")
1074:     end

Creates a URI suitable for display to users. If semantic attacks are likely, the application should try to detect these and warn the user. See <a href="RFC">www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>, section 7.6 for more information.

@return [Addressable::URI] A URI suitable for display purposes.

[Source]

      # File lib/addressable/uri.rb, line 1660
1660:     def display_uri
1661:       display_uri = self.normalize
1662:       display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host)
1663:       return display_uri
1664:     end

Clones the URI object.

@return [Addressable::URI] The cloned URI.

[Source]

      # File lib/addressable/uri.rb, line 1727
1727:     def dup
1728:       duplicated_uri = Addressable::URI.new(
1729:         :scheme => self.scheme ? self.scheme.dup : nil,
1730:         :user => self.user ? self.user.dup : nil,
1731:         :password => self.password ? self.password.dup : nil,
1732:         :host => self.host ? self.host.dup : nil,
1733:         :port => self.port,
1734:         :path => self.path ? self.path.dup : nil,
1735:         :query => self.query ? self.query.dup : nil,
1736:         :fragment => self.fragment ? self.fragment.dup : nil
1737:       )
1738:       return duplicated_uri
1739:     end

Returns true if the URI objects are equal. This method does NOT normalize either URI before doing the comparison.

@param [Object] uri The URI to compare.

@return [TrueClass, FalseClass]

  <tt>true</tt> if the URIs are equivalent, <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1709
1709:     def eql?(uri)
1710:       return false unless uri.kind_of?(self.class)
1711:       return self.to_s == uri.to_s
1712:     end

The extname, if any, of the file in the path component. Empty string if there is no extension.

@return [String] The path‘s extname.

[Source]

      # File lib/addressable/uri.rb, line 1081
1081:     def extname
1082:       return nil unless self.path
1083:       return File.extname(self.basename)
1084:     end

The fragment component for this URI.

@return [String] The fragment component.

[Source]

      # File lib/addressable/uri.rb, line 1277
1277:     def fragment
1278:       return @fragment
1279:     end

Sets the fragment component for this URI.

@param [String, to_str] new_fragment The new fragment component.

[Source]

      # File lib/addressable/uri.rb, line 1303
1303:     def fragment=(new_fragment)
1304:       # Check for frozenness
1305:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1306: 
1307:       @fragment = new_fragment ? new_fragment.to_str : nil
1308: 
1309:       # Reset dependant values
1310:       @normalized_fragment = nil
1311:       @uri_string = nil
1312: 
1313:       # Ensure we haven't created an invalid URI
1314:       validate()
1315:     end

Freezes the URI object.

@return [Addressable::URI] The frozen URI.

[Source]

      # File lib/addressable/uri.rb, line 1745
1745:     def freeze
1746:       # Unfortunately, because of the memoized implementation of many of the
1747:       # URI methods, the default freeze method will cause unexpected errors.
1748:       # As an alternative, we freeze the string representation of the URI
1749:       # instead.  This should generally produce the desired effect.
1750:       self.to_s.freeze
1751:       return self
1752:     end

Determines if the URI is frozen.

@return [TrueClass, FalseClass]

  True if the URI is frozen, false otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1759
1759:     def frozen?
1760:       self.to_s.frozen?
1761:     end

A hash value that will make a URI equivalent to its normalized form.

@return [Integer] A hash of the URI.

[Source]

      # File lib/addressable/uri.rb, line 1719
1719:     def hash
1720:       return @hash ||= (self.to_s.hash * -1)
1721:     end

The host component for this URI.

@return [String] The host component.

[Source]

     # File lib/addressable/uri.rb, line 782
782:     def host
783:       return @host
784:     end

Sets the host component for this URI.

@param [String, to_str] new_host The new host component.

[Source]

     # File lib/addressable/uri.rb, line 815
815:     def host=(new_host)
816:       # Check for frozenness
817:       raise TypeError, "Can't modify frozen URI." if self.frozen?
818: 
819:       @host = new_host ? new_host.to_str : nil
820: 
821:       # Reset dependant values
822:       @authority = nil
823:       @normalized_host = nil
824:       @uri_string = nil
825: 
826:       # Ensure we haven't created an invalid URI
827:       validate()
828:     end

The inferred port component for this URI. This method will normalize to the default port for the URI‘s scheme if the port isn‘t explicitly specified in the URI.

@return [Integer] The inferred port component.

[Source]

      # File lib/addressable/uri.rb, line 999
 999:     def inferred_port
1000:       @inferred_port ||= (begin
1001:         if port.to_i == 0
1002:           if scheme
1003:             self.class.port_mapping[scheme.strip.downcase]
1004:           else
1005:             nil
1006:           end
1007:         else
1008:           port.to_i
1009:         end
1010:       end)
1011:     end

Returns a String representation of the URI object‘s state.

@return [String] The URI object‘s state, as a String.

[Source]

      # File lib/addressable/uri.rb, line 1850
1850:     def inspect
1851:       sprintf("#<%s:%#0x URI:%s>", self.class.to_s, self.object_id, self.to_s)
1852:     end

Determines if the scheme indicates an IP-based protocol.

@return [TrueClass, FalseClass]

  <tt>true</tt> if the scheme indicates an IP-based protocol.
  <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1323
1323:     def ip_based?
1324:       if self.scheme
1325:         return self.class.ip_based_schemes.include?(
1326:           self.scheme.strip.downcase)
1327:       end
1328:       return false
1329:     end

Joins two URIs together.

@param [String, Addressable::URI, to_str] The URI to join with.

@return [Addressable::URI] The joined URI.

[Source]

      # File lib/addressable/uri.rb, line 1357
1357:     def join(uri)
1358:       if !uri.respond_to?(:to_str)
1359:         raise TypeError, "Can't convert #{uri.class} into String."
1360:       end
1361:       if !uri.kind_of?(self.class)
1362:         # Otherwise, convert to a String, then parse.
1363:         uri = self.class.parse(uri.to_str)
1364:       end
1365:       if uri.to_s == ""
1366:         return self.dup
1367:       end
1368: 
1369:       joined_scheme = nil
1370:       joined_user = nil
1371:       joined_password = nil
1372:       joined_host = nil
1373:       joined_port = nil
1374:       joined_path = nil
1375:       joined_query = nil
1376:       joined_fragment = nil
1377: 
1378:       # Section 5.2.2 of RFC 3986
1379:       if uri.scheme != nil
1380:         joined_scheme = uri.scheme
1381:         joined_user = uri.user
1382:         joined_password = uri.password
1383:         joined_host = uri.host
1384:         joined_port = uri.port
1385:         joined_path = self.class.normalize_path(uri.path)
1386:         joined_query = uri.query
1387:       else
1388:         if uri.authority != nil
1389:           joined_user = uri.user
1390:           joined_password = uri.password
1391:           joined_host = uri.host
1392:           joined_port = uri.port
1393:           joined_path = self.class.normalize_path(uri.path)
1394:           joined_query = uri.query
1395:         else
1396:           if uri.path == nil || uri.path == ""
1397:             joined_path = self.path
1398:             if uri.query != nil
1399:               joined_query = uri.query
1400:             else
1401:               joined_query = self.query
1402:             end
1403:           else
1404:             if uri.path[0..0] == "/"
1405:               joined_path = self.class.normalize_path(uri.path)
1406:             else
1407:               base_path = self.path.dup
1408:               base_path = "" if base_path == nil
1409:               base_path = self.class.normalize_path(base_path)
1410: 
1411:               # Section 5.2.3 of RFC 3986
1412:               #
1413:               # Removes the right-most path segment from the base path.
1414:               if base_path =~ /\//
1415:                 base_path.gsub!(/\/[^\/]+$/, "/")
1416:               else
1417:                 base_path = ""
1418:               end
1419: 
1420:               # If the base path is empty and an authority segment has been
1421:               # defined, use a base path of "/"
1422:               if base_path == "" && self.authority != nil
1423:                 base_path = "/"
1424:               end
1425: 
1426:               joined_path = self.class.normalize_path(base_path + uri.path)
1427:             end
1428:             joined_query = uri.query
1429:           end
1430:           joined_user = self.user
1431:           joined_password = self.password
1432:           joined_host = self.host
1433:           joined_port = self.port
1434:         end
1435:         joined_scheme = self.scheme
1436:       end
1437:       joined_fragment = uri.fragment
1438: 
1439:       return Addressable::URI.new(
1440:         :scheme => joined_scheme,
1441:         :user => joined_user,
1442:         :password => joined_password,
1443:         :host => joined_host,
1444:         :port => joined_port,
1445:         :path => joined_path,
1446:         :query => joined_query,
1447:         :fragment => joined_fragment
1448:       )
1449:     end

Destructive form of join.

@param [String, Addressable::URI, to_str] The URI to join with.

@return [Addressable::URI] The joined URI.

@see Addressable::URI#join

[Source]

      # File lib/addressable/uri.rb, line 1460
1460:     def join!(uri)
1461:       replace_self(self.join(uri))
1462:     end

Merges a URI with a Hash of components. This method has different behavior from join. Any components present in the hash parameter will override the original components. The path component is not treated specially.

@param [Hash, Addressable::URI, to_hash] The components to merge with.

@return [Addressable::URI] The merged URI.

@see Hash#merge

[Source]

      # File lib/addressable/uri.rb, line 1475
1475:     def merge(hash)
1476:       if !hash.respond_to?(:to_hash)
1477:         raise TypeError, "Can't convert #{hash.class} into Hash."
1478:       end
1479:       hash = hash.to_hash
1480: 
1481:       if hash.has_key?(:authority)
1482:         if (hash.keys & [:userinfo, :user, :password, :host, :port]).any?
1483:           raise ArgumentError,
1484:             "Cannot specify both an authority and any of the components " +
1485:             "within the authority."
1486:         end
1487:       end
1488:       if hash.has_key?(:userinfo)
1489:         if (hash.keys & [:user, :password]).any?
1490:           raise ArgumentError,
1491:             "Cannot specify both a userinfo and either the user or password."
1492:         end
1493:       end
1494: 
1495:       uri = Addressable::URI.new
1496:       uri.validation_deferred = true
1497:       uri.scheme =
1498:         hash.has_key?(:scheme) ? hash[:scheme] : self.scheme
1499:       if hash.has_key?(:authority)
1500:         uri.authority =
1501:           hash.has_key?(:authority) ? hash[:authority] : self.authority
1502:       end
1503:       if hash.has_key?(:userinfo)
1504:         uri.userinfo =
1505:           hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo
1506:       end
1507:       if !hash.has_key?(:userinfo) && !hash.has_key?(:authority)
1508:         uri.user =
1509:           hash.has_key?(:user) ? hash[:user] : self.user
1510:         uri.password =
1511:           hash.has_key?(:password) ? hash[:password] : self.password
1512:       end
1513:       if !hash.has_key?(:authority)
1514:         uri.host =
1515:           hash.has_key?(:host) ? hash[:host] : self.host
1516:         uri.port =
1517:           hash.has_key?(:port) ? hash[:port] : self.port
1518:       end
1519:       uri.path =
1520:         hash.has_key?(:path) ? hash[:path] : self.path
1521:       uri.query =
1522:         hash.has_key?(:query) ? hash[:query] : self.query
1523:       uri.fragment =
1524:         hash.has_key?(:fragment) ? hash[:fragment] : self.fragment
1525:       uri.validation_deferred = false
1526: 
1527:       return uri
1528:     end

Destructive form of merge.

@param [Hash, Addressable::URI, to_hash] The components to merge with.

@return [Addressable::URI] The merged URI.

@see Addressable::URI#merge

[Source]

      # File lib/addressable/uri.rb, line 1538
1538:     def merge!(uri)
1539:       replace_self(self.merge(uri))
1540:     end

Returns a normalized URI object.

NOTE: This method does not attempt to fully conform to specifications. It exists largely to correct other people‘s failures to read the specifications, and also to deal with caching issues since several different URIs may represent the same resource and should not be cached multiple times.

@return [Addressable::URI] The normalized URI.

[Source]

      # File lib/addressable/uri.rb, line 1623
1623:     def normalize
1624:       # This is a special exception for the frequently misused feed
1625:       # URI scheme.
1626:       if normalized_scheme == "feed"
1627:         if self.to_s =~ /^feed:\/*http:\/*/
1628:           return self.class.parse(
1629:             self.to_s[/^feed:\/*(http:\/*.*)/, 1]
1630:           ).normalize
1631:         end
1632:       end
1633: 
1634:       return Addressable::URI.new(
1635:         :scheme => normalized_scheme,
1636:         :authority => normalized_authority,
1637:         :path => normalized_path,
1638:         :query => normalized_query,
1639:         :fragment => normalized_fragment
1640:       )
1641:     end

Destructively normalizes this URI object.

@return [Addressable::URI] The normalized URI.

@see Addressable::URI#normalize

[Source]

      # File lib/addressable/uri.rb, line 1649
1649:     def normalize!
1650:       replace_self(self.normalize)
1651:     end

The authority component for this URI, normalized.

@return [String] The authority component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 857
857:     def normalized_authority
858:       @normalized_authority ||= (begin
859:         if self.normalized_host.nil?
860:           nil
861:         else
862:           authority = ""
863:           if self.normalized_userinfo != nil
864:             authority << "#{self.normalized_userinfo}@"
865:           end
866:           authority << self.normalized_host
867:           if self.normalized_port != nil
868:             authority << ":#{self.normalized_port}"
869:           end
870:           authority
871:         end
872:       end)
873:     end

The fragment component for this URI, normalized.

@return [String] The fragment component, normalized.

[Source]

      # File lib/addressable/uri.rb, line 1285
1285:     def normalized_fragment
1286:       @normalized_fragment ||= (begin
1287:         if self.fragment
1288:           Addressable::URI.encode_component(
1289:             Addressable::IDNA.unicode_normalize_kc(
1290:               Addressable::URI.unencode_component(self.fragment.strip)),
1291:             Addressable::URI::CharacterClasses::FRAGMENT
1292:           )
1293:         else
1294:           nil
1295:         end
1296:       end)
1297:     end

The host component for this URI, normalized.

@return [String] The host component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 790
790:     def normalized_host
791:       @normalized_host ||= (begin
792:         if self.host != nil
793:           if self.host.strip != ""
794:             result = ::Addressable::IDNA.to_ascii(
795:               self.class.unencode_component(self.host.strip.downcase)
796:             )
797:             if result[-1..-1] == "."
798:               # Trailing dots are unnecessary
799:               result = result[0...-1]
800:             end
801:             result
802:           else
803:             ""
804:           end
805:         else
806:           nil
807:         end
808:       end)
809:     end

The password component for this URI, normalized.

@return [String] The password component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 665
665:     def normalized_password
666:       @normalized_password ||= (begin
667:         if self.password
668:           if normalized_scheme =~ /https?/ && self.password.strip == "" &&
669:               (!self.user || self.user.strip == "")
670:             nil
671:           else
672:             Addressable::URI.encode_component(
673:               Addressable::IDNA.unicode_normalize_kc(
674:                 Addressable::URI.unencode_component(self.password.strip)),
675:               Addressable::URI::CharacterClasses::UNRESERVED
676:             )
677:           end
678:         else
679:           nil
680:         end
681:       end)
682:     end

The path component for this URI, normalized.

@return [String] The path component, normalized.

[Source]

      # File lib/addressable/uri.rb, line 1025
1025:     def normalized_path
1026:       @normalized_path ||= (begin
1027:         begin
1028:           result = Addressable::URI.encode_component(
1029:             Addressable::IDNA.unicode_normalize_kc(
1030:               Addressable::URI.unencode_component(self.path.strip)),
1031:             Addressable::URI::CharacterClasses::PATH
1032:           )
1033:         rescue ArgumentError
1034:           # Likely a malformed UTF-8 character, skip unicode normalization
1035:           result = Addressable::URI.encode_component(
1036:             Addressable::URI.unencode_component(self.path.strip),
1037:             Addressable::URI::CharacterClasses::PATH
1038:           )
1039:         end
1040:         result = self.class.normalize_path(result)
1041:         if result == "" &&
1042:             ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme)
1043:           result = "/"
1044:         end
1045:         result
1046:       end)
1047:     end

The port component for this URI, normalized.

@return [Integer] The port component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 954
954:     def normalized_port
955:       @normalized_port ||= (begin
956:         if self.class.port_mapping[normalized_scheme] == self.port
957:           nil
958:         else
959:           self.port
960:         end
961:       end)
962:     end

The query component for this URI, normalized.

@return [String] The query component, normalized.

[Source]

      # File lib/addressable/uri.rb, line 1098
1098:     def normalized_query
1099:       @normalized_query ||= (begin
1100:         if self.query
1101:           Addressable::URI.encode_component(
1102:             Addressable::IDNA.unicode_normalize_kc(
1103:               Addressable::URI.unencode_component(self.query.strip)),
1104:             Addressable::URI::CharacterClasses::QUERY
1105:           )
1106:         else
1107:           nil
1108:         end
1109:       end)
1110:     end

The scheme component for this URI, normalized.

@return [String] The scheme component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 557
557:     def normalized_scheme
558:       @normalized_scheme ||= (begin
559:         if self.scheme != nil
560:           if self.scheme =~ /^\s*ssh\+svn\s*$/i
561:             "svn+ssh"
562:           else
563:             Addressable::URI.encode_component(
564:               Addressable::IDNA.unicode_normalize_kc(
565:                 Addressable::URI.unencode_component(
566:                   self.scheme.strip.downcase)),
567:               Addressable::URI::CharacterClasses::SCHEME
568:             )
569:           end
570:         else
571:           nil
572:         end
573:       end)
574:     end

The user component for this URI, normalized.

@return [String] The user component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 607
607:     def normalized_user
608:       @normalized_user ||= (begin
609:         if self.user
610:           if normalized_scheme =~ /https?/ && self.user.strip == "" &&
611:               (!self.password || self.password.strip == "")
612:             nil
613:           else
614:             Addressable::URI.encode_component(
615:               Addressable::IDNA.unicode_normalize_kc(
616:                 Addressable::URI.unencode_component(self.user.strip)),
617:               Addressable::URI::CharacterClasses::UNRESERVED
618:             )
619:           end
620:         else
621:           nil
622:         end
623:       end)
624:     end

The userinfo component for this URI, normalized.

@return [String] The userinfo component, normalized.

[Source]

     # File lib/addressable/uri.rb, line 735
735:     def normalized_userinfo
736:       @normalized_userinfo ||= (begin
737:         current_user = self.normalized_user
738:         current_password = self.normalized_password
739:         if !current_user && !current_password
740:           nil
741:         elsif current_user && current_password
742:           "#{current_user}:#{current_password}"
743:         elsif current_user && !current_password
744:           "#{current_user}"
745:         end
746:       end)
747:     end

Omits components from a URI.

@param [Symbol] *components The components to be omitted.

@return [Addressable::URI] The URI with components omitted.

@example

  uri = Addressable::URI.parse("http://example.com/path?query")
  #=> #<Addressable::URI:0xcc5e7a URI:http://example.com/path?query>
  uri.omit(:scheme, :authority)
  #=> #<Addressable::URI:0xcc4d86 URI:/path?query>

[Source]

      # File lib/addressable/uri.rb, line 1775
1775:     def omit(*components)
1776:       invalid_components = components - [
1777:         :scheme, :user, :password, :userinfo, :host, :port, :authority,
1778:         :path, :query, :fragment
1779:       ]
1780:       unless invalid_components.empty?
1781:         raise ArgumentError,
1782:           "Invalid component names: #{invalid_components.inspect}."
1783:       end
1784:       duplicated_uri = self.dup
1785:       duplicated_uri.validation_deferred = true
1786:       components.each do |component|
1787:         duplicated_uri.send((component.to_s + "=").to_sym, nil)
1788:       end
1789:       duplicated_uri.user = duplicated_uri.normalized_user
1790:       duplicated_uri.validation_deferred = false
1791:       duplicated_uri
1792:     end

Destructive form of omit.

@param [Symbol] *components The components to be omitted.

@return [Addressable::URI] The URI with components omitted.

@see Addressable::URI#omit

[Source]

      # File lib/addressable/uri.rb, line 1802
1802:     def omit!(*components)
1803:       replace_self(self.omit(*components))
1804:     end

The password component for this URI.

@return [String] The password component.

[Source]

     # File lib/addressable/uri.rb, line 657
657:     def password
658:       return @password
659:     end

Sets the password component for this URI.

@param [String, to_str] new_password The new password component.

[Source]

     # File lib/addressable/uri.rb, line 688
688:     def password=(new_password)
689:       # Check for frozenness
690:       raise TypeError, "Can't modify frozen URI." if self.frozen?
691: 
692:       @password = new_password ? new_password.to_str : nil
693: 
694:       # You can't have a nil user with a non-nil password
695:       @password ||= nil
696:       @user ||= nil
697:       if @password != nil
698:         @user = "" if @user.nil?
699:       end
700: 
701:       # Reset dependant values
702:       @userinfo = nil
703:       @normalized_userinfo = nil
704:       @authority = nil
705:       @normalized_password = nil
706:       @uri_string = nil
707: 
708:       # Ensure we haven't created an invalid URI
709:       validate()
710:     end

The path component for this URI.

@return [String] The path component.

[Source]

      # File lib/addressable/uri.rb, line 1017
1017:     def path
1018:       return (@path || "")
1019:     end

Sets the path component for this URI.

@param [String, to_str] new_path The new path component.

[Source]

      # File lib/addressable/uri.rb, line 1053
1053:     def path=(new_path)
1054:       # Check for frozenness
1055:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1056: 
1057:       @path = (new_path || "").to_str
1058:       if @path != "" && @path[0..0] != "/" && host != nil
1059:         @path = "/#{@path}"
1060:       end
1061: 
1062:       # Reset dependant values
1063:       @normalized_path = nil
1064:       @uri_string = nil
1065:     end

The port component for this URI. This is the port number actually given in the URI. This does not infer port numbers from default values.

@return [Integer] The port component.

[Source]

     # File lib/addressable/uri.rb, line 946
946:     def port
947:       return @port ||= nil
948:     end

Sets the port component for this URI.

@param [String, Integer, to_s] new_port The new port component.

[Source]

     # File lib/addressable/uri.rb, line 968
968:     def port=(new_port)
969:       # Check for frozenness
970:       raise TypeError, "Can't modify frozen URI." if self.frozen?
971: 
972:       if new_port != nil && new_port.respond_to?(:to_str)
973:         new_port = Addressable::URI.unencode_component(new_port.to_str)
974:       end
975:       if new_port != nil && !(new_port.to_s =~ /^\d+$/)
976:         raise InvalidURIError,
977:           "Invalid port number: #{new_port.inspect}"
978:       end
979: 
980:       @port = new_port.to_s.to_i
981:       @port = nil if @port == 0
982: 
983:       # Reset dependant values
984:       @authority = nil
985:       @inferred_port = nil
986:       @normalized_port = nil
987:       @uri_string = nil
988: 
989:       # Ensure we haven't created an invalid URI
990:       validate()
991:     end

The query component for this URI.

@return [String] The query component.

[Source]

      # File lib/addressable/uri.rb, line 1090
1090:     def query
1091:       return @query
1092:     end

Sets the query component for this URI.

@param [String, to_str] new_query The new query component.

[Source]

      # File lib/addressable/uri.rb, line 1116
1116:     def query=(new_query)
1117:       # Check for frozenness
1118:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1119: 
1120:       @query = new_query ? new_query.to_str : nil
1121: 
1122:       # Reset dependant values
1123:       @normalized_query = nil
1124:       @uri_string = nil
1125:     end

Converts the query component to a Hash value.

@option [Symbol] notation

  May be one of <tt>:flat</tt>, <tt>:dot</tt>, or <tt>:subscript</tt>.
  The <tt>:dot</tt> notation is not supported for assignment.
  Default value is <tt>:subscript</tt>.

@return [Hash] The query string parsed as a Hash object.

@example

  Addressable::URI.parse("?one=1&two=2&three=3").query_values
  #=> {"one" => "1", "two" => "2", "three" => "3"}
  Addressable::URI.parse("?one[two][three]=four").query_values
  #=> {"one" => {"two" => {"three" => "four"}}}
  Addressable::URI.parse("?one.two.three=four").query_values(
    :notation => :dot
  )
  #=> {"one" => {"two" => {"three" => "four"}}}
  Addressable::URI.parse("?one[two][three]=four").query_values(
    :notation => :flat
  )
  #=> {"one[two][three]" => "four"}
  Addressable::URI.parse("?one.two.three=four").query_values(
    :notation => :flat
  )
  #=> {"one.two.three" => "four"}
  Addressable::URI.parse(
    "?one[two][three][]=four&one[two][three][]=five"
  ).query_values
  #=> {"one" => {"two" => {"three" => ["four", "five"]}}}

[Source]

      # File lib/addressable/uri.rb, line 1158
1158:     def query_values(options={})
1159:       defaults = {:notation => :subscript}
1160:       options = defaults.merge(options)
1161:       if ![:flat, :dot, :subscript].include?(options[:notation])
1162:         raise ArgumentError,
1163:           "Invalid notation. Must be one of: [:flat, :dot, :subscript]."
1164:       end
1165:       dehash = lambda do |hash|
1166:         hash.each do |(key, value)|
1167:           if value.kind_of?(Hash)
1168:             hash[key] = dehash.call(value)
1169:           end
1170:         end
1171:         if hash != {} && hash.keys.all? { |key| key =~ /^\d+$/ }
1172:           hash.sort.inject([]) do |accu, (key, value)|
1173:             accu << value; accu
1174:           end
1175:         else
1176:           hash
1177:         end
1178:       end
1179:       return nil if self.query == nil
1180:       return ((self.query.split("&").map do |pair|
1181:         pair.split("=")
1182:       end).inject({}) do |accumulator, (key, value)|
1183:         value = true if value.nil?
1184:         key = self.class.unencode_component(key)
1185:         if value != true
1186:           value = self.class.unencode_component(value).gsub(/\+/, " ")
1187:         end
1188:         if options[:notation] == :flat
1189:           if accumulator[key]
1190:             raise ArgumentError, "Key was repeated: #{key.inspect}"
1191:           end
1192:           accumulator[key] = value
1193:         else
1194:           if options[:notation] == :dot
1195:             array_value = false
1196:             subkeys = key.split(".")
1197:           elsif options[:notation] == :subscript
1198:             array_value = !!(key =~ /\[\]$/)
1199:             subkeys = key.split(/[\[\]]+/)
1200:           end
1201:           current_hash = accumulator
1202:           for i in 0...(subkeys.size - 1)
1203:             subkey = subkeys[i]
1204:             current_hash[subkey] = {} unless current_hash[subkey]
1205:             current_hash = current_hash[subkey]
1206:           end
1207:           if array_value
1208:             current_hash[subkeys.last] = [] unless current_hash[subkeys.last]
1209:             current_hash[subkeys.last] << value
1210:           else
1211:             current_hash[subkeys.last] = value
1212:           end
1213:         end
1214:         accumulator
1215:       end).inject({}) do |accumulator, (key, value)|
1216:         accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1217:         accumulator
1218:       end
1219:     end

Sets the query component for this URI from a Hash object. This method produces a query string using the :subscript notation.

@param [Hash, to_hash] new_query_values The new query values.

[Source]

      # File lib/addressable/uri.rb, line 1226
1226:     def query_values=(new_query_values)
1227:       # Check for frozenness
1228:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1229:       if !new_query_values.respond_to?(:to_hash)
1230:         raise TypeError, "Can't convert #{new_query_values.class} into Hash."
1231:       end
1232:       new_query_values = new_query_values.to_hash
1233: 
1234:       # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
1235:       buffer = ""
1236:       stack = []
1237:       e = lambda do |component|
1238:         component = component.to_s if component.kind_of?(Symbol)
1239:         self.class.encode_component(component, CharacterClasses::UNRESERVED)
1240:       end
1241:       new_query_values.each do |key, value|
1242:         if value.kind_of?(Hash)
1243:           stack << [key, value]
1244:         elsif value.kind_of?(Array)
1245:           stack << [
1246:             key,
1247:             value.inject({}) { |accu, x| accu[accu.size.to_s] = x; accu }
1248:           ]
1249:         elsif value == true
1250:           buffer << "#{e.call(key)}&"
1251:         else
1252:           buffer << "#{e.call(key)}=#{e.call(value)}&"
1253:         end
1254:       end
1255:       stack.each do |(parent, hash)|
1256:         (hash.sort_by { |key| key.to_s }).each do |(key, value)|
1257:           if value.kind_of?(Hash)
1258:             stack << ["#{parent}[#{key}]", value]
1259:           elsif value == true
1260:             buffer << "#{parent}[#{e.call(key)}]&"
1261:           else
1262:             buffer << "#{parent}[#{e.call(key)}]=#{e.call(value)}&"
1263:           end
1264:         end
1265:       end
1266:       @query = buffer.chop
1267: 
1268:       # Reset dependant values
1269:       @normalized_query = nil
1270:       @uri_string = nil
1271:     end

Determines if the URI is relative.

@return [TrueClass, FalseClass]

  <tt>true</tt> if the URI is relative.
  <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1337
1337:     def relative?
1338:       return self.scheme.nil?
1339:     end

Returns the shortest normalized relative form of this URI that uses the supplied URI as a base for resolution. Returns an absolute URI if necessary. This is effectively the opposite of route_to.

@param [String, Addressable::URI, to_str] uri The URI to route from.

@return [Addressable::URI]

  The normalized relative URI that is equivalent to the original URI.

[Source]

      # File lib/addressable/uri.rb, line 1551
1551:     def route_from(uri)
1552:       uri = self.class.parse(uri).normalize
1553:       normalized_self = self.normalize
1554:       if normalized_self.relative?
1555:         raise ArgumentError, "Expected absolute URI, got: #{self.to_s}"
1556:       end
1557:       if uri.relative?
1558:         raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}"
1559:       end
1560:       if normalized_self == uri
1561:         return Addressable::URI.parse("##{normalized_self.fragment}")
1562:       end
1563:       components = normalized_self.to_hash
1564:       if normalized_self.scheme == uri.scheme
1565:         components[:scheme] = nil
1566:         if normalized_self.authority == uri.authority
1567:           components[:user] = nil
1568:           components[:password] = nil
1569:           components[:host] = nil
1570:           components[:port] = nil
1571:           if normalized_self.path == uri.path
1572:             components[:path] = nil
1573:             if normalized_self.query == uri.query
1574:               components[:query] = nil
1575:             end
1576:           else
1577:             if uri.path != "/"
1578:               components[:path].gsub!(
1579:                 Regexp.new("^" + Regexp.escape(uri.path)), "")
1580:             end
1581:           end
1582:         end
1583:       end
1584:       # Avoid network-path references.
1585:       if components[:host] != nil
1586:         components[:scheme] = normalized_self.scheme
1587:       end
1588:       return Addressable::URI.new(
1589:         :scheme => components[:scheme],
1590:         :user => components[:user],
1591:         :password => components[:password],
1592:         :host => components[:host],
1593:         :port => components[:port],
1594:         :path => components[:path],
1595:         :query => components[:query],
1596:         :fragment => components[:fragment]
1597:       )
1598:     end

Returns the shortest normalized relative form of the supplied URI that uses this URI as a base for resolution. Returns an absolute URI if necessary. This is effectively the opposite of route_from.

@param [String, Addressable::URI, to_str] uri The URI to route to.

@return [Addressable::URI]

  The normalized relative URI that is equivalent to the supplied URI.

[Source]

      # File lib/addressable/uri.rb, line 1609
1609:     def route_to(uri)
1610:       return self.class.parse(uri).route_from(self)
1611:     end

The scheme component for this URI.

@return [String] The scheme component.

[Source]

     # File lib/addressable/uri.rb, line 549
549:     def scheme
550:       return @scheme
551:     end

Sets the scheme component for this URI.

@param [String, to_str] new_scheme The new scheme component.

[Source]

     # File lib/addressable/uri.rb, line 580
580:     def scheme=(new_scheme)
581:       # Check for frozenness
582:       raise TypeError, "Can't modify frozen URI." if self.frozen?
583: 
584:       @scheme = new_scheme ? new_scheme.to_str : nil
585:       @scheme = nil if @scheme.to_s.strip == ""
586: 
587:       # Reset dependant values
588:       @normalized_scheme = nil
589:       @uri_string = nil
590: 
591:       # Ensure we haven't created an invalid URI
592:       validate()
593:     end

Returns a Hash of the URI components.

@return [Hash] The URI as a Hash of components.

[Source]

      # File lib/addressable/uri.rb, line 1833
1833:     def to_hash
1834:       return {
1835:         :scheme => self.scheme,
1836:         :user => self.user,
1837:         :password => self.password,
1838:         :host => self.host,
1839:         :port => self.port,
1840:         :path => self.path,
1841:         :query => self.query,
1842:         :fragment => self.fragment
1843:       }
1844:     end

Converts the URI to a String.

@return [String] The URI‘s String representation.

[Source]

      # File lib/addressable/uri.rb, line 1810
1810:     def to_s
1811:       @uri_string ||= (begin
1812:         uri_string = ""
1813:         uri_string << "#{self.scheme}:" if self.scheme != nil
1814:         uri_string << "//#{self.authority}" if self.authority != nil
1815:         uri_string << self.path.to_s
1816:         uri_string << "?#{self.query}" if self.query != nil
1817:         uri_string << "##{self.fragment}" if self.fragment != nil
1818:         if uri_string.respond_to?(:force_encoding)
1819:           uri_string.force_encoding(Encoding::UTF_8)
1820:         end
1821:         uri_string
1822:       end)
1823:     end
to_str()

Alias for to_s

The user component for this URI.

@return [String] The user component.

[Source]

     # File lib/addressable/uri.rb, line 599
599:     def user
600:       return @user
601:     end

Sets the user component for this URI.

@param [String, to_str] new_user The new user component.

[Source]

     # File lib/addressable/uri.rb, line 630
630:     def user=(new_user)
631:       # Check for frozenness
632:       raise TypeError, "Can't modify frozen URI." if self.frozen?
633: 
634:       @user = new_user ? new_user.to_str : nil
635: 
636:       # You can't have a nil user with a non-nil password
637:       @password ||= nil
638:       if @password != nil
639:         @user = "" if @user.nil?
640:       end
641: 
642:       # Reset dependant values
643:       @userinfo = nil
644:       @normalized_userinfo = nil
645:       @authority = nil
646:       @normalized_user = nil
647:       @uri_string = nil
648: 
649:       # Ensure we haven't created an invalid URI
650:       validate()
651:     end

The userinfo component for this URI. Combines the user and password components.

@return [String] The userinfo component.

[Source]

     # File lib/addressable/uri.rb, line 717
717:     def userinfo
718:       @userinfo ||= (begin
719:         current_user = self.user
720:         current_password = self.password
721:         if !current_user && !current_password
722:           nil
723:         elsif current_user && current_password
724:           "#{current_user}:#{current_password}"
725:         elsif current_user && !current_password
726:           "#{current_user}"
727:         end
728:       end)
729:     end

Sets the userinfo component for this URI.

@param [String, to_str] new_userinfo The new userinfo component.

[Source]

     # File lib/addressable/uri.rb, line 753
753:     def userinfo=(new_userinfo)
754:       # Check for frozenness
755:       raise TypeError, "Can't modify frozen URI." if self.frozen?
756: 
757:       new_user, new_password = if new_userinfo
758:         [
759:           new_userinfo.to_str.strip[/^(.*):/, 1],
760:           new_userinfo.to_str.strip[/:(.*)$/, 1]
761:         ]
762:       else
763:         [nil, nil]
764:       end
765: 
766:       # Password assigned first to ensure validity in case of nil
767:       self.password = new_password
768:       self.user = new_user
769: 
770:       # Reset dependant values
771:       @authority = nil
772:       @uri_string = nil
773: 
774:       # Ensure we haven't created an invalid URI
775:       validate()
776:     end

If URI validation needs to be disabled, this can be set to true.

@return [TrueClass, FalseClass]

  <tt>true</tt> if validation has been deferred,
  <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1860
1860:     def validation_deferred
1861:       !!@validation_deferred
1862:     end

If URI validation needs to be disabled, this can be set to true.

@param [TrueClass, FalseClass] new_validation_deferred

  <tt>true</tt> if validation will be deferred,
  <tt>false</tt> otherwise.

[Source]

      # File lib/addressable/uri.rb, line 1870
1870:     def validation_deferred=(new_validation_deferred)
1871:       # Check for frozenness
1872:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1873: 
1874:       @validation_deferred = new_validation_deferred
1875:       validate unless @validation_deferred
1876:     end

[Validate]