# Elixir v1.10.3 URI View Source

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

## Types

t()

## 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 \\ %{})

Decodes a query string 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 given `scheme`.

encode(string, predicate \\ &char_unescaped?/1)

Percent-escapes all characters that require escaping in `string`.

encode_query(enumerable)

Encodes an enumerable into a query string.

encode_www_form(string)

Encodes `string` as "x-www-form-urlencoded".

merge(uri, rel)

Merges two URIs.

parse(uri)

Parses a well-formed URI reference into its components.

query_decoder(query)

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.

# Link to this section Types

Link to this type

# t()

View 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()
    }

# Link to this section Functions

Link to this function

# char_reserved?(character)

View 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

Link to this function

# char_unescaped?(character)

View 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

Link to this function

# char_unreserved?(character)

View 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

Link to this function

# decode(uri)

View Source

## Specs

    decode(binary()) :: binary()

Percent-unescapes a URI.

## Examples

    iex> URI.decode("https%3A%2F%2Felixir-lang.org")
    "https://elixir-lang.org"

Link to this function

# decode_query(query, map \\ %{})

View Source

## Specs

    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"}

Link to this function

# decode_www_form(string)

View Source

## Specs

    decode_www_form(binary()) :: binary()

Decodes `string` as "x-www-form-urlencoded".

## Examples

    iex> URI.decode_www_form("%3Call+in%2F")
    "<all in/"

Link to this function

# default_port(scheme)

View 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

Link to this function

# default_port(scheme, port)

View 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.

Link to this function

# encode(string, predicate \\ &char_unescaped?/1)

View 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"

Link to this function

# encode_query(enumerable)

View Source

## Specs

    encode_query(Enum.t()) :: binary()

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]

Link to this function

# encode_www_form(string)

View Source

## Specs

    encode_www_form(binary()) :: binary()

Encodes `string` as "x-www-form-urlencoded".

## Example

    iex> URI.encode_www_form("put: it+й")
    "put%3A+it%2B%D0%B9"

Link to this function

# merge(uri, rel)

View 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"

Link to this function

# parse(uri)

View Source

## Specs

    parse(t() | binary()) :: t()

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
    }

Link to this function

# query_decoder(query)

View Source

## Specs

    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"}]

Link to this function

# to_string(uri)

View 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: "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"