uri (ex_stdlib v0.3.0)

View Source

URI parsing and manipulation module inspired by Elixir's URI module.

This module provides functions for parsing, manipulating, and encoding URIs. A URI is represented as a map with the standard components: scheme, userinfo, host, port, path, query and fragment. Missing components are undefined.

Examples:

   URI = uri:parse("https://user:pass@example.com:8080/path?query=value#fragment"),
   <<"https://example.com/a/c">> = uri:to_string(uri:merge("https://example.com/a/b", "c")),
   <<"name=John+Doe&age=30">> = uri:encode_query([{name, "John Doe"}, {age, 30}]).

Summary

Functions

Appends a path to the URI's path.

Appends a query string to the URI's query.

Checks if a character is reserved in a URI (RFC 3986, section 2.2).

Checks if a character is allowed unescaped in a URI, i.e. it is either reserved or unreserved.

Checks if a character is unreserved in a URI (RFC 3986, section 2.3): alphanumerics and ~, _, -, ..

Percent-unescapes a URI.

Decodes a query string into a list of {Key, Value} binaries, using the www_form encoding.

Decodes a query string into a list of {Key, Value} binaries.

Decodes a string as "x-www-form-urlencoded", turning + into spaces.

Returns the default port for the given scheme, or undefined.

Registers the default port for the given scheme, globally.

Percent-encodes all characters that require escaping in a URI.

Percent-encodes the characters of a string.

Encodes a list of key-value pairs (or a map) into a query string, using the www_form encoding.

Encodes a list of key-value pairs (or a map) into a query string.

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

Extracts the fragment from a URI.

Extracts the host from a URI.

Merges a relative reference onto a base URI as per RFC 3986, section 5.2, including removal of . and .. segments.

Creates a URI.

Parses a URI into its components, without further validation.

Extracts the path from a URI.

Extracts the port from a URI.

Extracts the query from a URI.

Resolves a relative URI against a base URI. Same as merge/2.

Extracts the scheme from a URI.

Converts a URI map back to a string.

Extracts the userinfo from a URI.

Checks if a URI is valid according to basic URI syntax rules.

Types

component/0

-type component() :: scheme | userinfo | host | port | path | query | fragment.

encode_type/0

-type encode_type() :: path | query | fragment | userinfo.

query_encoding/0

-type query_encoding() :: www_form | rfc3986.

uri/0

-type uri() ::
          #{scheme => binary() | undefined,
            userinfo => binary() | undefined,
            host => binary() | undefined,
            port => non_neg_integer() | undefined,
            path => binary() | undefined,
            query => binary() | undefined,
            fragment => binary() | undefined}.

Functions

append_path(URI, Path)

-spec append_path(uri(), binary() | string()) -> uri().

Appends a path to the URI's path.

The path must start with / (but not //) and must not contain a query string or fragment; otherwise badarg is raised.

append_query(URI, Query)

-spec append_query(uri(), binary() | string()) -> uri().

Appends a query string to the URI's query.

The query is not encoded; use encode_query/1 or encode_www_form/1.

char_reserved(C)

-spec char_reserved(byte()) -> boolean().

Checks if a character is reserved in a URI (RFC 3986, section 2.2).

char_unescaped(C)

-spec char_unescaped(byte()) -> boolean().

Checks if a character is allowed unescaped in a URI, i.e. it is either reserved or unreserved.

char_unreserved(C)

-spec char_unreserved(byte()) -> boolean().

Checks if a character is unreserved in a URI (RFC 3986, section 2.3): alphanumerics and ~, _, -, ..

decode(String)

-spec decode(string() | binary()) -> binary().

Percent-unescapes a URI.

Invalid escape sequences are kept as-is.

decode_query(Query)

-spec decode_query(string() | binary()) -> [{binary(), binary()}].

Decodes a query string into a list of {Key, Value} binaries, using the www_form encoding.

decode_query(Query, Encoding)

-spec decode_query(string() | binary(), query_encoding()) -> [{binary(), binary()}].

Decodes a query string into a list of {Key, Value} binaries.

Unlike Elixir, which returns a map, pairs are returned in order and duplicate keys are kept. A key without = gets an empty value. With www_form (the default) + is decoded as a space; with rfc3986 it is kept as-is.

decode_www_form(String)

-spec decode_www_form(string() | binary()) -> binary().

Decodes a string as "x-www-form-urlencoded", turning + into spaces.

default_port(Scheme)

-spec default_port(binary()) -> non_neg_integer() | undefined.

Returns the default port for the given scheme, or undefined.

Built-in defaults: ftp 21, sftp 22, tftp 69, http 80, https 443, ldap 389, ws 80 and wss 443.

default_port(Scheme, Port)

-spec default_port(binary(), non_neg_integer()) -> ok.

Registers the default port for the given scheme, globally.

This is backed by persistent_term, so it should be called rarely, typically once at application start.

encode(String)

-spec encode(string() | binary()) -> binary().

Percent-encodes all characters that require escaping in a URI.

Reserved (such as : and /) and unreserved characters are kept as-is. Same as encode(String, fun uri:char_unescaped/1).

encode(String, Type)

-spec encode(string() | binary(), encode_type() | fun((byte()) -> boolean())) -> binary().

Percent-encodes the characters of a string.

The second argument is either a predicate that receives each byte and returns true when it should be kept as-is, or one of the component types path, query, fragment and userinfo, which keep the characters allowed unescaped in that component.

encode_query(Params)

-spec encode_query([{term(), term()}] | map()) -> binary().

Encodes a list of key-value pairs (or a map) into a query string, using the www_form encoding.

encode_query(Params, Encoding)

-spec encode_query([{term(), term()}] | map(), query_encoding()) -> binary().

Encodes a list of key-value pairs (or a map) into a query string.

Keys and values may be binaries, strings, atoms or numbers. With www_form (the default) they are encoded with encode_www_form/1, so spaces become +. With rfc3986 only unreserved characters are kept and spaces become %20.

encode_www_form(String)

-spec encode_www_form(string() | binary()) -> binary().

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

Only unreserved characters are kept as-is, and spaces become +.

fragment(URI)

-spec fragment(uri()) -> binary() | undefined.

Extracts the fragment from a URI.

host(URI)

-spec host(uri()) -> binary() | undefined.

Extracts the host from a URI.

merge(Base, Rel)

-spec merge(uri() | string() | binary(), uri() | string() | binary()) -> uri().

Merges a relative reference onto a base URI as per RFC 3986, section 5.2, including removal of . and .. segments.

Both arguments may be URI maps or strings. The base must be absolute (have a scheme), otherwise badarg is raised.

new(Components)

-spec new(map()) -> uri();
         (binary() | string()) -> {ok, uri()} | {error, binary()}.

Creates a URI.

Given a map of components, returns a URI with any missing component set to undefined.

Given a string, parses it strictly according to RFC 3986 and returns {ok, URI} or {error, Part} with the part that could not be parsed. Like parse/1, the scheme is downcased and the default port filled in.

parse(URI)

-spec parse(string() | binary() | uri()) -> uri().

Parses a URI into its components, without further validation.

Both absolute and relative URIs are accepted. The scheme is downcased and, when no port is given, the default port for the scheme is filled in (see default_port/1). IPv6 hosts are returned without brackets. Use new/1 for strict RFC 3986 parsing.

path(URI)

-spec path(uri()) -> binary() | undefined.

Extracts the path from a URI.

port(URI)

-spec port(uri()) -> non_neg_integer() | undefined.

Extracts the port from a URI.

query(URI)

-spec query(uri()) -> binary() | undefined.

Extracts the query from a URI.

resolve(Base, Rel)

-spec resolve(uri() | string() | binary(), uri() | string() | binary()) -> uri().

Resolves a relative URI against a base URI. Same as merge/2.

scheme(URI)

-spec scheme(uri()) -> binary() | undefined.

Extracts the scheme from a URI.

to_string(URI)

-spec to_string(uri()) -> binary().

Converts a URI map back to a string.

The port is omitted when it is the default port for the scheme, and IPv6 hosts are wrapped in brackets. Raises badarg if the URI has a host and a path that is neither empty nor absolute.

userinfo(URI)

-spec userinfo(uri()) -> binary() | undefined.

Extracts the userinfo from a URI.

valid(URI)

-spec valid(uri() | string() | binary()) -> boolean().

Checks if a URI is valid according to basic URI syntax rules.

A map is valid when all its components have the right types. A string is valid when it can be parsed by new/1.