URI
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.
Summary
Types
Functions
- char_reserved?(character)
Checks if
character
is a reserved one in a URI.- char_unescaped?(character)
Checks if
character
is allowed unescaped in a URI.- char_unreserved?(character)
Checks if
character
is an unreserved one in a URI.- decode(uri)
Percent-unescapes a URI.
- decode_query(query, map \\ %{}, encoding \\ :www_form)
Decodes
query
into a map.- decode_www_form(string)
Decodes
string
as "x-www-form-urlencoded".- default_port(scheme)
Returns the default port for a given
scheme
.- default_port(scheme, port)
Registers the default
port
for the givenscheme
.- encode(string, predicate \\ &char_unescaped?/1)
Percent-escapes all characters that require escaping in
string
.- encode_query(enumerable, encoding \\ :www_form)
Encodes
enumerable
into a query string usingencoding
.- encode_www_form(string)
Encodes
string
as "x-www-form-urlencoded".- merge(uri, rel)
Merges two URIs.
- parse(uri)
Parses a well-formed URI into its components.
- query_decoder(query, encoding \\ :www_form)
Returns a stream of two-element tuples representing key-value pairs in the given
query
.- to_string(uri)
Returns the string representation of the given URI struct.
Types
t()Source
Specs
t() :: %URI{ authority: nil | binary(), fragment: nil | binary(), host: nil | binary(), path: nil | binary(), port: nil | :inet.port_number(), query: nil | binary(), scheme: nil | binary(), userinfo: nil | binary() }
Functions
char_reserved?(character)Source
Specs
char_reserved?(byte()) :: boolean()
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
char_unescaped?(character)Source
Specs
char_unescaped?(byte()) :: boolean()
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
char_unreserved?(character)Source
Specs
char_unreserved?(byte()) :: boolean()
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
decode(uri)Source
Specs
decode(binary()) :: binary()
Percent-unescapes a URI.
Examples
iex> URI.decode("https%3A%2F%2Felixir-lang.org") "https://elixir-lang.org"
decode_query(query, map \\ %{}, encoding \\ :www_form)Source
Specs
decode_query(binary(), %{optional(binary()) => binary()}, :rfc3986 | :www_form) :: %{optional(binary()) => binary()}
Decodes query
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.
You can specify one of the following encoding
options:
:www_form
- (default, since v1.12.0) keys and values are decoded as perdecode_www_form/1
. This is the format typically used by browsers on query strings and form data. It decodes "+" as " ".:rfc3986
- (since v1.12.0) keys and values are decoded as perdecode/1
. The result is the same as:www_form
except for leaving "+" as is in line with RFC 3986.
Encoding defaults to :www_form
for backward compatibility.
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"} iex> URI.decode_query("percent=oh+yes%21", %{}, :rfc3986) %{"percent" => "oh+yes!"}
decode_www_form(string)Source
Specs
decode_www_form(binary()) :: binary()
Decodes string
as "x-www-form-urlencoded".
Note "x-www-form-urlencoded" is not specified as part of RFC 3986. However, it is a commonly used format to encode query strings and form data by browsers.
Examples
iex> URI.decode_www_form("%3Call+in%2F") "<all in/"
default_port(scheme)Source
Specs
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
default_port(scheme, port)Source
Specs
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.
encode(string, predicate \\ &char_unescaped?/1)Source
Specs
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"
encode_query(enumerable, encoding \\ :www_form)Source
Specs
encode_query(Enum.t(), :rfc3986 | :www_form) :: binary()
Encodes enumerable
into a query string using encoding
.
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...
.
Keys and values can be any term that implements the String.Chars
protocol with the exception of lists, which are explicitly forbidden.
You can specify one of the following encoding
strategies:
:www_form
- (default, since v1.12.0) keys and values are URL encoded as perencode_www_form/1
. This is the format typically used by browsers on query strings and form data. It encodes " " as "+".:rfc3986
- (since v1.12.0) the same as:www_form
except it encodes " " as "%20" according RFC 3986. This is the best option if you are encoding in a non-browser situation, since encoding spaces as "+" can be ambiguous to URI parsers. This can inadvertently lead to spaces being interpreted as literal plus signs.
Encoding defaults to :www_form
for backward compatibility.
Examples
iex> query = %{"foo" => 1, "bar" => 2} iex> URI.encode_query(query) "bar=2&foo=1" iex> query = %{"key" => "value with spaces"} iex> URI.encode_query(query) "key=value+with+spaces" iex> query = %{"key" => "value with spaces"} iex> URI.encode_query(query, :rfc3986) "key=value%20with%20spaces" iex> URI.encode_query(%{key: [:a, :list]}) ** (ArgumentError) encode_query/2 values cannot be lists, got: [:a, :list]
encode_www_form(string)Source
Specs
encode_www_form(binary()) :: binary()
Encodes string
as "x-www-form-urlencoded".
Note "x-www-form-urlencoded" is not specified as part of RFC 3986. However, it is a commonly used format to encode query strings and form data by browsers.
Example
iex> URI.encode_www_form("put: it+й") "put%3A+it%2B%D0%B9"
merge(uri, rel)Source
Specs
merge(t() | binary(), t() | binary()) :: t()
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"
parse(uri)Source
Specs
parse(t() | binary()) :: t()
Parses a well-formed URI into its components.
This function can parse both absolute and relative URLs. You can check if a URI is absolute or relative by checking if the scheme
field is nil or not. Furthermore, this function expects both absolute and relative URIs to be well-formed and does not perform any validation. See the "Examples" section below.
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 }
query_decoder(query, encoding \\ :www_form)Source
Specs
query_decoder(binary(), :rfc3986 | :www_form) :: 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.
You can specify one of the following encoding
options:
:www_form
- (default, since v1.12.0) keys and values are decoded as perdecode_www_form/1
. This is the format typically used by browsers on query strings and form data. It decodes "+" as " ".:rfc3986
- (since v1.12.0) keys and values are decoded as perdecode/1
. The result is the same as:www_form
except for leaving "+" as is in line with RFC 3986.
Encoding defaults to :www_form
for backward compatibility.
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+please") |> Enum.to_list() [{"food", "bread&butter"}, {"drinks", "tap water please"}] iex> URI.query_decoder("food=bread%26butter&drinks=tap%20water+please", :rfc3986) |> Enum.to_list() [{"food", "bread&butter"}, {"drinks", "tap water+please"}]
to_string(uri)Source
Specs
to_string(t()) :: binary()
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: "[email protected]:80"}) "//[email protected]:80" iex> URI.to_string(%URI{userinfo: "bar", host: "example.org", port: 81}) "//[email protected]:81" iex> URI.to_string(%URI{ ...> authority: "[email protected]:80", ...> userinfo: "bar", ...> host: "example.org", ...> port: 81 ...> }) "//[email protected]:81"
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.12.0/URI.html