View Source URI (Elixir v1.11.4)
Utilities for working with URIs.
This module provides functions for working with URIs (for example, parsing URIs or encoding query strings). The functions in this module are implemented according to RFC 3986.
Link to this section Summary
Functions
Checks if character is a reserved one in a URI.
Checks if character is allowed unescaped in a URI.
Checks if character is an unreserved one in a URI.
Percent-unescapes a URI.
Decodes a query string into a map.
Decodes string as "x-www-form-urlencoded".
Returns the default port for a given scheme.
Registers the default port for the given scheme.
Percent-escapes all characters that require escaping in string.
Encodes an enumerable into a query string.
Encodes string as "x-www-form-urlencoded".
Merges two URIs.
Parses a well-formed URI reference into its components.
Returns a stream of two-element tuples representing key-value pairs in the
given query.
Returns the string representation of the given URI struct.
Link to this section Types
Link to this section Functions
Checks if character is a reserved one in a URI.
As specified in RFC 3986, section 2.2,
the following characters are reserved: :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ;, =
Examples
iex> URI.char_reserved?(?+)
true
Checks if character is allowed unescaped in a URI.
This is the default used by URI.encode/2 where both
reserved and unreserved characters
are kept unescaped.
Examples
iex> URI.char_unescaped?(?{)
false
Checks if character is an unreserved one in a URI.
As specified in RFC 3986, section 2.3, the following characters are unreserved:
- Alphanumeric characters:
A-Z,a-z,0-9 ~,_,-,.
Examples
iex> URI.char_unreserved?(?_)
true
Percent-unescapes a URI.
Examples
iex> URI.decode("https%3A%2F%2Felixir-lang.org")
"https://elixir-lang.org"
@spec decode_query(binary(), %{optional(binary()) => binary()}) :: %{ optional(binary()) => binary() }
Decodes a query string into a map.
Given a query string in the form of key1=value1&key2=value2..., this
function inserts each key-value pair in the query string as one entry in the
given map. Keys and values in the resulting map will be binaries. Keys and
values will be percent-unescaped.
Use query_decoder/1 if you want to iterate over each value manually.
Examples
iex> URI.decode_query("foo=1&bar=2")
%{"bar" => "2", "foo" => "1"}
iex> URI.decode_query("percent=oh+yes%21", %{"starting" => "map"})
%{"percent" => "oh yes!", "starting" => "map"}
Decodes string as "x-www-form-urlencoded".
Examples
iex> URI.decode_www_form("%3Call+in%2F")
"<all in/"
@spec default_port(binary()) :: nil | non_neg_integer()
Returns the default port for a given scheme.
If the scheme is unknown to the URI module, this function returns
nil. The default port for any scheme can be configured globally
via default_port/2.
Examples
iex> URI.default_port("ftp")
21
iex> URI.default_port("ponzi")
nil
@spec default_port(binary(), non_neg_integer()) :: :ok
Registers the default port for the given scheme.
After this function is called, port will be returned by
default_port/1 for the given scheme scheme. Note that this function
changes the default port for the given scheme globally, meaning for
every application.
It is recommended for this function to be invoked in your application's start callback in case you want to register new URIs.
@spec encode(binary(), (byte() -> as_boolean(term()))) :: binary()
Percent-escapes all characters that require escaping in string.
This means reserved characters, such as : and /, and the
so-called unreserved characters, which have the same meaning both
escaped and unescaped, won't be escaped by default.
See encode_www_form/1 if you are interested in escaping reserved
characters too.
This function also accepts a predicate function as an optional
argument. If passed, this function will be called with each byte
in string as its argument and should return a truthy value (anything other
than false or nil) if the given byte should be left as is, or return a
falsy value (false or nil) if the character should be escaped. Defaults
to URI.char_unescaped?/1.
Examples
iex> URI.encode("ftp://s-ite.tld/?value=put it+й")
"ftp://s-ite.tld/?value=put%20it+%D0%B9"
iex> URI.encode("a string", &(&1 != ?i))
"a str%69ng"
Encodes an enumerable into a query string.
Takes an enumerable that enumerates as a list of two-element
tuples (for instance, a map or a keyword list) and returns a string
in the form of key1=value1&key2=value2... where keys and
values are URL encoded as per encode_www_form/1.
Keys and values can be any term that implements the String.Chars
protocol with the exception of lists, which are explicitly forbidden.
Examples
iex> hd = %{"foo" => 1, "bar" => 2}
iex> URI.encode_query(hd)
"bar=2&foo=1"
iex> query = %{"key" => "value with spaces"}
iex> URI.encode_query(query)
"key=value+with+spaces"
iex> URI.encode_query(%{key: [:a, :list]})
** (ArgumentError) encode_query/1 values cannot be lists, got: [:a, :list]
Encodes string as "x-www-form-urlencoded".
Example
iex> URI.encode_www_form("put: it+й")
"put%3A+it%2B%D0%B9"
Merges two URIs.
This function merges two URIs as per RFC 3986, section 5.2.
Examples
iex> URI.merge(URI.parse("http://google.com"), "/query") |> to_string()
"http://google.com/query"
iex> URI.merge("http://example.com", "http://google.com") |> to_string()
"http://google.com"
Parses a well-formed URI reference into its components.
Note this function expects a well-formed URI and does not perform
any validation. See the "Examples" section below for examples of how
URI.parse/1 can be used to parse a wide range of URIs.
This function uses the parsing regular expression as defined in RFC 3986, Appendix B.
When a URI is given without a port, the value returned by
URI.default_port/1 for the URI's scheme is used for the :port field.
If a %URI{} struct is given to this function, this function returns it
unmodified.
Examples
iex> URI.parse("https://elixir-lang.org/")
%URI{
authority: "elixir-lang.org",
fragment: nil,
host: "elixir-lang.org",
path: "/",
port: 443,
query: nil,
scheme: "https",
userinfo: nil
}
iex> URI.parse("//elixir-lang.org/")
%URI{
authority: "elixir-lang.org",
fragment: nil,
host: "elixir-lang.org",
path: "/",
port: nil,
query: nil,
scheme: nil,
userinfo: nil
}
iex> URI.parse("/foo/bar")
%URI{
authority: nil,
fragment: nil,
host: nil,
path: "/foo/bar",
port: nil,
query: nil,
scheme: nil,
userinfo: nil
}
iex> URI.parse("foo/bar")
%URI{
authority: nil,
fragment: nil,
host: nil,
path: "foo/bar",
port: nil,
query: nil,
scheme: nil,
userinfo: nil
}
@spec query_decoder(binary()) :: Enumerable.t()
Returns a stream of two-element tuples representing key-value pairs in the
given query.
Key and value in each tuple will be binaries and will be percent-unescaped.
Examples
iex> URI.query_decoder("foo=1&bar=2") |> Enum.to_list()
[{"foo", "1"}, {"bar", "2"}]
iex> URI.query_decoder("food=bread%26butter&drinks=tap%20water") |> Enum.to_list()
[{"food", "bread&butter"}, {"drinks", "tap water"}]
Returns the string representation of the given URI struct.
Examples
iex> uri = URI.parse("http://google.com")
iex> URI.to_string(uri)
"http://google.com"
iex> uri = URI.parse("foo://bar.baz")
iex> URI.to_string(uri)
"foo://bar.baz"Note that when creating this string representation, the :authority value will be
used if the :host is nil. Otherwise, the :userinfo, :host, and :port will
be used.
iex> URI.to_string(%URI{authority: "foo@example.com:80"})
"//foo@example.com:80"
iex> URI.to_string(%URI{userinfo: "bar", host: "example.org", port: 81})
"//bar@example.org:81"
iex> URI.to_string(%URI{
...> authority: "foo@example.com:80",
...> userinfo: "bar",
...> host: "example.org",
...> port: 81
...> })
"//bar@example.org:81"