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::InvalidTemplateOperatorError
Class Addressable::URI::InvalidTemplateValueError
Class Addressable::URI::InvalidURIError
Class Addressable::URI::TemplateOperatorAbortedError

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 233
233:     def self.convert_path(path)
234:       # If we were given nil, return nil.
235:       return nil unless path
236:       # If a URI object is passed, just return itself.
237:       return path if path.kind_of?(self)
238:       if !path.respond_to?(:to_str)
239:         raise TypeError, "Can't convert #{path.class} into String."
240:       end
241:       # Otherwise, convert to a String
242:       path = path.to_str.strip
243: 
244:       path.gsub!(/^file:\/?\/?/, "") if path =~ /^file:\/?\/?/
245:       path = "/" + path if path =~ /^([a-zA-Z])(\||:)/
246:       uri = self.parse(path)
247: 
248:       if uri.scheme == nil
249:         # Adjust windows-style uris
250:         uri.path.gsub!(/^\/?([a-zA-Z])\|(\\|\/)/, "/\\1:/")
251:         uri.path.gsub!(/\\/, "/")
252:         if File.exists?(uri.path) &&
253:             File.stat(uri.path).directory?
254:           uri.path.gsub!(/\/$/, "")
255:           uri.path = uri.path + '/'
256:         end
257: 
258:         # If the path is absolute, set the scheme and host.
259:         if uri.path =~ /^\//
260:           uri.scheme = "file"
261:           uri.host = ""
262:         end
263:         uri.normalize!
264:       end
265: 
266:       return uri
267:     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 1026
1026:     def self.encode(uri, returning=String)
1027:       return nil if uri.nil?
1028:       if !uri.respond_to?(:to_str)
1029:         raise TypeError, "Can't convert #{uri.class} into String."
1030:       end
1031:       if ![String, ::Addressable::URI].include?(returning)
1032:         raise TypeError,
1033:           "Expected String or Addressable::URI, got #{returning.inspect}"
1034:       end
1035:       uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
1036:       encoded_uri = Addressable::URI.new(
1037:         :scheme => self.encode_component(uri_object.scheme,
1038:           Addressable::URI::CharacterClasses::SCHEME),
1039:         :authority => self.encode_component(uri_object.authority,
1040:           Addressable::URI::CharacterClasses::AUTHORITY),
1041:         :path => self.encode_component(uri_object.path,
1042:           Addressable::URI::CharacterClasses::PATH),
1043:         :query => self.encode_component(uri_object.query,
1044:           Addressable::URI::CharacterClasses::QUERY),
1045:         :fragment => self.encode_component(uri_object.fragment,
1046:           Addressable::URI::CharacterClasses::FRAGMENT)
1047:       )
1048:       if returning == String
1049:         return encoded_uri.to_s
1050:       elsif returning == ::Addressable::URI
1051:         return encoded_uri
1052:       end
1053:     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 946
946:     def self.encode_component(component, character_class=
947:         CharacterClasses::RESERVED + CharacterClasses::UNRESERVED)
948:       return nil if component.nil?
949:       if !component.respond_to?(:to_str)
950:         raise TypeError, "Can't convert #{component.class} into String."
951:       end
952:       component = component.to_str
953:       if ![String, Regexp].include?(character_class.class)
954:         raise TypeError,
955:           "Expected String or Regexp, got #{character_class.inspect}"
956:       end
957:       if character_class.kind_of?(String)
958:         character_class = /[^#{character_class}]/
959:       end
960:       return component.gsub(character_class) do |sequence|
961:         (sequence.unpack('C*').map { |c| "%#{c.to_s(16).upcase}" }).join("")
962:       end
963:     end

Expands a URI template into a full URI.

@param [String, to_str] pattern The URI template pattern. @param [Hash] mapping The mapping that corresponds to the pattern. @param [validate, transform] processor

  An optional processor object may be supplied.  The object should
  respond to either the <tt>validate</tt> or <tt>transform</tt> messages
  or both.  Both the <tt>validate</tt> and <tt>transform</tt> methods
  should take two parameters: <tt>name</tt> and <tt>value</tt>.  The
  <tt>validate</tt> method should return <tt>true</tt> or
  <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
  <tt>false</tt> otherwise.  An <tt>InvalidTemplateValueError</tt>
  exception will be raised if the value is invalid.  The
  <tt>transform</tt> method should return the transformed variable
  value as a <tt>String</tt>.

@return [Addressable::URI] The expanded URI template.

@example

  class ExampleProcessor
    def self.validate(name, value)
      return !!(value =~ /^[\w ]+$/) if name == "query"
      return true
    end

    def self.transform(name, value)
      return value.gsub(/ /, "+") if name == "query"
      return value
    end
  end

  Addressable::URI.expand_template(
    "http://example.com/search/{query}/",
    {"query" => "an example search query"},
    ExampleProcessor
  ).to_s
  #=> "http://example.com/search/an+example+search+query/"

  Addressable::URI.expand_template(
    "http://example.com/search/{-list|+|query}/",
    {"query" => "an example search query".split(" ")}
  ).to_s
  #=> "http://example.com/search/an+example+search+query/"

  Addressable::URI.expand_template(
    "http://example.com/search/{query}/",
    {"query" => "bogus!"},
    ExampleProcessor
  ).to_s
  #=> Addressable::URI::InvalidTemplateValueError

[Source]

     # File lib/addressable/uri.rb, line 320
320:     def self.expand_template(pattern, mapping, processor=nil)
321: 
322:       # FIXME: MUST REFACTOR!!!
323: 
324:       result = pattern.dup
325: 
326:       reserved = Addressable::URI::CharacterClasses::RESERVED
327:       unreserved = Addressable::URI::CharacterClasses::UNRESERVED
328:       anything = reserved + unreserved
329:       operator_expansion =
330:         /\{-([a-zA-Z]+)\|([#{anything}]+)\|([#{anything}]+)\}/
331:       variable_expansion = /\{([#{anything}]+?)(=([#{anything}]+))?\}/
332: 
333:       transformed_mapping = mapping.inject({}) do |accu, pair|
334:         name, value = pair
335:         unless value.respond_to?(:to_ary) || value.respond_to?(:to_str)
336:           raise TypeError,
337:             "Can't convert #{value.class} into String or Array."
338:         end
339:         transformed_value =
340:           value.respond_to?(:to_ary) ? value.to_ary : value.to_str
341: 
342:         # Handle percent escaping, and unicode normalization
343:         if transformed_value.kind_of?(Array)
344:           transformed_value.map! do |value|
345:             self.encode_component(
346:               Addressable::IDNA.unicode_normalize_kc(value),
347:               Addressable::URI::CharacterClasses::UNRESERVED
348:             )
349:           end
350:         else
351:           transformed_value = self.encode_component(
352:             Addressable::IDNA.unicode_normalize_kc(transformed_value),
353:             Addressable::URI::CharacterClasses::UNRESERVED
354:           )
355:         end
356: 
357:         # Process, if we've got a processor
358:         if processor != nil
359:           if processor.respond_to?(:validate)
360:             if !processor.validate(name, value)
361:               display_value = value.kind_of?(Array) ? value.inspect : value
362:               raise InvalidTemplateValueError,
363:                 "#{name}=#{display_value} is an invalid template value."
364:             end
365:           end
366:           if processor.respond_to?(:transform)
367:             transformed_value = processor.transform(name, value)
368:           end
369:         end
370: 
371:         accu[name] = transformed_value
372:         accu
373:       end
374:       result.gsub!(
375:         /#{operator_expansion}|#{variable_expansion}/
376:       ) do |capture|
377:         if capture =~ operator_expansion
378:           operator, argument, variables, default_mapping =
379:             parse_template_expansion(capture, transformed_mapping)
380:           expand_method = "expand_#{operator}_operator"
381:           if ([expand_method, expand_method.to_sym] & private_methods).empty?
382:             raise InvalidTemplateOperatorError,
383:               "Invalid template operator: #{operator}"
384:           else
385:             send(expand_method.to_sym, argument, variables, default_mapping)
386:           end
387:         else
388:           varname, _, vardefault = capture.scan(/^\{(.+?)(=(.*))?\}$/)[0]
389:           transformed_mapping[varname] || vardefault
390:         end
391:       end
392:       return Addressable::URI.parse(result)
393:     end

Extracts uris from an arbitrary body of text.

@param [String, to_str] text

  The body of text to extract URIs from.

@option [String, Addressable::URI, to_str] base

  Causes any relative URIs to be resolved against the base URI.

@option [TrueClass, FalseClass] parse

  If parse is true, all extracted URIs will be parsed.  If parse is
  false, the return value with be an <tt>Array</tt> of <tt>Strings</aa>.
  Defaults to false.

@return [Array] The extracted URIs.

[Source]

      # File lib/addressable/uri.rb, line 1136
1136:     def self.extract(text, options={})
1137:       defaults = {:base => nil, :parse => false}
1138:       options = defaults.merge(options)
1139:       raise InvalidOptionError unless (options.keys - defaults.keys).empty?
1140:       # This regular expression needs to be less forgiving or else it would
1141:       # match virtually all text.  Which isn't exactly what we're going for.
1142:       extract_regex = /((([a-z\+]+):)[^ \n\<\>\"\\]+[\w\/])/
1143:       extracted_uris =
1144:         text.scan(extract_regex).collect { |match| match[0] }
1145:       sgml_extract_regex = /<[^>]+href=\"([^\"]+?)\"[^>]*>/
1146:       sgml_extracted_uris =
1147:         text.scan(sgml_extract_regex).collect { |match| match[0] }
1148:       extracted_uris.concat(sgml_extracted_uris - extracted_uris)
1149:       textile_extract_regex = /\".+?\":([^ ]+\/[^ ]+)[ \,\.\;\:\?\!\<\>\"]/i
1150:       textile_extracted_uris =
1151:         text.scan(textile_extract_regex).collect { |match| match[0] }
1152:       extracted_uris.concat(textile_extracted_uris - extracted_uris)
1153:       parsed_uris = []
1154:       base_uri = nil
1155:       if options[:base] != nil
1156:         base_uri = options[:base] if options[:base].kind_of?(self)
1157:         base_uri = self.parse(options[:base].to_s) if base_uri == nil
1158:       end
1159:       for uri_string in extracted_uris
1160:         begin
1161:           if base_uri == nil
1162:             parsed_uris << self.parse(uri_string)
1163:           else
1164:             parsed_uris << (base_uri + self.parse(uri_string))
1165:           end
1166:         rescue Exception
1167:           nil
1168:         end
1169:       end
1170:       parsed_uris = parsed_uris.select do |uri|
1171:         (self.ip_based_schemes | [
1172:           "file", "git", "svn", "mailto", "tel"
1173:         ]).include?(uri.normalized_scheme)
1174:       end
1175:       if options[:parse]
1176:         return parsed_uris
1177:       else
1178:         return parsed_uris.collect { |uri| uri.to_s }
1179:       end
1180:     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 162
162:     def self.heuristic_parse(uri, hints={})
163:       # If we were given nil, return nil.
164:       return nil unless uri
165:       # If a URI object is passed, just return itself.
166:       return uri if uri.kind_of?(self)
167:       if !uri.respond_to?(:to_str)
168:         raise TypeError, "Can't convert #{uri.class} into String."
169:       end
170:       # Otherwise, convert to a String
171:       uri = uri.to_str.dup
172:       hints = {
173:         :scheme => "http"
174:       }.merge(hints)
175:       case uri
176:       when /^http:\/+/
177:         uri.gsub!(/^http:\/+/, "http://")
178:       when /^feed:\/+http:\/+/
179:         uri.gsub!(/^feed:\/+http:\/+/, "feed:http://")
180:       when /^feed:\/+/
181:         uri.gsub!(/^feed:\/+/, "feed://")
182:       when /^file:\/+/
183:         uri.gsub!(/^file:\/+/, "file:///")
184:       end
185:       parsed = self.parse(uri)
186:       if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/
187:         parsed = self.parse(hints[:scheme] + "://" + uri)
188:       end
189:       if parsed.authority == nil
190:         if parsed.path =~ /^[^\/]+\./
191:           new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
192:           if new_host
193:             new_path = parsed.path.gsub(
194:               Regexp.new("^" + Regexp.escape(new_host)), "")
195:             parsed.host = new_host
196:             parsed.path = new_path
197:             parsed.scheme = hints[:scheme]
198:           end
199:         end
200:       end
201:       return parsed
202:     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 1557
1557:     def self.ip_based_schemes
1558:       return self.port_mapping.keys
1559:     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 903
903:     def self.join(*uris)
904:       uri_objects = uris.collect do |uri|
905:         if !uri.respond_to?(:to_str)
906:           raise TypeError, "Can't convert #{uri.class} into String."
907:         end
908:         uri.kind_of?(self) ? uri : self.parse(uri.to_str)
909:       end
910:       result = uri_objects.shift.dup
911:       for uri in uri_objects
912:         result.join!(uri)
913:       end
914:       return result
915:     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 1201
1201:     def initialize(options={})
1202:       if options.has_key?(:authority)
1203:         if (options.keys & [:userinfo, :user, :password, :host, :port]).any?
1204:           raise ArgumentError,
1205:             "Cannot specify both an authority and any of the components " +
1206:             "within the authority."
1207:         end
1208:       end
1209:       if options.has_key?(:userinfo)
1210:         if (options.keys & [:user, :password]).any?
1211:           raise ArgumentError,
1212:             "Cannot specify both a userinfo and either the user or password."
1213:         end
1214:       end
1215: 
1216:       self.validation_deferred = true
1217:       self.scheme = options[:scheme] if options[:scheme]
1218:       self.user = options[:user] if options[:user]
1219:       self.password = options[:password] if options[:password]
1220:       self.userinfo = options[:userinfo] if options[:userinfo]
1221:       self.host = options[:host] if options[:host]
1222:       self.port = options[:port] if options[:port]
1223:       self.authority = options[:authority] if options[:authority]
1224:       self.path = options[:path] if options[:path]
1225:       self.query = options[:query] if options[:query]
1226:       self.fragment = options[:fragment] if options[:fragment]
1227:       self.validation_deferred = false
1228:     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 1074
1074:     def self.normalized_encode(uri, returning=String)
1075:       if !uri.respond_to?(:to_str)
1076:         raise TypeError, "Can't convert #{uri.class} into String."
1077:       end
1078:       if ![String, ::Addressable::URI].include?(returning)
1079:         raise TypeError,
1080:           "Expected String or Addressable::URI, got #{returning.inspect}"
1081:       end
1082:       uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
1083:       components = {
1084:         :scheme => self.unencode_component(uri_object.scheme),
1085:         :user => self.unencode_component(uri_object.user),
1086:         :password => self.unencode_component(uri_object.password),
1087:         :host => self.unencode_component(uri_object.host),
1088:         :port => uri_object.port,
1089:         :path => self.unencode_component(uri_object.path),
1090:         :query => self.unencode_component(uri_object.query),
1091:         :fragment => self.unencode_component(uri_object.fragment)
1092:       }
1093:       components.each do |key, value|
1094:         if value != nil
1095:           components[key] = Addressable::IDNA.unicode_normalize_kc(value.to_s)
1096:         end
1097:       end
1098:       encoded_uri = Addressable::URI.new(
1099:         :scheme => self.encode_component(components[:scheme],
1100:           Addressable::URI::CharacterClasses::SCHEME),
1101:         :user => self.encode_component(components[:user],
1102:           Addressable::URI::CharacterClasses::AUTHORITY),
1103:         :password => self.encode_component(components[:password],
1104:           Addressable::URI::CharacterClasses::AUTHORITY),
1105:         :host => components[:host],
1106:         :port => components[:port],
1107:         :path => self.encode_component(components[:path],
1108:           Addressable::URI::CharacterClasses::PATH),
1109:         :query => self.encode_component(components[:query],
1110:           Addressable::URI::CharacterClasses::QUERY),
1111:         :fragment => self.encode_component(components[:fragment],
1112:           Addressable::URI::CharacterClasses::FRAGMENT)
1113:       )
1114:       if returning == String
1115:         return encoded_uri.to_s
1116:       elsif returning == ::Addressable::URI
1117:         return encoded_uri
1118:       end
1119:     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 88
 88:     def self.parse(uri)
 89:       # If we were given nil, return nil.
 90:       return nil unless uri
 91:       # If a URI object is passed, just return itself.
 92:       return uri if uri.kind_of?(self)
 93:       if !uri.respond_to?(:to_str)
 94:         raise TypeError, "Can't convert #{uri.class} into String."
 95:       end
 96:       # Otherwise, convert to a String
 97:       uri = uri.to_str
 98: 
 99:       # If a URI object of the Ruby standard library variety is passed,
100:       # convert it to a string, then parse the string.
101:       # We do the check this way because we don't want to accidentally
102:       # cause a missing constant exception to be thrown.
103:       if uri.class.name =~ /^URI\b/
104:         uri = uri.to_s
105:       end
106: 
107:       # This Regexp supplied as an example in RFC 3986, and it works great.
108:       uri_regex =
109:         /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/
110:       scan = uri.scan(uri_regex)
111:       fragments = scan[0]
112:       return nil if fragments.nil?
113:       scheme = fragments[1]
114:       authority = fragments[3]
115:       path = fragments[4]
116:       query = fragments[6]
117:       fragment = fragments[8]
118:       userinfo = nil
119:       user = nil
120:       password = nil
121:       host = nil
122:       port = nil
123:       if authority != nil
124:         # The Regexp above doesn't split apart the authority.
125:         userinfo = authority[/^([^\[\]]*)@/, 1]
126:         if userinfo != nil
127:           user = userinfo.strip[/^([^:]*):?/, 1]
128:           password = userinfo.strip[/:(.*)$/, 1]
129:         end
130:         host = authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
131:         port = authority[/:([^:@\[\]]*?)$/, 1]
132:       end
133:       if port == ""
134:         port = nil
135:       end
136: 
137:       return Addressable::URI.new(
138:         :scheme => scheme,
139:         :user => user,
140:         :password => password,
141:         :host => host,
142:         :port => port,
143:         :path => path,
144:         :query => query,
145:         :fragment => fragment
146:       )
147:     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 1564
1564:     def self.port_mapping
1565:       @port_mapping ||= {
1566:         "http" => 80,
1567:         "https" => 443,
1568:         "ftp" => 21,
1569:         "tftp" => 69,
1570:         "sftp" => 22,
1571:         "ssh" => 22,
1572:         "svn+ssh" => 22,
1573:         "telnet" => 23,
1574:         "nntp" => 119,
1575:         "gopher" => 70,
1576:         "wais" => 210,
1577:         "ldap" => 389,
1578:         "prospero" => 1525
1579:       }
1580:     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 986
 986:     def self.unencode(uri, returning=String)
 987:       return nil if uri.nil?
 988:       if !uri.respond_to?(:to_str)
 989:         raise TypeError, "Can't convert #{uri.class} into String."
 990:       end
 991:       if ![String, ::Addressable::URI].include?(returning)
 992:         raise TypeError,
 993:           "Expected String or Addressable::URI, got #{returning.inspect}"
 994:       end
 995:       result = uri.to_str.gsub(/%[0-9a-f]{2}/i) do |sequence|
 996:         sequence[1..3].to_i(16).chr
 997:       end
 998:       result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
 999:       if returning == String
1000:         return result
1001:       elsif returning == ::Addressable::URI
1002:         return ::Addressable::URI.parse(result)
1003:       end
1004:     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 2240
2240:     def ==(uri)
2241:       return false unless uri.kind_of?(self.class)
2242:       return self.normalize.to_s == uri.normalize.to_s
2243:     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 2219
2219:     def ===(uri)
2220:       if uri.respond_to?(:normalize)
2221:         uri_string = uri.normalize.to_s
2222:       else
2223:         begin
2224:           uri_string = ::Addressable::URI.parse(uri).normalize.to_s
2225:         rescue InvalidURIError, TypeError
2226:           return false
2227:         end
2228:       end
2229:       return self.normalize.to_s == uri_string
2230:     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 1887
1887:     def absolute?
1888:       return !relative?
1889:     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 1481
1481:     def authority
1482:       @authority ||= (begin
1483:         if self.host.nil?
1484:           nil
1485:         else
1486:           authority = ""
1487:           if self.userinfo != nil
1488:             authority << "#{self.userinfo}@"
1489:           end
1490:           authority << self.host
1491:           if self.port != nil
1492:             authority << ":#{self.port}"
1493:           end
1494:           authority
1495:         end
1496:       end)
1497:     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 1525
1525:     def authority=(new_authority)
1526:       if new_authority
1527:         new_authority = new_authority.to_str
1528:         new_userinfo = new_authority[/^([^\[\]]*)@/, 1]
1529:         if new_userinfo
1530:           new_user = new_userinfo.strip[/^([^:]*):?/, 1]
1531:           new_password = new_userinfo.strip[/:(.*)$/, 1]
1532:         end
1533:         new_host =
1534:           new_authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
1535:         new_port =
1536:           new_authority[/:([^:@\[\]]*?)$/, 1]
1537:       end
1538: 
1539:       # Password assigned first to ensure validity in case of nil
1540:       self.password = new_password
1541:       self.user = new_user
1542:       self.host = new_host
1543:       self.port = new_port
1544: 
1545:       # Reset dependant values
1546:       @inferred_port = nil
1547:       @userinfo = nil
1548:       @normalized_userinfo = nil
1549: 
1550:       # Ensure we haven't created an invalid URI
1551:       validate()
1552:     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 1689
1689:     def basename
1690:       # Path cannot be nil
1691:       return File.basename(self.path).gsub(/;[^\/]*$/, "")
1692:     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 2203
2203:     def display_uri
2204:       display_uri = self.normalize
2205:       display_uri.instance_variable_set("@host",
2206:         ::Addressable::IDNA.to_unicode(display_uri.host))
2207:       return display_uri
2208:     end

Clones the URI object.

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

[Source]

      # File lib/addressable/uri.rb, line 2271
2271:     def dup
2272:       duplicated_uri = Addressable::URI.new(
2273:         :scheme => self.scheme ? self.scheme.dup : nil,
2274:         :user => self.user ? self.user.dup : nil,
2275:         :password => self.password ? self.password.dup : nil,
2276:         :host => self.host ? self.host.dup : nil,
2277:         :port => self.port,
2278:         :path => self.path ? self.path.dup : nil,
2279:         :query => self.query ? self.query.dup : nil,
2280:         :fragment => self.fragment ? self.fragment.dup : nil
2281:       )
2282:       return duplicated_uri
2283:     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 2253
2253:     def eql?(uri)
2254:       return false unless uri.kind_of?(self.class)
2255:       return self.to_s == uri.to_s
2256:     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 1699
1699:     def extname
1700:       return nil unless self.path
1701:       return File.extname(self.basename)
1702:     end

Extracts a mapping from the URI using a URI Template pattern.

@param [String] pattern

  A URI template pattern.

@param [restore, match] processor

  A template processor object may optionally be supplied.
  The object should respond to either the <tt>restore</tt> or
  <tt>match</tt> messages or both.  The <tt>restore</tt> method should
  take two parameters: [String] name and [String] value.  The
  <tt>restore</tt> method should reverse any transformations that have
  been performed on the value to ensure a valid URI.  The
  <tt>match</tt> method should take a single parameter: [String] name.
  The <tt>match</tt> method should return a <tt>String</tt> containing
  a regular expression capture group for matching on that particular
  variable.  The default value is ".*?".  The <tt>match</tt> method has
  no effect on multivariate operator expansions.

@return [Hash, NilClass]

  The <tt>Hash</tt> mapping that was extracted from the URI, or
  <tt>nil</tt> if the URI didn't match the template.

@example

  class ExampleProcessor
    def self.restore(name, value)
      return value.gsub(/\+/, " ") if name == "query"
      return value
    end

    def self.match(name)
      return ".*?" if name == "first"
      return ".*"
    end
  end

  uri = Addressable::URI.parse(
    "http://example.com/search/an+example+search+query/"
  )
  uri.extract_mapping(
    "http://example.com/search/{query}/",
    ExampleProcessor
  )
  #=> {"query" => "an example search query"}

  uri = Addressable::URI.parse("http://example.com/a/b/c/")
  uri.extract_mapping(
    "http://example.com/{first}/{second}/",
    ExampleProcessor
  )
  #=> {"first" => "a", "second" => "b/c"}

  uri = Addressable::URI.parse("http://example.com/a/b/c/")
  uri.extract_mapping(
    "http://example.com/{first}/{-list|/|second}/"
  )
  #=> {"first" => "a", "second" => ["b", "c"]}

[Source]