From 27cfa1da6d35674f6cd169b103385a09c8d4c55a Mon Sep 17 00:00:00 2001
From: Luca Favatella <luca.favatella@erlang-solutions.com>
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(-)

(limited to 'lib/inets')

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:</p>
     <p><c>boolean() = true | false</c></p>
     <p><c>string()</c> = list of ASCII characters</p>
-    <p><c>unicode_binary()</c> = binary() with characters encoded in the UTF-8 coding standard</p>
 
   </section>
   
@@ -54,22 +53,22 @@
     <p>Type definitions that are related to URI:</p>
     
 <taglist>
-       <tag><c>uri() = string() | unicode:unicode_binary()</c></tag>
+       <tag><c>uri() = string() | binary()</c></tag>
        <item><p>Syntax according to the URI definition in RFC 3986,
        for example, "http://www.erlang.org/"</p></item>
-       <tag><c>user_info() = string() | unicode:unicode_binary()</c></tag>
+       <tag><c>user_info() = string() | binary()</c></tag>
        <item><p></p></item>
        <tag><c>scheme() = atom()</c></tag>
        <item><p>Example: http, https</p></item>
-       <tag><c>host() = string() | unicode:unicode_binary()</c></tag>
+       <tag><c>host() = string() | binary()</c></tag>
        <item><p></p></item>
-       <tag><c>port() = pos_integer()</c></tag>
+       <tag><c>port() = inet:port_number()</c></tag>
        <item><p></p></item>
-       <tag><c>path() = string() | unicode:unicode_binary()</c></tag>
+       <tag><c>path() = string() | binary()</c></tag>
        <item><p>Represents a file path or directory path</p></item>
-       <tag><c>query() = string() | unicode:unicode_binary()</c></tag>
+       <tag><c>query() = string() | binary()</c></tag>
        <item><p></p></item>
-       <tag><c>fragment() = string() | unicode:unicode_binary()</c></tag>
+       <tag><c>fragment() = string() | binary()</c></tag>
        <item><p></p></item>
      </taglist>
    
@@ -84,7 +83,7 @@
       
       <fsummary>Decodes a hexadecimal encoded URI.</fsummary>
       <type>
-        <v>HexEncodedURI = string() | unicode:unicode_binary() - A possibly hexadecimal encoded URI</v>
+        <v>HexEncodedURI = string() | binary() - A possibly hexadecimal encoded URI</v>
         <v>URI = uri()</v>
       </type>
 
@@ -99,7 +98,7 @@
       <fsummary>Encodes a hexadecimal encoded URI.</fsummary>
       <type>
         <v>URI = uri()</v>
-        <v>HexEncodedURI = string() | unicode:unicode_binary() - Hexadecimal encoded URI</v>
+        <v>HexEncodedURI = string() | binary() - Hexadecimal encoded URI</v>
       </type>
 
       <desc>
@@ -122,9 +121,10 @@
                     {scheme_validation_fun, fun()}]</v>
         <v>Result = {Scheme, UserInfo, Host, Port, Path, Query} |
                     {Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v>
+	<v>Scheme = scheme()</v>
 	<v>UserInfo = user_info()</v>
 	<v>Host = host()</v>
-	<v>Port = pos_integer()</v>
+	<v>Port = inet:port_number()</v>
 	<v>Path = path()</v>
 	<v>Query = query()</v>
         <v>Fragment = fragment()</v>
@@ -146,7 +146,7 @@
         <p>Scheme validation fun is to be defined as follows:</p>
 
 	<code>
-fun(SchemeStr :: string() | unicode:unicode_binary()) ->
+fun(SchemeStr :: string() | binary()) ->
 	valid |	{error, Reason :: term()}.
 	</code>
 
@@ -162,7 +162,7 @@ fun(SchemeStr :: string() | unicode:unicode_binary()) ->
       <fsummary>A list of the scheme and their default ports.</fsummary>
       <type>
         <v>SchemeDefaults = [{scheme(), default_scheme_port_number()}] </v> 
-	<v>default_scheme_port_number() = pos_integer()</v>
+	<v>default_scheme_port_number() = inet:port_number()</v>
       </type>
       <desc>
         <p>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>> || <<Char>> <= 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 <luca.favatella@erlang-solutions.com>
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(-)

(limited to 'lib/inets')

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 @@
         <v>Option = {ipv6_host_with_brackets, boolean()} | 
                     {scheme_defaults, scheme_defaults()} |
                     {fragment, boolean()} |
-                    {scheme_validation_fun, fun()}]</v>
+                    {scheme_validation_fun, fun()}</v>
         <v>Result = {Scheme, UserInfo, Host, Port, Path, Query} |
                     {Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v>
 	<v>Scheme = scheme()</v>
@@ -153,6 +153,13 @@ fun(SchemeStr :: string() | binary()) ->
         <p>It is called before scheme string gets converted into scheme atom and
         thus possible atom leak could be prevented</p>
 
+        <warning>
+          <p>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.</p>
+        </warning>
+
         <marker id="encode"></marker>
       </desc>
     </func>
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 <luca.favatella@erlang-solutions.com>
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(-)

(limited to 'lib/inets')

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