From 27cfa1da6d35674f6cd169b103385a09c8d4c55a Mon Sep 17 00:00:00 2001 From: Luca Favatella Date: Thu, 22 Feb 2018 20:14:18 +0000 Subject: inets: export types documented for http_uri module Also: * Reuse type `inet:port_number()` in `http_uri` code and doc; * Do not imply that http_uri module can properly handle UTF-8 encoded binaries, while it can't. * Enrich function specifications in http_uri module; * Fix http_uri doc re missing type definition for `Scheme`. --- lib/inets/doc/src/http_uri.xml | 26 +++++++++++++------------- lib/inets/src/http_lib/http_uri.erl | 32 ++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml index 20c042c202..97be292d87 100644 --- a/lib/inets/doc/src/http_uri.xml +++ b/lib/inets/doc/src/http_uri.xml @@ -45,7 +45,6 @@ this module:

boolean() = true | false

string() = list of ASCII characters

-

unicode_binary() = binary() with characters encoded in the UTF-8 coding standard

@@ -54,22 +53,22 @@

Type definitions that are related to URI:

- uri() = string() | unicode:unicode_binary() + uri() = string() | binary()

Syntax according to the URI definition in RFC 3986, for example, "http://www.erlang.org/"

- user_info() = string() | unicode:unicode_binary() + user_info() = string() | binary()

scheme() = atom()

Example: http, https

- host() = string() | unicode:unicode_binary() + host() = string() | binary()

- port() = pos_integer() + port() = inet:port_number()

- path() = string() | unicode:unicode_binary() + path() = string() | binary()

Represents a file path or directory path

- query() = string() | unicode:unicode_binary() + query() = string() | binary()

- fragment() = string() | unicode:unicode_binary() + fragment() = string() | binary()

@@ -84,7 +83,7 @@ Decodes a hexadecimal encoded URI. - HexEncodedURI = string() | unicode:unicode_binary() - A possibly hexadecimal encoded URI + HexEncodedURI = string() | binary() - A possibly hexadecimal encoded URI URI = uri() @@ -99,7 +98,7 @@ Encodes a hexadecimal encoded URI. URI = uri() - HexEncodedURI = string() | unicode:unicode_binary() - Hexadecimal encoded URI + HexEncodedURI = string() | binary() - Hexadecimal encoded URI @@ -122,9 +121,10 @@ {scheme_validation_fun, fun()}] Result = {Scheme, UserInfo, Host, Port, Path, Query} | {Scheme, UserInfo, Host, Port, Path, Query, Fragment} + Scheme = scheme() UserInfo = user_info() Host = host() - Port = pos_integer() + Port = inet:port_number() Path = path() Query = query() Fragment = fragment() @@ -146,7 +146,7 @@

Scheme validation fun is to be defined as follows:

-fun(SchemeStr :: string() | unicode:unicode_binary()) -> +fun(SchemeStr :: string() | binary()) -> valid | {error, Reason :: term()}. @@ -162,7 +162,7 @@ fun(SchemeStr :: string() | unicode:unicode_binary()) -> A list of the scheme and their default ports. SchemeDefaults = [{scheme(), default_scheme_port_number()}] - default_scheme_port_number() = pos_integer() + default_scheme_port_number() = inet:port_number()

Provides a list of the scheme and their default diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index 7f1ca02014..648bd0538a 100644 --- a/lib/inets/src/http_lib/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -61,16 +61,30 @@ scheme_defaults/0, encode/1, decode/1]). --export_type([scheme/0, default_scheme_port_number/0]). +-export_type([uri/0, + user_info/0, + scheme/0, default_scheme_port_number/0, + host/0, + path/0, + query/0, + fragment/0]). +-type uri() :: string() | binary(). +-type user_info() :: string() | binary(). +-type scheme() :: atom(). +-type host() :: string() | binary(). +-type path() :: string() | binary(). +-type query() :: string() | binary(). +-type fragment() :: string() | binary(). +-type port_number() :: inet:port_number(). +-type default_scheme_port_number() :: port_number(). +-type hex_uri() :: string() | binary(). %% Hexadecimal encoded URI. +-type maybe_hex_uri() :: string() | binary(). %% A possibly hexadecimal encoded URI. %%%========================================================================= %%% API %%%========================================================================= --type scheme() :: atom(). --type default_scheme_port_number() :: pos_integer(). - -spec scheme_defaults() -> [{scheme(), default_scheme_port_number()}]. @@ -82,9 +96,17 @@ scheme_defaults() -> {sftp, 22}, {tftp, 69}]. +-type parse_result() :: + {scheme(), user_info(), host(), port_number(), path(), query()} | + {scheme(), user_info(), host(), port_number(), path(), query(), + fragment()}. + +-spec parse(uri()) -> {ok, parse_result()} | {error, term()}. parse(AbsURI) -> parse(AbsURI, []). +-spec parse(uri(), [Option]) -> {ok, parse_result()} | {error, term()} when + Option :: {atom(), term()}. parse(AbsURI, Opts) -> case parse_scheme(AbsURI, Opts) of {error, Reason} -> @@ -105,6 +127,7 @@ reserved() -> $#, $[, $], $<, $>, $\", ${, $}, $|, %" $\\, $', $^, $%, $ ]). +-spec encode(uri()) -> hex_uri(). encode(URI) when is_list(URI) -> Reserved = reserved(), lists:append([uri_encode(Char, Reserved) || Char <- URI]); @@ -112,6 +135,7 @@ encode(URI) when is_binary(URI) -> Reserved = reserved(), << <<(uri_encode_binary(Char, Reserved))/binary>> || <> <= URI >>. +-spec decode(maybe_hex_uri()) -> uri(). decode(String) when is_list(String) -> do_decode(String); decode(String) when is_binary(String) -> -- cgit v1.2.3 From 81dc712abfc5e93d996191178e555d0c6af3652d Mon Sep 17 00:00:00 2001 From: Luca Favatella Date: Mon, 5 Mar 2018 11:05:34 +0000 Subject: inets: refine types and doc of http_uri:parse options --- lib/inets/doc/src/http_uri.xml | 9 ++++++++- lib/inets/src/http_lib/http_uri.erl | 13 +++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml index 97be292d87..f57214a7ce 100644 --- a/lib/inets/doc/src/http_uri.xml +++ b/lib/inets/doc/src/http_uri.xml @@ -118,7 +118,7 @@ Option = {ipv6_host_with_brackets, boolean()} | {scheme_defaults, scheme_defaults()} | {fragment, boolean()} | - {scheme_validation_fun, fun()}] + {scheme_validation_fun, fun()} Result = {Scheme, UserInfo, Host, Port, Path, Query} | {Scheme, UserInfo, Host, Port, Path, Query, Fragment} Scheme = scheme() @@ -153,6 +153,13 @@ fun(SchemeStr :: string() | binary()) ->

It is called before scheme string gets converted into scheme atom and thus possible atom leak could be prevented

+ +

The scheme portion of the URI gets converted into atom, + meaning that atom leak may occur. Specifying a scheme + validation fun is recommended unless the URI is already + sanitized.

+
+
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index 648bd0538a..3bada84357 100644 --- a/lib/inets/src/http_lib/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -81,13 +81,15 @@ -type hex_uri() :: string() | binary(). %% Hexadecimal encoded URI. -type maybe_hex_uri() :: string() | binary(). %% A possibly hexadecimal encoded URI. +-type scheme_defaults() :: [{scheme(), default_scheme_port_number()}]. +-type scheme_validation_fun() :: fun((SchemeStr :: string() | binary()) -> + valid | {error, Reason :: term()}). + %%%========================================================================= %%% API %%%========================================================================= --spec scheme_defaults() -> - [{scheme(), default_scheme_port_number()}]. - +-spec scheme_defaults() -> scheme_defaults(). scheme_defaults() -> [{http, 80}, {https, 443}, @@ -106,7 +108,10 @@ parse(AbsURI) -> parse(AbsURI, []). -spec parse(uri(), [Option]) -> {ok, parse_result()} | {error, term()} when - Option :: {atom(), term()}. + Option :: {ipv6_host_with_brackets, boolean()} | + {scheme_defaults, scheme_defaults()} | + {fragment, boolean()} | + {scheme_validation_fun, scheme_validation_fun()}. parse(AbsURI, Opts) -> case parse_scheme(AbsURI, Opts) of {error, Reason} -> -- cgit v1.2.3 From 9fc5b13f919cdda12ee8e980d59b67f28a109786 Mon Sep 17 00:00:00 2001 From: Luca Favatella Date: Tue, 6 Mar 2018 09:28:16 +0000 Subject: inets: work around http_uri:parse Dialyzer warning in uri_SUITE.erl:274 Addresses https://github.com/erlang/otp/pull/1724#discussion_r172442753 Current `http_uri:parse/2` implementation intends that ["non-fun scheme_validation_fun works as no option passed"](https://github.com/erlang/otp/blob/OTP-20.2.4/lib/inets/test/uri_SUITE.erl#L271-L274). --- lib/inets/src/http_lib/http_uri.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index 3bada84357..d02913121c 100644 --- a/lib/inets/src/http_lib/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -111,7 +111,7 @@ parse(AbsURI) -> Option :: {ipv6_host_with_brackets, boolean()} | {scheme_defaults, scheme_defaults()} | {fragment, boolean()} | - {scheme_validation_fun, scheme_validation_fun()}. + {scheme_validation_fun, scheme_validation_fun() | none}. parse(AbsURI, Opts) -> case parse_scheme(AbsURI, Opts) of {error, Reason} -> -- cgit v1.2.3