W3cubDocs

/Crystal

class URI

Overview

This class represents a URI reference as defined by RFC 3986: Uniform Resource Identifier (URI): Generic Syntax.

This class provides constructors for creating URI instances from their components or by parsing their string forms and methods for accessing the various components of an instance.

Basic example:

require "uri"

uri = URI.parse "http://foo.com/posts?id=30&limit=5#time=1305298413"
# => #<URI:0x1003f1e40 @scheme="http", @host="foo.com", @port=nil, @path="/posts", @query="id=30&limit=5", ... >
uri.scheme # => "http"
uri.host   # => "foo.com"
uri.query  # => "id=30&limit=5"
uri.to_s   # => "http://foo.com/posts?id=30&limit=5#time=1305298413"

Resolution and Relativization

Resolution is the process of resolving one URI against another, base URI. The resulting URI is constructed from components of both URIs in the manner specified by RFC 3986 section 5.2, taking components from the base URI for those not specified in the original. For hierarchical URIs, the path of the original is resolved against the path of the base and then normalized. See #resolve for examples.

Relativization is the inverse of resolution as that it procudes an URI that resolves to the original when resolved against the base.

For normalized URIs, the following is true:

a.relativize(a.resolve(b)) # => b
a.resolve(a.relativize(b)) # => b

This operation is often useful when constructing a document containing URIs that must be made relative to the base URI of the document wherever possible.

URL Encoding

This class provides a number of methods for encoding and decoding strings using URL Encoding (also known as Percent Encoding) as defined in RFC 3986 as well as x-www-form-urlencoded.

Each method has two variants, one returns a string, the other writes directly to an IO.

The main difference is that .encode_www_form encodes reserved characters (see .reserved?), while .encode does not. The decode methods are identical except for the handling of + characters.

NOTE HTTP::Params provides a higher-level API for handling x-www-form-urlencoded serialized data.

Defined in:

uri.cr
uri/encoding.cr
uri/punycode.cr
uri/uri_parser.cr

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.new(scheme = nil, host = nil, port = nil, path = "", query = nil, user = nil, password = nil, fragment = nil)Source

def self.parse(raw_url : String) : URISource

Parses the given raw_url into an URI. The raw_url may be relative or absolute.

require "uri"

uri = URI.parse("http://crystal-lang.org") # => #<URI:0x1068a7e40 @scheme="http", @host="crystal-lang.org", ... >
uri.scheme                                 # => "http"
uri.host                                   # => "crystal-lang.org"

Class Method Detail

def self.decode(string : String, io : IO, *, plus_to_space : Bool = false) : NilSource

URL-decodes a string and writes the result to io.

See .decode(string : String, *, plus_to_space : Bool = false) : String for details.

def self.decode(string : String, *, plus_to_space : Bool = false) : StringSource

URL-decodes string.

require "uri"

URI.decode("hello%20world!")                                 # => "hello world!"
URI.decode("put:%20it+%D0%B9")                               # => "put: it+й"
URI.decode("http://example.com/Crystal%20is%20awesome%20=)") # => "http://example.com/Crystal is awesome =)"

By default, + is decoded literally. If plus_to_space is true, + is decoded as space character (0x20). Percent-encoded values such as %20 and %2B are always decoded as characters with the respective codepoint.

require "uri"

URI.decode("peter+%2B+paul")                      # => "peter+++paul"
URI.decode("peter+%2B+paul", plus_to_space: true) # => "peter + paul"

def self.decode(string : String, io : IO, *, plus_to_space : Bool = false, &) : NilSource

URL-decodes string and writes the result to io.

The block is called for each percent-encoded ASCII character and determines whether the value is to be decoded. When the return value is falsey, the character is decoded. Non-ASCII characters are always decoded.

By default, + is decoded literally. If plus_to_space is true, + is decoded as space character (0x20).

This method enables some customization, but typical use cases can be implemented by either .decode(string : String, *, plus_to_space : Bool = false) : String or .deode_www_form(string : String, *, plus_to_space : Bool = true) : String.

def self.decode_www_form(string : String, io : IO, *, plus_to_space : Bool = true) : NilSource

URL-decodes string as x-www-form-urlencoded and writes the result to io.

See self.decode_www_form(string : String, *, plus_to_space : Bool = true) : String for details.

def self.decode_www_form(string : String, *, plus_to_space : Bool = true) : StringSource

URL-decodes string as x-www-form-urlencoded.

require "uri"

URI.decode_www_form("hello%20world!")                           # => "hello world!"
URI.decode_www_form("put:%20it+%D0%B9")                         # => "put: it й"
URI.decode_www_form("http://example.com/Crystal+is+awesome+=)") # => "http://example.com/Crystal is awesome =)"

By default, + is decoded as space character (0x20). If plus_to_space is false, + is decoded literally as +. Percent-encoded values such as %20 and %2B are always decoded as characters with the respective codepoint.

require "uri"

URI.decode_www_form("peter+%2B+paul")                       # => "peter + paul"
URI.decode_www_form("peter+%2B+paul", plus_to_space: false) # => "peter+++paul"

def self.default_port(scheme : String) : Int32?Source

Returns the default port for the given scheme if known, otherwise returns nil.

require "uri"

URI.default_port "http"  # => 80
URI.default_port "ponzi" # => nil

def self.encode(string : String, io : IO, *, space_to_plus : Bool = false) : NilSource

URL-encodes string and writes the result to io.

See .encode(string : String, *, space_to_plus : Bool = false) : String for details.

def self.encode(string : String, *, space_to_plus : Bool = false) : StringSource

URL-encodes string.

Reserved and unreserved characters are not escaped, so this only modifies some special characters as well as non-ASCII characters. .reserved? and .unreserved? provide more details on these character classes.

require "uri"

URI.encode("hello world!")                             # => "hello%20world!"
URI.encode("put: it+й")                                # => "put:%20it+%D0%B9"
URI.encode("http://example.com/Crystal is awesome =)") # => "http://example.com/Crystal%20is%20awesome%20=)"

By default, the space character (0x20) is encoded as %20 and + is encoded literally. If space_to_plus is true, space character is encoded as + and + is encoded as %2B:

require "uri"

URI.encode("peter + paul")                      # => "peter%20+%20paul"
URI.encode("peter + paul", space_to_plus: true) # => "peter+%2B+paul"

def self.encode(string : String, io : IO, space_to_plus : Bool = false, &) : NilSource

URL-encodes string and writes the result to an IO.

The block is called for each ascii character (codepoint less than 0x80) and determines whether the value is to be encoded. When the return value is falsey, the character is encoded. Non-ASCII characters are always encoded.

By default, the space character (0x20) is encoded as %20 and + is encoded literally. If space_to_plus is true, space character is encoded as + and + is encoded as %2B.

This method enables some customization, but typical use cases can be implemented by either .encode(string : String, *, space_to_plus : Bool = false) : String or .encode_www_form(string : String, *, space_to_plus : Bool = true) : String.

def self.encode_www_form(string : String, io : IO, *, space_to_plus : Bool = true) : NilSource

URL-encodes string as x-www-form-urlencoded and writes the result to io.

See .encode_www_form(string : String, *, space_to_plus : Bool = true) for details.

def self.encode_www_form(string : String, *, space_to_plus : Bool = true) : StringSource

URL-encodes string as x-www-form-urlencoded.

Reserved characters are escaped, unreserved characters are not. .reserved? and .unreserved? provide more details on these character classes.

require "uri"

URI.encode_www_form("hello world!")                             # => "hello+world%21"
URI.encode_www_form("put: it+й")                                # => "put%3A+it%2B%D0%B9"
URI.encode_www_form("http://example.com/Crystal is awesome =)") # => "http%3A%2F%2Fexample.com%2FCrystal+is+awesome+%3D%29"

The encoded string returned from this method can be used as name or value components for a application/x-www-form-urlencoded format serialization. HTTP::Params provides a higher-level API for this use case.

By default, the space character (0x20) is encoded as + and + is encoded as %2B. If space_to_plus is false, space character is encoded as %20 and '+' is encoded literally.

require "uri"

URI.encode_www_form("peter + paul")                       # => "peter+%2B+paul"
URI.encode_www_form("peter + paul", space_to_plus: false) # => "peter%20%2B%20paul"

def self.reserved?(byte) : BoolSource

Returns whether given byte is reserved character defined in RFC 3986.

Reserved characters are ':', '/', '?', '#', '[', ']', '@', '!', '$', '&', "'", '(', ')', '*', '+', ',', ';' and '='.

def self.set_default_port(scheme : String, port : Int32?) : NilSource

Registers the default port for the given scheme.

If port is nil, the existing default port for the scheme, if any, will be unregistered.

require "uri"

URI.set_default_port "ponzi", 9999

def self.unreserved?(byte) : BoolSource

Returns whether given byte is unreserved character defined in RFC 3986.

Unreserved characters are ASCII letters, ASCII digits, _, ., - and ~.

Instance Method Detail

def ==(other : self)

Description copied from class Reference

Returns true if this reference is the same as other. Invokes same?.

def absolute? : BoolSource

Returns true if URI has a scheme specified.

def fragment : String?Source

Returns the fragment component of the URI.

require "uri"

URI.parse("http://foo.com/bar#section1").fragment # => "section1"

def fragment=(fragment : String?)Source

Sets the fragment component of the URI.

def full_path : StringSource

Returns the full path of this URI.

require "uri"

uri = URI.parse "http://foo.com/posts?id=30&limit=5#time=1305298413"
uri.full_path # => "/posts?id=30&limit=5"

def hash(hasher)

Description copied from class Reference

See Object#hash(hasher)

def host : String?Source

Returns the host component of the URI.

require "uri"

URI.parse("http://foo.com").host # => "foo.com"

def host=(host : String?)Source

Sets the host component of the URI.

def hostnameSource

Returns the host part of the URI and unwrap brackets for IPv6 addresses.

require "uri"

URI.parse("http://[::1]/bar").hostname # => "::1"
URI.parse("http://[::1]/bar").host     # => "[::1]"

def normalize : URISource

Returns a normalized copy of this URI.

See #normalize! for details.

def normalize! : URISource

Normalizes this URI instance.

The following normalizations are applied to the individual components (if available):

  • #scheme is lowercased.
  • #host is lowercased.
  • #port is removed if it is the .default_port? of the scheme.
  • #path is resolved to a minimal, semantical equivalent representation removing dot segments /. and /...
uri = URI.parse("HTTP://example.COM:80/./foo/../bar/")
uri.normalize!
uri # => "http://example.com/bar/"

def opaque? : BoolSource

Returns true if this URI is opaque.

A URI is considered opaque if it has a #scheme but no hierarchical part, i.e. no #host and the first character of #path is not a slash (/).

def password : String?Source

Returns the password component of the URI.

require "uri"

URI.parse("http://admin:[email protected]").password # => "password"

def password=(password : String?)Source

Sets the password component of the URI.

def path : StringSource

Returns the path component of the URI.

require "uri"

URI.parse("http://foo.com/bar").path # => "/bar"

def path=(path : String)Source

Sets the path component of the URI.

def port : Int32?Source

Returns the port component of the URI.

require "uri"

URI.parse("http://foo.com:5432").port # => 5432

def port=(port : Int32?)Source

Sets the port component of the URI.

def query : String?Source

Returns the query component of the URI.

require "uri"

URI.parse("http://foo.com/bar?q=1").query # => "q=1"

def query=(query : String?)Source

Sets the query component of the URI.

def query_params : HTTP::ParamsSource

Returns a HTTP::Params of the URI#query.

require "uri"

uri = URI.parse "http://foo.com?id=30&limit=5#time=1305298413"
uri.query_params # => HTTP::Params(@raw_params={"id" => ["30"], "limit" => ["5"]})

def relative? : BoolSource

Returns true if URI does not have a scheme specified.

def relativize(uri : URI | String) : URISource

Relativizes uri against this URI.

An exact copy of uri is returned if

Otherwise a new relative hierarchical URI is constructed with #query and #fragment components from uri and with a path component that describes a minimum-difference relative path from #path to uri's path.

URI.parse("http://foo.com/bar/baz").relativize("http://foo.com/quux")         # => "../quux"
URI.parse("http://foo.com/bar/baz").relativize("http://foo.com/bar/quux")     # => "quux"
URI.parse("http://foo.com/bar/baz").relativize("http://quux.com")             # => "http://quux.com"
URI.parse("http://foo.com/bar/baz").relativize("http://foo.com/bar/baz#quux") # => "#quux"

This method is the inverse operation to #resolve (see Resolution and Relativization).

def resolve(uri : URI | String) : URISource

Resolves uri against this URI.

If uri is #absolute?, or if this URI is #opaque?, then an exact copy of uri is returned.

Otherwise the URI is resolved according to the specifications in RFC 3986 section 5.2.

URI.parse("http://foo.com/bar/baz").resolve("../quux")         # => "http://foo.com/quux"
URI.parse("http://foo.com/bar/baz").resolve("/quux")           # => "http://foo.com/quux"
URI.parse("http://foo.com/bar/baz").resolve("http://quux.com") # => "http://quux.com"
URI.parse("http://foo.com/bar/baz").resolve("#quux")           # => "http://foo.com/bar/baz#quux"

This method is the inverse operation to #relativize (see Resolution and Relativization).

def scheme : String?Source

Returns the scheme component of the URI.

require "uri"

URI.parse("http://foo.com").scheme           # => "http"
URI.parse("mailto:[email protected]").scheme # => "mailto"

def scheme=(scheme : String?)Source

Sets the scheme component of the URI.

def to_s(io : IO) : NilSource

Description copied from class Reference

Appends a short String representation of this object which includes its class name and its object address.

class Person
  def initialize(@name : String, @age : Int32)
  end
end

Person.new("John", 32).to_s # => #<Person:0x10a199f20>

def user : String?Source

Returns the user component of the URI.

require "uri"

URI.parse("http://admin:[email protected]").user # => "admin"

def user=(user : String?)Source

Sets the user component of the URI.

def userinfoSource

Returns the user-information component containing the provided username and password.

require "uri"

uri = URI.parse "http://admin:[email protected]"
uri.userinfo # => "admin:password"

The return value is URL encoded (see #encode_www_form).

© 2012–2020 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/0.35.1/URI.html