Parent

Files

Addressable::URI

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

Public Class Methods

convert_path(path) click to toggle source

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, #] path

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

Percent encodes any special characters in the URI.

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

  The URI to encode.

@param [Class] returning

  The type of object to return.

This value may only be set to String or Addressable::URI. All other values are invalid. Defaults to String.

@return [String, Addressable::URI]

  The encoded URI.

The return type is determined by the returning parameter.

     # File lib/addressable/uri.rb, line 459
459:     def self.encode(uri, returning=String)
460:       return nil if uri.nil?
461:       if !uri.respond_to?(:to_str)
462:         raise TypeError, "Can't convert #{uri.class} into String."
463:       end
464:       if ![String, ::Addressable::URI].include?(returning)
465:         raise TypeError,
466:           "Expected Class (String or Addressable::URI), " +
467:           "got #{returning.inspect}"
468:       end
469:       uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
470:       encoded_uri = Addressable::URI.new(
471:         :scheme => self.encode_component(uri_object.scheme,
472:           Addressable::URI::CharacterClasses::SCHEME),
473:         :authority => self.encode_component(uri_object.authority,
474:           Addressable::URI::CharacterClasses::AUTHORITY),
475:         :path => self.encode_component(uri_object.path,
476:           Addressable::URI::CharacterClasses::PATH),
477:         :query => self.encode_component(uri_object.query,
478:           Addressable::URI::CharacterClasses::QUERY),
479:         :fragment => self.encode_component(uri_object.fragment,
480:           Addressable::URI::CharacterClasses::FRAGMENT)
481:       )
482:       if returning == String
483:         return encoded_uri.to_s
484:       elsif returning == ::Addressable::URI
485:         return encoded_uri
486:       end
487:     end
encode_component(component, character_class= CharacterClasses::RESERVED + CharacterClasses::UNRESERVED) click to toggle source

Percent encodes a URI component.

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

@param [String, Regexp] character_class

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

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

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, #] uri

  The URI string to parse.

No parsing is performed if the object is already an Addressable::URI. @param [Hash] hints

  A <tt>Hash</tt> of hints to the heuristic parser. 

Defaults to {:scheme => "http"}.

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

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

Returns an array of known ip-based schemes. These schemes typically use a similar URI form: //:@:/

     # File lib/addressable/uri.rb, line 997
997:     def self.ip_based_schemes
998:       return self.port_mapping.keys
999:     end
join(*uris) click to toggle source

Joins several URIs together.

@param [String, Addressable::URI, #] *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>
     # File lib/addressable/uri.rb, line 262
262:     def self.join(*uris)
263:       uri_objects = uris.collect do |uri|
264:         if !uri.respond_to?(:to_str)
265:           raise TypeError, "Can't convert #{uri.class} into String."
266:         end
267:         uri.kind_of?(self) ? uri : self.parse(uri.to_str)
268:       end
269:       result = uri_objects.shift.dup
270:       for uri in uri_objects
271:         result.join!(uri)
272:       end
273:       return result
274:     end
new(options={}) click to toggle source

Creates a new uri object from component parts.

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

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

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

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

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

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

     # File lib/addressable/uri.rb, line 582
582:     def initialize(options={})
583:       if options.has_key?(:authority)
584:         if (options.keys & [:userinfo, :user, :password, :host, :port]).any?
585:           raise ArgumentError,
586:             "Cannot specify both an authority and any of the components " +
587:             "within the authority."
588:         end
589:       end
590:       if options.has_key?(:userinfo)
591:         if (options.keys & [:user, :password]).any?
592:           raise ArgumentError,
593:             "Cannot specify both a userinfo and either the user or password."
594:         end
595:       end
596: 
597:       self.defer_validation do
598:         # Bunch of crazy logic required because of the composite components
599:         # like userinfo and authority.
600:         self.scheme = options[:scheme] if options[:scheme]
601:         self.user = options[:user] if options[:user]
602:         self.password = options[:password] if options[:password]
603:         self.userinfo = options[:userinfo] if options[:userinfo]
604:         self.host = options[:host] if options[:host]
605:         self.port = options[:port] if options[:port]
606:         self.authority = options[:authority] if options[:authority]
607:         self.path = options[:path] if options[:path]
608:         self.query = options[:query] if options[:query]
609:         self.fragment = options[:fragment] if options[:fragment]
610:       end
611:     end
normalize_component(component, character_class= CharacterClasses::RESERVED + CharacterClasses::UNRESERVED) click to toggle source

Normalizes the encoding of a URI component.

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

@param [String, Regexp] character_class

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

@return [String] The normalized component.

@example

  Addressable::URI.normalize_component("simpl%65/%65xampl%65", "b-zB-Z")
  => "simple%2Fex%61mple"
  Addressable::URI.normalize_component(
    "simpl%65/%65xampl%65", /[^b-zB-Z]/
  )
  => "simple%2Fex%61mple"
  Addressable::URI.normalize_component(
    "simpl%65/%65xampl%65",
    Addressable::URI::CharacterClasses::UNRESERVED
  )
  => "simple%2Fexample"
     # File lib/addressable/uri.rb, line 412
412:     def self.normalize_component(component, character_class=
413:         CharacterClasses::RESERVED + CharacterClasses::UNRESERVED)
414:       return nil if component.nil?
415:       if !component.respond_to?(:to_str)
416:         raise TypeError, "Can't convert #{component.class} into String."
417:       end
418:       component = component.to_str
419:       if ![String, Regexp].include?(character_class.class)
420:         raise TypeError,
421:           "Expected String or Regexp, got #{character_class.inspect}"
422:       end
423:       if character_class.kind_of?(String)
424:         character_class = /[^#{character_class}]/
425:       end
426:       if component.respond_to?(:force_encoding)
427:         # We can't perform regexps on invalid UTF sequences, but
428:         # here we need to, so switch to ASCII.
429:         component = component.dup
430:         component.force_encoding(Encoding::ASCII_8BIT)
431:       end
432:       unencoded = self.unencode_component(component)
433:       begin
434:         encoded = self.encode_component(
435:           Addressable::IDNA.unicode_normalize_kc(unencoded),
436:           character_class
437:         )
438:       rescue ArgumentError
439:         encoded = self.encode_component(unencoded)
440:       end
441:       return encoded
442:     end
normalized_encode(uri, returning=String) click to toggle source

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

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

  The URI to encode.

@param [Class] returning

  The type of object to return.

This value may only be set to String or Addressable::URI. All other values are invalid. Defaults to String.

@return [String, Addressable::URI]

  The encoded URI. 

The return type is determined by the returning parameter.

     # File lib/addressable/uri.rb, line 509
509:     def self.normalized_encode(uri, returning=String)
510:       if !uri.respond_to?(:to_str)
511:         raise TypeError, "Can't convert #{uri.class} into String."
512:       end
513:       if ![String, ::Addressable::URI].include?(returning)
514:         raise TypeError,
515:           "Expected Class (String or Addressable::URI), " +
516:           "got #{returning.inspect}"
517:       end
518:       uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
519:       components = {
520:         :scheme => self.unencode_component(uri_object.scheme),
521:         :user => self.unencode_component(uri_object.user),
522:         :password => self.unencode_component(uri_object.password),
523:         :host => self.unencode_component(uri_object.host),
524:         :port => uri_object.port,
525:         :path => self.unencode_component(uri_object.path),
526:         :query => self.unencode_component(uri_object.query),
527:         :fragment => self.unencode_component(uri_object.fragment)
528:       }
529:       components.each do |key, value|
530:         if value != nil
531:           begin
532:             components[key] =
533:               Addressable::IDNA.unicode_normalize_kc(value.to_str)
534:           rescue ArgumentError
535:             # Likely a malformed UTF-8 character, skip unicode normalization
536:             components[key] = value.to_str
537:           end
538:         end
539:       end
540:       encoded_uri = Addressable::URI.new(
541:         :scheme => self.encode_component(components[:scheme],
542:           Addressable::URI::CharacterClasses::SCHEME),
543:         :user => self.encode_component(components[:user],
544:           Addressable::URI::CharacterClasses::UNRESERVED),
545:         :password => self.encode_component(components[:password],
546:           Addressable::URI::CharacterClasses::UNRESERVED),
547:         :host => components[:host],
548:         :port => components[:port],
549:         :path => self.encode_component(components[:path],
550:           Addressable::URI::CharacterClasses::PATH),
551:         :query => self.encode_component(components[:query],
552:           Addressable::URI::CharacterClasses::QUERY),
553:         :fragment => self.encode_component(components[:fragment],
554:           Addressable::URI::CharacterClasses::FRAGMENT)
555:       )
556:       if returning == String
557:         return encoded_uri.to_s
558:       elsif returning == ::Addressable::URI
559:         return encoded_uri
560:       end
561:     end
parse(uri) click to toggle source

Returns a URI object based on the parsed string.

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

  The URI string to parse. 

No parsing is performed if the object is already an Addressable::URI.

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

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

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.

      # File lib/addressable/uri.rb, line 1004
1004:     def self.port_mapping
1005:       @port_mapping ||= {
1006:         "http" => 80,
1007:         "https" => 443,
1008:         "ftp" => 21,
1009:         "tftp" => 69,
1010:         "sftp" => 22,
1011:         "ssh" => 22,
1012:         "svn+ssh" => 22,
1013:         "telnet" => 23,
1014:         "nntp" => 119,
1015:         "gopher" => 70,
1016:         "wais" => 210,
1017:         "ldap" => 389,
1018:         "prospero" => 1525
1019:       }
1020:     end
unencode(uri, returning=String) click to toggle source

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, #] uri

  The URI or component to unencode.

@param [Class] returning

  The type of object to return.

This value may only be set to String or Addressable::URI. All other values are invalid. Defaults to String.

@return [String, Addressable::URI]

  The unencoded component or URI.

The return type is determined by the returning parameter.

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

Private Class Methods

normalize_path(path) click to toggle source

Resolves paths to their simplest form.

@param [String] path The path to normalize.

@return [String] The normalized path.

      # File lib/addressable/uri.rb, line 2005
2005:     def self.normalize_path(path)
2006:       # Section 5.2.4 of RFC 3986
2007: 
2008:       return nil if path.nil?
2009:       normalized_path = path.dup
2010:       previous_state = normalized_path.dup
2011:       begin
2012:         previous_state = normalized_path.dup
2013:         normalized_path.gsub!(/\/\.\//, "/")
2014:         normalized_path.gsub!(/\/\.$/, "/")
2015:         parent = normalized_path[/\/([^\/]+)\/\.\.\//, 1]
2016:         if parent != "." && parent != ".."
2017:           normalized_path.gsub!(/\/#{parent}\/\.\.\//, "/")
2018:         end
2019:         parent = normalized_path[/\/([^\/]+)\/\.\.$/, 1]
2020:         if parent != "." && parent != ".."
2021:           normalized_path.gsub!(/\/#{parent}\/\.\.$/, "/")
2022:         end
2023:         normalized_path.gsub!(/^\.\.?\/?/, "")
2024:         normalized_path.gsub!(/^\/\.\.?\//, "/")
2025:       end until previous_state == normalized_path
2026:       return normalized_path
2027:     end

Public Instance Methods

+(uri) click to toggle source
Alias for: join
==(uri) click to toggle source

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.
      # File lib/addressable/uri.rb, line 1823
1823:     def ==(uri)
1824:       return false unless uri.kind_of?(self.class)
1825:       return self.normalize.to_s == uri.normalize.to_s
1826:     end
===(uri) click to toggle source

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.
      # File lib/addressable/uri.rb, line 1802
1802:     def ===(uri)
1803:       if uri.respond_to?(:normalize)
1804:         uri_string = uri.normalize.to_s
1805:       else
1806:         begin
1807:           uri_string = ::Addressable::URI.parse(uri).normalize.to_s
1808:         rescue InvalidURIError, TypeError
1809:           return false
1810:         end
1811:       end
1812:       return self.normalize.to_s == uri_string
1813:     end
absolute?() click to toggle source

Determines if the URI is absolute.

@return [TrueClass, FalseClass] true if the URI is absolute. false otherwise.

      # File lib/addressable/uri.rb, line 1472
1472:     def absolute?
1473:       return !relative?
1474:     end
authority() click to toggle source

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

@return [String] The authority component.

     # File lib/addressable/uri.rb, line 914
914:     def authority
915:       @authority ||= (begin
916:         if self.host.nil?
917:           nil
918:         else
919:           authority = ""
920:           if self.userinfo != nil
921:             authority << "#{self.userinfo}@"
922:           end
923:           authority << self.host
924:           if self.port != nil
925:             authority << ":#{self.port}"
926:           end
927:           authority
928:         end
929:       end)
930:     end
authority=(new_authority) click to toggle source

Sets the authority component for this URI.

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

     # File lib/addressable/uri.rb, line 958
958:     def authority=(new_authority)
959:       # Check for frozenness
960:       raise TypeError, "Can't modify frozen URI." if self.frozen?
961: 
962:       if new_authority
963:         if !new_authority.respond_to?(:to_str)
964:           raise TypeError, "Can't convert #{new_authority.class} into String."
965:         end
966:         new_authority = new_authority.to_str
967:         new_userinfo = new_authority[/^([^\[\]]*)@/, 1]
968:         if new_userinfo
969:           new_user = new_userinfo.strip[/^([^:]*):?/, 1]
970:           new_password = new_userinfo.strip[/:(.*)$/, 1]
971:         end
972:         new_host =
973:           new_authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
974:         new_port =
975:           new_authority[/:([^:@\[\]]*?)$/, 1]
976:       end
977: 
978:       # Password assigned first to ensure validity in case of nil
979:       self.password = defined?(new_password) ? new_password : nil
980:       self.user = defined?(new_user) ? new_user : nil
981:       self.host = defined?(new_host) ? new_host : nil
982:       self.port = defined?(new_port) ? new_port : nil
983: 
984:       # Reset dependant values
985:       @inferred_port = nil
986:       @userinfo = nil
987:       @normalized_userinfo = nil
988:       @uri_string = nil
989: 
990:       # Ensure we haven't created an invalid URI
991:       validate()
992:     end
basename() click to toggle source

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

@return [String] The path’s basename.

      # File lib/addressable/uri.rb, line 1157
1157:     def basename
1158:       # Path cannot be nil
1159:       return File.basename(self.path).gsub(/;[^\/]*$/, "")
1160:     end
defer_validation(&block) click to toggle source

This method allows you to make several changes to a URI simultaneously, which separately would cause validation errors, but in conjunction, are valid. The URI will be revalidated as soon as the entire block has been executed.

@param [Proc] block

  A set of operations to perform on a given URI.
      # File lib/addressable/uri.rb, line 1989
1989:     def defer_validation(&block)
1990:       raise LocalJumpError, "No block given." unless block
1991:       @validation_deferred = true
1992:       block.call()
1993:       @validation_deferred = false
1994:       validate
1995:       return nil
1996:     end
display_uri() click to toggle source

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 RFC">www.ietf.org/rfc/rfc3986.txt">RFC 3986, section 7.6 for more information.

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

      # File lib/addressable/uri.rb, line 1787
1787:     def display_uri
1788:       display_uri = self.normalize
1789:       display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host)
1790:       return display_uri
1791:     end
dup() click to toggle source

Clones the URI object.

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

      # File lib/addressable/uri.rb, line 1854
1854:     def dup
1855:       duplicated_uri = Addressable::URI.new(
1856:         :scheme => self.scheme ? self.scheme.dup : nil,
1857:         :user => self.user ? self.user.dup : nil,
1858:         :password => self.password ? self.password.dup : nil,
1859:         :host => self.host ? self.host.dup : nil,
1860:         :port => self.port,
1861:         :path => self.path ? self.path.dup : nil,
1862:         :query => self.query ? self.query.dup : nil,
1863:         :fragment => self.fragment ? self.fragment.dup : nil
1864:       )
1865:       return duplicated_uri
1866:     end
eql?(uri) click to toggle source

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.
      # File lib/addressable/uri.rb, line 1836
1836:     def eql?(uri)
1837:       return false unless uri.kind_of?(self.class)
1838:       return self.to_s == uri.to_s
1839:     end
extname() click to toggle source

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

@return [String] The path’s extname.

      # File lib/addressable/uri.rb, line 1167
1167:     def extname
1168:       return nil unless self.path
1169:       return File.extname(self.basename)
1170:     end
fragment() click to toggle source

The fragment component for this URI.

@return [String] The fragment component.

      # File lib/addressable/uri.rb, line 1402
1402:     def fragment
1403:       return @fragment ||= nil
1404:     end
fragment=(new_fragment) click to toggle source

Sets the fragment component for this URI.

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

      # File lib/addressable/uri.rb, line 1427
1427:     def fragment=(new_fragment)
1428:       # Check for frozenness
1429:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1430: 
1431:       if new_fragment && !new_fragment.respond_to?(:to_str)
1432:         raise TypeError, "Can't convert #{new_fragment.class} into String."
1433:       end
1434:       @fragment = new_fragment ? new_fragment.to_str : nil
1435: 
1436:       # Reset dependant values
1437:       @normalized_fragment = nil
1438:       @uri_string = nil
1439: 
1440:       # Ensure we haven't created an invalid URI
1441:       validate()
1442:     end
freeze() click to toggle source

Freezes the URI object.

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

      # File lib/addressable/uri.rb, line 1872
1872:     def freeze
1873:       # Unfortunately, because of the memoized implementation of many of the
1874:       # URI methods, the default freeze method will cause unexpected errors.
1875:       # As an alternative, we freeze the string representation of the URI
1876:       # instead. This should generally produce the desired effect.
1877:       self.to_s.freeze
1878:       return self
1879:     end
frozen?() click to toggle source

Determines if the URI is frozen.

@return [TrueClass, FalseClass]

  True if the URI is frozen, false otherwise.
      # File lib/addressable/uri.rb, line 1886
1886:     def frozen?
1887:       self.to_s.frozen?
1888:     end
hash() click to toggle source

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

@return [Integer] A hash of the URI.

      # File lib/addressable/uri.rb, line 1846
1846:     def hash
1847:       return @hash ||= (self.to_s.hash * 1)
1848:     end
host() click to toggle source

The host component for this URI.

@return [String] The host component.

     # File lib/addressable/uri.rb, line 858
858:     def host
859:       return @host ||= nil
860:     end
host=(new_host) click to toggle source

Sets the host component for this URI.

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

     # File lib/addressable/uri.rb, line 891
891:     def host=(new_host)
892:       # Check for frozenness
893:       raise TypeError, "Can't modify frozen URI." if self.frozen?
894: 
895:       if new_host && !new_host.respond_to?(:to_str)
896:         raise TypeError, "Can't convert #{new_host.class} into String."
897:       end
898:       @host = new_host ? new_host.to_str : nil
899: 
900:       # Reset dependant values
901:       @authority = nil
902:       @normalized_host = nil
903:       @uri_string = nil
904: 
905:       # Ensure we haven't created an invalid URI
906:       validate()
907:     end
inferred_port() click to toggle source

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.

      # File lib/addressable/uri.rb, line 1081
1081:     def inferred_port
1082:       @inferred_port ||= (begin
1083:         if port.to_i == 0
1084:           if scheme
1085:             self.class.port_mapping[scheme.strip.downcase]
1086:           else
1087:             nil
1088:           end
1089:         else
1090:           port.to_i
1091:         end
1092:       end)
1093:     end
inspect() click to toggle source

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

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

      # File lib/addressable/uri.rb, line 1977
1977:     def inspect
1978:       sprintf("#<%s:%#0x URI:%s>", self.class.to_s, self.object_id, self.to_s)
1979:     end
ip_based?() click to toggle source

Determines if the scheme indicates an IP-based protocol.

@return [TrueClass, FalseClass] true if the scheme indicates an IP-based protocol. false otherwise.

      # File lib/addressable/uri.rb, line 1450
1450:     def ip_based?
1451:       if self.scheme
1452:         return self.class.ip_based_schemes.include?(
1453:           self.scheme.strip.downcase)
1454:       end
1455:       return false
1456:     end
join(uri) click to toggle source

Joins two URIs together.

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

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

      # File lib/addressable/uri.rb, line 1482
1482:     def join(uri)
1483:       if !uri.respond_to?(:to_str)
1484:         raise TypeError, "Can't convert #{uri.class} into String."
1485:       end
1486:       if !uri.kind_of?(self.class)
1487:         # Otherwise, convert to a String, then parse.
1488:         uri = self.class.parse(uri.to_str)
1489:       end
1490:       if uri.to_s == ""
1491:         return self.dup
1492:       end
1493: 
1494:       joined_scheme = nil
1495:       joined_user = nil
1496:       joined_password = nil
1497:       joined_host = nil
1498:       joined_port = nil
1499:       joined_path = nil
1500:       joined_query = nil
1501:       joined_fragment = nil
1502: 
1503:       # Section 5.2.2 of RFC 3986
1504:       if uri.scheme != nil
1505:         joined_scheme = uri.scheme
1506:         joined_user = uri.user
1507:         joined_password = uri.password
1508:         joined_host = uri.host
1509:         joined_port = uri.port
1510:         joined_path = self.class.normalize_path(uri.path)
1511:         joined_query = uri.query
1512:       else
1513:         if uri.authority != nil
1514:           joined_user = uri.user
1515:           joined_password = uri.password
1516:           joined_host = uri.host
1517:           joined_port = uri.port
1518:           joined_path = self.class.normalize_path(uri.path)
1519:           joined_query = uri.query
1520:         else
1521:           if uri.path == nil || uri.path == ""
1522:             joined_path = self.path
1523:             if uri.query != nil
1524:               joined_query = uri.query
1525:             else
1526:               joined_query = self.query
1527:             end
1528:           else
1529:             if uri.path[0..0] == "/"
1530:               joined_path = self.class.normalize_path(uri.path)
1531:             else
1532:               base_path = self.path.dup
1533:               base_path = "" if base_path == nil
1534:               base_path = self.class.normalize_path(base_path)
1535: 
1536:               # Section 5.2.3 of RFC 3986
1537:               #
1538:               # Removes the right-most path segment from the base path.
1539:               if base_path =~ /\//
1540:                 base_path.gsub!(/\/[^\/]+$/, "/")
1541:               else
1542:                 base_path = ""
1543:               end
1544: 
1545:               # If the base path is empty and an authority segment has been
1546:               # defined, use a base path of "/"
1547:               if base_path == "" && self.authority != nil
1548:                 base_path = "/"
1549:               end
1550: 
1551:               joined_path = self.class.normalize_path(base_path + uri.path)
1552:             end
1553:             joined_query = uri.query
1554:           end
1555:           joined_user = self.user
1556:           joined_password = self.password
1557:           joined_host = self.host
1558:           joined_port = self.port
1559:         end
1560:         joined_scheme = self.scheme
1561:       end
1562:       joined_fragment = uri.fragment
1563: 
1564:       return Addressable::URI.new(
1565:         :scheme => joined_scheme,
1566:         :user => joined_user,
1567:         :password => joined_password,
1568:         :host => joined_host,
1569:         :port => joined_port,
1570:         :path => joined_path,
1571:         :query => joined_query,
1572:         :fragment => joined_fragment
1573:       )
1574:     end
Also aliased as: +
join!(uri) click to toggle source

Destructive form of join.

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

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

@see Addressable::URI#join

      # File lib/addressable/uri.rb, line 1585
1585:     def join!(uri)
1586:       replace_self(self.join(uri))
1587:     end
merge(hash) click to toggle source

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, #] The components to merge with.

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

@see Hash#merge

      # File lib/addressable/uri.rb, line 1600
1600:     def merge(hash)
1601:       if !hash.respond_to?(:to_hash)
1602:         raise TypeError, "Can't convert #{hash.class} into Hash."
1603:       end
1604:       hash = hash.to_hash
1605: 
1606:       if hash.has_key?(:authority)
1607:         if (hash.keys & [:userinfo, :user, :password, :host, :port]).any?
1608:           raise ArgumentError,
1609:             "Cannot specify both an authority and any of the components " +
1610:             "within the authority."
1611:         end
1612:       end
1613:       if hash.has_key?(:userinfo)
1614:         if (hash.keys & [:user, :password]).any?
1615:           raise ArgumentError,
1616:             "Cannot specify both a userinfo and either the user or password."
1617:         end
1618:       end
1619: 
1620:       uri = Addressable::URI.new
1621:       uri.defer_validation do
1622:         # Bunch of crazy logic required because of the composite components
1623:         # like userinfo and authority.
1624:         uri.scheme =
1625:           hash.has_key?(:scheme) ? hash[:scheme] : self.scheme
1626:         if hash.has_key?(:authority)
1627:           uri.authority =
1628:             hash.has_key?(:authority) ? hash[:authority] : self.authority
1629:         end
1630:         if hash.has_key?(:userinfo)
1631:           uri.userinfo =
1632:             hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo
1633:         end
1634:         if !hash.has_key?(:userinfo) && !hash.has_key?(:authority)
1635:           uri.user =
1636:             hash.has_key?(:user) ? hash[:user] : self.user
1637:           uri.password =
1638:             hash.has_key?(:password) ? hash[:password] : self.password
1639:         end
1640:         if !hash.has_key?(:authority)
1641:           uri.host =
1642:             hash.has_key?(:host) ? hash[:host] : self.host
1643:           uri.port =
1644:             hash.has_key?(:port) ? hash[:port] : self.port
1645:         end
1646:         uri.path =
1647:           hash.has_key?(:path) ? hash[:path] : self.path
1648:         uri.query =
1649:           hash.has_key?(:query) ? hash[:query] : self.query
1650:         uri.fragment =
1651:           hash.has_key?(:fragment) ? hash[:fragment] : self.fragment
1652:       end
1653: 
1654:       return uri
1655:     end
merge!(uri) click to toggle source

Destructive form of merge.

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

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

@see Addressable::URI#merge

      # File lib/addressable/uri.rb, line 1665
1665:     def merge!(uri)
1666:       replace_self(self.merge(uri))
1667:     end
normalize() click to toggle source

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.

      # File lib/addressable/uri.rb, line 1750
1750:     def normalize
1751:       # This is a special exception for the frequently misused feed
1752:       # URI scheme.
1753:       if normalized_scheme == "feed"
1754:         if self.to_s =~ /^feed:\/*http:\/*/
1755:           return self.class.parse(
1756:             self.to_s[/^feed:\/*(http:\/*.*)/, 1]
1757:           ).normalize
1758:         end
1759:       end
1760: 
1761:       return Addressable::URI.new(
1762:         :scheme => normalized_scheme,
1763:         :authority => normalized_authority,
1764:         :path => normalized_path,
1765:         :query => normalized_query,
1766:         :fragment => normalized_fragment
1767:       )
1768:     end
normalize!() click to toggle source

Destructively normalizes this URI object.

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

@see Addressable::URI#normalize

      # File lib/addressable/uri.rb, line 1776
1776:     def normalize!
1777:       replace_self(self.normalize)
1778:     end
normalized_authority() click to toggle source

The authority component for this URI, normalized.

@return [String] The authority component, normalized.

     # File lib/addressable/uri.rb, line 936
936:     def normalized_authority
937:       @normalized_authority ||= (begin
938:         if self.normalized_host.nil?
939:           nil
940:         else
941:           authority = ""
942:           if self.normalized_userinfo != nil
943:             authority << "#{self.normalized_userinfo}@"
944:           end
945:           authority << self.normalized_host
946:           if self.normalized_port != nil
947:             authority << ":#{self.normalized_port}"
948:           end
949:           authority
950:         end
951:       end)
952:     end
normalized_fragment() click to toggle source

The fragment component for this URI, normalized.

@return [String] The fragment component, normalized.

      # File lib/addressable/uri.rb, line 1410
1410:     def normalized_fragment
1411:       @normalized_fragment ||= (begin
1412:         if self.fragment
1413:           Addressable::URI.normalize_component(
1414:             self.fragment.strip,
1415:             Addressable::URI::CharacterClasses::FRAGMENT
1416:           )
1417:         else
1418:           nil
1419:         end
1420:       end)
1421:     end
normalized_host() click to toggle source

The host component for this URI, normalized.

@return [String] The host component, normalized.

     # File lib/addressable/uri.rb, line 866
866:     def normalized_host
867:       @normalized_host ||= (begin
868:         if self.host != nil
869:           if self.host.strip != ""
870:             result = ::Addressable::IDNA.to_ascii(
871:               self.class.unencode_component(self.host.strip.downcase)
872:             )
873:             if result[1..1] == "."
874:               # Trailing dots are unnecessary
875:               result = result[0...1]
876:             end
877:             result
878:           else
879:             ""
880:           end
881:         else
882:           nil
883:         end
884:       end)
885:     end
normalized_password() click to toggle source

The password component for this URI, normalized.

@return [String] The password component, normalized.

     # File lib/addressable/uri.rb, line 736
736:     def normalized_password
737:       @normalized_password ||= (begin
738:         if self.password
739:           if normalized_scheme =~ /https?/ && self.password.strip == "" &&
740:               (!self.user || self.user.strip == "")
741:             nil
742:           else
743:             Addressable::URI.normalize_component(
744:               self.password.strip,
745:               Addressable::URI::CharacterClasses::UNRESERVED
746:             )
747:           end
748:         else
749:           nil
750:         end
751:       end)
752:     end
normalized_path() click to toggle source

The path component for this URI, normalized.

@return [String] The path component, normalized.

      # File lib/addressable/uri.rb, line 1108
1108:     def normalized_path
1109:       @normalized_path ||= (begin
1110:         if self.scheme == nil && self.path != nil && self.path != "" &&
1111:             self.path =~ /^(?!\/)[^\/:]*:.*$/
1112:           # Relative paths with colons in the first segment are ambiguous.
1113:           self.path.sub!(":", "%2F")
1114:         end
1115:         # String#split(delimeter, -1) uses the more strict splitting behavior
1116:         # found by default in Python.
1117:         result = (self.path.strip.split("/", 1).map do |segment|
1118:           Addressable::URI.normalize_component(
1119:             segment,
1120:             Addressable::URI::CharacterClasses::PCHAR
1121:           )
1122:         end).join("/")
1123:         result = self.class.normalize_path(result)
1124:         if result == "" &&
1125:             ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme)
1126:           result = "/"
1127:         end
1128:         result
1129:       end)
1130:     end
normalized_port() click to toggle source

The port component for this URI, normalized.

@return [Integer] The port component, normalized.

      # File lib/addressable/uri.rb, line 1036
1036:     def normalized_port
1037:       @normalized_port ||= (begin
1038:         if self.class.port_mapping[normalized_scheme] == self.port
1039:           nil
1040:         else
1041:           self.port
1042:         end
1043:       end)
1044:     end
normalized_query() click to toggle source

The query component for this URI, normalized.

@return [String] The query component, normalized.

      # File lib/addressable/uri.rb, line 1184
1184:     def normalized_query
1185:       @normalized_query ||= (begin
1186:         if self.query
1187:           Addressable::URI.normalize_component(
1188:             self.query.strip,
1189:             Addressable::URI::CharacterClasses::QUERY
1190:           )
1191:         else
1192:           nil
1193:         end
1194:       end)
1195:     end
normalized_scheme() click to toggle source

The scheme component for this URI, normalized.

@return [String] The scheme component, normalized.

     # File lib/addressable/uri.rb, line 625
625:     def normalized_scheme
626:       @normalized_scheme ||= (begin
627:         if self.scheme != nil
628:           if self.scheme =~ /^\s*ssh\+svn\s*$/
629:             "svn+ssh"
630:           else
631:             Addressable::URI.normalize_component(
632:               self.scheme.strip.downcase,
633:               Addressable::URI::CharacterClasses::SCHEME
634:             )
635:           end
636:         else
637:           nil
638:         end
639:       end)
640:     end
normalized_user() click to toggle source

The user component for this URI, normalized.

@return [String] The user component, normalized.

     # File lib/addressable/uri.rb, line 676
676:     def normalized_user
677:       @normalized_user ||= (begin
678:         if self.user
679:           if normalized_scheme =~ /https?/ && self.user.strip == "" &&
680:               (!self.password || self.password.strip == "")
681:             nil
682:           else
683:             Addressable::URI.normalize_component(
684:               self.user.strip,
685:               Addressable::URI::CharacterClasses::UNRESERVED
686:             )
687:           end
688:         else
689:           nil
690:         end
691:       end)
692:     end
normalized_userinfo() click to toggle source

The userinfo component for this URI, normalized.

@return [String] The userinfo component, normalized.

     # File lib/addressable/uri.rb, line 808
808:     def normalized_userinfo
809:       @normalized_userinfo ||= (begin
810:         current_user = self.normalized_user
811:         current_password = self.normalized_password
812:         if !current_user && !current_password
813:           nil
814:         elsif current_user && current_password
815:           "#{current_user}:#{current_password}"
816:         elsif current_user && !current_password
817:           "#{current_user}"
818:         end
819:       end)
820:     end
omit(*components) click to toggle source

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>
      # File lib/addressable/uri.rb, line 1902
1902:     def omit(*components)
1903:       invalid_components = components - [
1904:         :scheme, :user, :password, :userinfo, :host, :port, :authority,
1905:         :path, :query, :fragment
1906:       ]
1907:       unless invalid_components.empty?
1908:         raise ArgumentError,
1909:           "Invalid component names: #{invalid_components.inspect}."
1910:       end
1911:       duplicated_uri = self.dup
1912:       duplicated_uri.defer_validation do
1913:         components.each do |component|
1914:           duplicated_uri.send((component.to_s + "=").to_sym, nil)
1915:         end
1916:         duplicated_uri.user = duplicated_uri.normalized_user
1917:       end
1918:       duplicated_uri
1919:     end
omit!(*components) click to toggle source

Destructive form of omit.

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

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

@see Addressable::URI#omit

      # File lib/addressable/uri.rb, line 1929
1929:     def omit!(*components)
1930:       replace_self(self.omit(*components))
1931:     end
password() click to toggle source

The password component for this URI.

@return [String] The password component.

     # File lib/addressable/uri.rb, line 728
728:     def password
729:       return @password ||= nil
730:     end
password=(new_password) click to toggle source

Sets the password component for this URI.

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

     # File lib/addressable/uri.rb, line 758
758:     def password=(new_password)
759:       # Check for frozenness
760:       raise TypeError, "Can't modify frozen URI." if self.frozen?
761: 
762:       if new_password && !new_password.respond_to?(:to_str)
763:         raise TypeError, "Can't convert #{new_password.class} into String."
764:       end
765:       @password = new_password ? new_password.to_str : nil
766: 
767:       # You can't have a nil user with a non-nil password
768:       @password ||= nil
769:       @user ||= nil
770:       if @password != nil
771:         @user = "" if @user.nil?
772:       end
773: 
774:       # Reset dependant values
775:       @userinfo = nil
776:       @normalized_userinfo = nil
777:       @authority = nil
778:       @normalized_password = nil
779:       @uri_string = nil
780: 
781:       # Ensure we haven't created an invalid URI
782:       validate()
783:     end
path() click to toggle source

The path component for this URI.

@return [String] The path component.

      # File lib/addressable/uri.rb, line 1099
1099:     def path
1100:       @path ||= ""
1101:       return @path
1102:     end
path=(new_path) click to toggle source

Sets the path component for this URI.

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

      # File lib/addressable/uri.rb, line 1136
1136:     def path=(new_path)
1137:       # Check for frozenness
1138:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1139: 
1140:       if new_path && !new_path.respond_to?(:to_str)
1141:         raise TypeError, "Can't convert #{new_path.class} into String."
1142:       end
1143:       @path = (new_path || "").to_str
1144:       if @path != "" && @path[0..0] != "/" && host != nil
1145:         @path = "/#{@path}"
1146:       end
1147: 
1148:       # Reset dependant values
1149:       @normalized_path = nil
1150:       @uri_string = nil
1151:     end
port() click to toggle source

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.

      # File lib/addressable/uri.rb, line 1028
1028:     def port
1029:       return @port ||= nil
1030:     end
port=(new_port) click to toggle source

Sets the port component for this URI.

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

      # File lib/addressable/uri.rb, line 1050
1050:     def port=(new_port)
1051:       # Check for frozenness
1052:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1053: 
1054:       if new_port != nil && new_port.respond_to?(:to_str)
1055:         new_port = Addressable::URI.unencode_component(new_port.to_str)
1056:       end
1057:       if new_port != nil && !(new_port.to_s =~ /^\d+$/)
1058:         raise InvalidURIError,
1059:           "Invalid port number: #{new_port.inspect}"
1060:       end
1061: 
1062:       @port = new_port.to_s.to_i
1063:       @port = nil if @port == 0
1064: 
1065:       # Reset dependant values
1066:       @authority = nil
1067:       @inferred_port = nil
1068:       @normalized_port = nil
1069:       @uri_string = nil
1070: 
1071:       # Ensure we haven't created an invalid URI
1072:       validate()
1073:     end
query() click to toggle source

The query component for this URI.

@return [String] The query component.

      # File lib/addressable/uri.rb, line 1176
1176:     def query
1177:       return @query ||= nil
1178:     end
query=(new_query) click to toggle source

Sets the query component for this URI.

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

      # File lib/addressable/uri.rb, line 1201
1201:     def query=(new_query)
1202:       # Check for frozenness
1203:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1204: 
1205:       if new_query && !new_query.respond_to?(:to_str)
1206:         raise TypeError, "Can't convert #{new_query.class} into String."
1207:       end
1208:       @query = new_query ? new_query.to_str : nil
1209: 
1210:       # Reset dependant values
1211:       @normalized_query = nil
1212:       @uri_string = nil
1213:     end
query_values(options={}) click to toggle source

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 :dot notation is not supported for assignment. Default value is :subscript.

@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"]}}}
      # File lib/addressable/uri.rb, line 1246
1246:     def query_values(options={})
1247:       defaults = {:notation => :subscript}
1248:       options = defaults.merge(options)
1249:       if ![:flat, :dot, :subscript].include?(options[:notation])
1250:         raise ArgumentError,
1251:           "Invalid notation. Must be one of: [:flat, :dot, :subscript]."
1252:       end
1253:       dehash = lambda do |hash|
1254:         hash.each do |(key, value)|
1255:           if value.kind_of?(Hash)
1256:             hash[key] = dehash.call(value)
1257:           end
1258:         end
1259:         if hash != {} && hash.keys.all? { |key| key =~ /^\d+$/ }
1260:           hash.sort.inject([]) do |accu, (key, value)|
1261:             accu << value; accu
1262:           end
1263:         else
1264:           hash
1265:         end
1266:       end
1267:       return nil if self.query == nil
1268:       return ((self.query.split("&").map do |pair|
1269:         pair.split("=")
1270:       end).inject({}) do |accumulator, (key, value)|
1271:         value = true if value.nil?
1272:         key = self.class.unencode_component(key)
1273:         if value != true
1274:           value = self.class.unencode_component(value).gsub(/\+/, " ")
1275:         end
1276:         if options[:notation] == :flat
1277:           if accumulator[key]
1278:             raise ArgumentError, "Key was repeated: #{key.inspect}"
1279:           end
1280:           accumulator[key] = value
1281:         else
1282:           if options[:notation] == :dot
1283:             array_value = false
1284:             subkeys = key.split(".")
1285:           elsif options[:notation] == :subscript
1286:             array_value = !!(key =~ /\[\]$/)
1287:             subkeys = key.split(/[\[\]]+/)
1288:           end
1289:           current_hash = accumulator
1290:           for i in 0...(subkeys.size - 1)
1291:             subkey = subkeys[i]
1292:             current_hash[subkey] = {} unless current_hash[subkey]
1293:             current_hash = current_hash[subkey]
1294:           end
1295:           if array_value
1296:             current_hash[subkeys.last] = [] unless current_hash[subkeys.last]
1297:             current_hash[subkeys.last] << value
1298:           else
1299:             current_hash[subkeys.last] = value
1300:           end
1301:         end
1302:         accumulator
1303:       end).inject({}) do |accumulator, (key, value)|
1304:         accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1305:         accumulator
1306:       end
1307:     end
query_values=(new_query_values) click to toggle source

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

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

      # File lib/addressable/uri.rb, line 1314
1314:     def query_values=(new_query_values)
1315:       # Check for frozenness
1316:       raise TypeError, "Can't modify frozen URI." if self.frozen?
1317:       if !new_query_values.respond_to?(:to_hash)
1318:         raise TypeError, "Can't convert #{new_query_values.class} into Hash."
1319:       end
1320:       new_query_values = new_query_values.to_hash
1321: 
1322:       # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
1323:       buffer = ""
1324:       stack = []
1325:       e = lambda do |component|
1326:         component = component.to_s if component.kind_of?(Symbol)
1327:         self.class.encode_component(component, CharacterClasses::UNRESERVED)
1328:       end
1329:       new_query_values.each do |key, value|
1330:         if value.kind_of?(Hash)
1331:           stack << [key, value]
1332:         elsif value.kind_of?(Array)
1333:           stack << [
1334:             key,
1335:             value.inject({}) { |accu, x| accu[accu.size.to_s] = x; accu }
1336:           ]
1337:         elsif value == true
1338:           buffer << "#{e.call(key)}&"
1339:         else
1340:           buffer << "#{e.call(key)}=#{e.call(value)}&"
1341:         end
1342:       end
1343:       stack.each do |(parent, hash)|
1344:         (hash.sort_by { |key| key.to_s }).each do |(key, value)|
1345:           if value.kind_of?(Hash)
1346:             stack << ["#{parent}[#{key}]", value]
1347:           elsif value == true
1348:             buffer << "#{parent}[#{e.call(key)}]&"
1349:           else
1350:             buffer << "#{parent}[#{e.call(key)}]=#{e.call(value)}&"
1351:           end
1352:         end
1353:       end
1354:       @query = buffer.chop
1355: 
1356:       # Reset dependant values
1357:       @normalized_query = nil
1358:       @uri_string = nil
1359:     end
relative?() click to toggle source

Determines if the URI is relative.

@return [TrueClass, FalseClass] true if the URI is relative. false otherwise.

      # File lib/addressable/uri.rb, line 1463
1463:     def relative?
1464:       return self.scheme.nil?
1465:     end
request_uri() click to toggle source

The HTTP request URI for this URI. This is the path and the query string.

@return [String] The request URI required for an HTTP request.

      # File lib/addressable/uri.rb, line 1366
1366:     def request_uri
1367:       return nil if self.absolute? && self.scheme !~ /^https?$/
1368:       return (
1369:         (self.path != "" ? self.path : "/") +
1370:         (self.query ? "?#{self.query}" : "")
1371:       )
1372:     end
request_uri=(new_request_uri) click to toggle source

Sets the HTTP request URI for this URI.

@param [String, #] new_request_uri The new HTTP request URI.

      # File lib/addressable/uri.rb, line 1378
1378:     def request_uri=(new_request_uri)
1379:       if !new_request_uri.respond_to?(:to_str)
1380:         raise TypeError, "Can't convert #{new_request_uri.class} into String."
1381:       end
1382:       if self.absolute? && self.scheme !~ /^https?$/
1383:         raise InvalidURIError,
1384:           "Cannot set an HTTP request URI for a non-HTTP URI."
1385:       end
1386:       new_request_uri = new_request_uri.to_str
1387:       path_component = new_request_uri[/^([^\?]*)\?(?:.*)$/, 1]
1388:       query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1]
1389:       path_component = path_component.to_s
1390:       path_component = (path_component != "" ? path_component : "/")
1391:       self.path = path_component
1392:       self.query = query_component
1393: 
1394:       # Reset dependant values
1395:       @uri_string = nil
1396:     end
route_from(uri) click to toggle source

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, #] uri The URI to route from.

@return [Addressable::URI]

  The normalized relative URI that is equivalent to the original URI.
      # File lib/addressable/uri.rb, line 1678
1678:     def route_from(uri)
1679:       uri = self.class.parse(uri).normalize
1680:       normalized_self = self.normalize
1681:       if normalized_self.relative?
1682:         raise ArgumentError, "Expected absolute URI, got: #{self.to_s}"
1683:       end
1684:       if uri.relative?
1685:         raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}"
1686:       end
1687:       if normalized_self == uri
1688:         return Addressable::URI.parse("##{normalized_self.fragment}")
1689:       end
1690:       components = normalized_self.to_hash
1691:       if normalized_self.scheme == uri.scheme
1692:         components[:scheme] = nil
1693:         if normalized_self.authority == uri.authority
1694:           components[:user] = nil
1695:           components[:password] = nil
1696:           components[:host] = nil
1697:           components[:port] = nil
1698:           if normalized_self.path == uri.path
1699:             components[:path] = nil
1700:             if normalized_self.query == uri.query
1701:               components[:query] = nil
1702:             end
1703:           else
1704:             if uri.path != "/"
1705:               components[:path].gsub!(
1706:                 Regexp.new("^" + Regexp.escape(uri.path)), "")
1707:             end
1708:           end
1709:         end
1710:       end
1711:       # Avoid network-path references.
1712:       if components[:host] != nil
1713:         components[:scheme] = normalized_self.scheme
1714:       end
1715:       return Addressable::URI.new(
1716:         :scheme => components[:scheme],
1717:         :user => components[:user],
1718:         :password => components[:password],
1719:         :host => components[:host],
1720:         :port => components[:port],
1721:         :path => components[:path],
1722:         :query => components[:query],
1723:         :fragment => components[:fragment]
1724:       )
1725:     end
route_to(uri) click to toggle source

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, #] uri The URI to route to.

@return [Addressable::URI]

  The normalized relative URI that is equivalent to the supplied URI.
      # File lib/addressable/uri.rb, line 1736
1736:     def route_to(uri)
1737:       return self.class.parse(uri).route_from(self)
1738:     end
scheme() click to toggle source

The scheme component for this URI.

@return [String] The scheme component.

     # File lib/addressable/uri.rb, line 617
617:     def scheme
618:       return @scheme ||= nil
619:     end
scheme=(new_scheme) click to toggle source

Sets the scheme component for this URI.

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

     # File lib/addressable/uri.rb, line 646
646:     def scheme=(new_scheme)
647:       # Check for frozenness
648:       raise TypeError, "Can't modify frozen URI." if self.frozen?
649: 
650:       if new_scheme && !new_scheme.respond_to?(:to_str)
651:         raise TypeError, "Can't convert #{new_scheme.class} into String."
652:       end
653:       @scheme = new_scheme ? new_scheme.to_str : nil
654:       @scheme = nil if @scheme.to_s.strip == ""
655: 
656:       # Reset dependant values
657:       @normalized_scheme = nil
658:       @uri_string = nil
659: 
660:       # Ensure we haven't created an invalid URI
661:       validate()
662:     end
to_hash() click to toggle source

Returns a Hash of the URI components.

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

      # File lib/addressable/uri.rb, line 1960
1960:     def to_hash
1961:       return {
1962:         :scheme => self.scheme,
1963:         :user => self.user,
1964:         :password => self.password,
1965:         :host => self.host,
1966:         :port => self.port,
1967:         :path => self.path,
1968:         :query => self.query,
1969:         :fragment => self.fragment
1970:       }
1971:     end
to_s() click to toggle source

Converts the URI to a String.

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

      # File lib/addressable/uri.rb, line 1937
1937:     def to_s
1938:       @uri_string ||= (begin
1939:         uri_string = ""
1940:         uri_string << "#{self.scheme}:" if self.scheme != nil
1941:         uri_string << "//#{self.authority}" if self.authority != nil
1942:         uri_string << self.path.to_s
1943:         uri_string << "?#{self.query}" if self.query != nil
1944:         uri_string << "##{self.fragment}" if self.fragment != nil
1945:         if uri_string.respond_to?(:force_encoding)
1946:           uri_string.force_encoding(Encoding::UTF_8)
1947:         end
1948:         uri_string
1949:       end)
1950:     end
Also aliased as: to_str
to_str() click to toggle source

URI’s are glorified Strings. Allow implicit conversion.

Alias for: to_s
user() click to toggle source

The user component for this URI.

@return [String] The user component.

     # File lib/addressable/uri.rb, line 668
668:     def user
669:       return @user ||= nil
670:     end
user=(new_user) click to toggle source

Sets the user component for this URI.

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

     # File lib/addressable/uri.rb, line 698
698:     def user=(new_user)
699:       # Check for frozenness
700:       raise TypeError, "Can't modify frozen URI." if self.frozen?
701: 
702:       if new_user && !new_user.respond_to?(:to_str)
703:         raise TypeError, "Can't convert #{new_user.class} into String."
704:       end
705:       @user = new_user ? new_user.to_str : nil
706: 
707:       # You can't have a nil user with a non-nil password
708:       @password ||= nil
709:       if @password != nil
710:         @user = "" if @user.nil?
711:       end
712: 
713:       # Reset dependant values
714:       @userinfo = nil
715:       @normalized_userinfo = nil
716:       @authority = nil
717:       @normalized_user = nil
718:       @uri_string = nil
719: 
720:       # Ensure we haven't created an invalid URI
721:       validate()
722:     end
userinfo() click to toggle source

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

@return [String] The userinfo component.

     # File lib/addressable/uri.rb, line 790
790:     def userinfo
791:       @userinfo ||= (begin
792:         current_user = self.user
793:         current_password = self.password
794:         if !current_user && !current_password
795:           nil
796:         elsif current_user && current_password
797:           "#{current_user}:#{current_password}"
798:         elsif current_user && !current_password
799:           "#{current_user}"
800:         end
801:       end)
802:     end
userinfo=(new_userinfo) click to toggle source

Sets the userinfo component for this URI.

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

     # File lib/addressable/uri.rb, line 826
826:     def userinfo=(new_userinfo)
827:       # Check for frozenness
828:       raise TypeError, "Can't modify frozen URI." if self.frozen?
829: 
830:       if new_userinfo && !new_userinfo.respond_to?(:to_str)
831:         raise TypeError, "Can't convert #{new_userinfo.class} into String."
832:       end
833:       new_user, new_password = if new_userinfo
834:         [
835:           new_userinfo.to_str.strip[/^(.*):/, 1],
836:           new_userinfo.to_str.strip[/:(.*)$/, 1]
837:         ]
838:       else
839:         [nil, nil]
840:       end
841: 
842:       # Password assigned first to ensure validity in case of nil
843:       self.password = new_password
844:       self.user = new_user
845: 
846:       # Reset dependant values
847:       @authority = nil
848:       @uri_string = nil
849: 
850:       # Ensure we haven't created an invalid URI
851:       validate()
852:     end

Private Instance Methods

replace_self(uri) click to toggle source

Replaces the internal state of self with the specified URI’s state. Used in destructive operations to avoid massive code repetition.

@param [Addressable::URI] uri The URI to replace self with.

@return [Addressable::URI] self.

      # File lib/addressable/uri.rb, line 2061
2061:     def replace_self(uri)
2062:       # Reset dependant values
2063:       instance_variables.each do |var|
2064:         instance_variable_set(var, nil)
2065:       end
2066: 
2067:       @scheme = uri.scheme
2068:       @user = uri.user
2069:       @password = uri.password
2070:       @host = uri.host
2071:       @port = uri.port
2072:       @path = uri.path
2073:       @query = uri.query
2074:       @fragment = uri.fragment
2075:       return self
2076:     end
validate() click to toggle source

Ensures that the URI is valid.

      # File lib/addressable/uri.rb, line 2031
2031:     def validate
2032:       return if !!@validation_deferred
2033:       if self.scheme != nil &&
2034:           (self.host == nil || self.host == "") &&
2035:           (self.path == nil || self.path == "")
2036:         raise InvalidURIError,
2037:           "Absolute URI missing hierarchical segment: '#{self.to_s}'"
2038:       end
2039:       if self.host == nil
2040:         if self.port != nil ||
2041:             self.user != nil ||
2042:             self.password != nil
2043:           raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'"
2044:         end
2045:       end
2046:       if self.path != nil && self.path != "" && self.path[0..0] != "/" &&
2047:           self.authority != nil
2048:         raise InvalidURIError,
2049:           "Cannot have a relative path with an authority set: '#{self.to_s}'"
2050:       end
2051:       return nil
2052:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.