diff options
23 files changed, 656 insertions, 249 deletions
diff --git a/lib/inets/doc/src/Makefile b/lib/inets/doc/src/Makefile index 53d505b102..c4152a1d72 100644 --- a/lib/inets/doc/src/Makefile +++ b/lib/inets/doc/src/Makefile @@ -48,6 +48,7 @@ XML_REF3_FILES = \ inets.xml \ ftp.xml \ tftp.xml \ + http_uri.xml\ httpc.xml\ httpd.xml \ httpd_conf.xml \ diff --git a/lib/inets/doc/src/book.xml b/lib/inets/doc/src/book.xml index 7da0abd98f..51cbb2d963 100644 --- a/lib/inets/doc/src/book.xml +++ b/lib/inets/doc/src/book.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE book SYSTEM "book.dtd"> <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/fascicules.xml b/lib/inets/doc/src/fascicules.xml index 101e745722..ea3b988882 100644 --- a/lib/inets/doc/src/fascicules.xml +++ b/lib/inets/doc/src/fascicules.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE fascicules SYSTEM "fascicules.dtd"> <fascicules> diff --git a/lib/inets/doc/src/ftp_client.xml b/lib/inets/doc/src/ftp_client.xml index 7f62a453a6..b44674d997 100644 --- a/lib/inets/doc/src/ftp_client.xml +++ b/lib/inets/doc/src/ftp_client.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2004</year><year>2009</year> + <year>2004</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml new file mode 100644 index 0000000000..bd31ae42d2 --- /dev/null +++ b/lib/inets/doc/src/http_uri.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="iso-8859-1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2012</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>http_uri</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <date></date> + <rev></rev> + </header> + + <module>http_uri</module> + <modulesummary>URI utility module</modulesummary> + + <description> + <p>This module provides utility functions for working with URIs, + according to RFC 3986. </p> + + </description> + + <section> + <title>COMMON DATA TYPES </title> + <p>Type definitions that are used more than once in + this module:</p> + <code type="none"><![CDATA[ +boolean() = true | false +string() = list of ASCII characters + ]]></code> + + </section> + + <section> + <title>URI DATA TYPES </title> + <p>Type definitions that are related to URI:</p> + <p>For more information about URI, see RFC 3986. </p> + + <code type="none"><![CDATA[ +uri() = string() - Syntax according to the URI definition in rfc 3986, ex: "http://www.erlang.org/" +user_info() = string() +scheme() = atom() - Example: http, https +host() = string() +port() = pos_integer() +path() = string() - Representing a file path or directory path +query() = string() + ]]></code> + + <marker id="scheme_defaults"></marker> + </section> + + <funcs> + <func> + <name>scheme_defaults() -> SchemeDefaults</name> + <fsummary>A list of scheme and their default ports</fsummary> + <type> + <v>SchemeDefaults = [{scheme(), default_scheme_port_number()}] </v> + <v>default_scheme_port_number() = pos_integer()</v> + </type> + <desc> + <p>This function provides a list of the scheme and their default + port numbers currently supported (by default) by this utility. </p> + + <marker id="parse"></marker> + </desc> + </func> + + <func> + <name>parse(URI) -> {ok, Result} | {error, Reason}</name> + <name>parse(URI, Options) -> {ok, Result} | {error, Reason}</name> + <fsummary>Parse an URI</fsummary> + <type> + <v>URI = uri() </v> + <v>Options = [Option] </v> + <v>Option = {ipv6_host_with_brackets, boolean()} | + {scheme_defaults, scheme_defaults()}]</v> + <v>Result = {Scheme, UserInfo, Host, Port, Path, Query}</v> + <v>UserInfo = user_info()</v> + <v>Host = host()</v> + <v>Port = pos_integer()</v> + <v>Path = path()</v> + <v>Query = query()</v> + <v>Reason = term() </v> + </type> + <desc> + <p>This function is used to parse an URI. If no scheme defaults + are provided, the value of + <seealso marker="#scheme_defaults">scheme_defaults</seealso> + function will be used. </p> + + <p>Note that when parsing an URI with an unknown scheme (that is, + a scheme not found in the scheme defaults) a port number must be + provided or else the parsing will fail. </p> + + <marker id="encode"></marker> + </desc> + </func> + + <func> + <name>encode(URI) -> HexEncodedURI</name> + + <fsummary>Hex encode an URI</fsummary> + <type> + <v>URI = uri()</v> + <v>HexEncodedURI = string() - Hex encoded uri</v> + </type> + + <desc> + <p>Hex encode an URI. </p> + + <marker id="decode"></marker> + </desc> + </func> + + <func> + <name>decode(HexEncodedURI) -> URI</name> + + <fsummary>Decode a hex encoded URI</fsummary> + <type> + <v>HexEncodedURI = string() - A possibly hex encoded uri</v> + <v>URI = uri()</v> + </type> + + <desc> + <p>Decode a possibly hex encoded URI. </p> + + </desc> + </func> + + </funcs> + +<!-- + <section> + <title>SEE ALSO</title> + <p>RFC 2616, <seealso marker="inets">inets(3)</seealso>, + <seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>, + <seealso marker="ssl:ssl">ssl(3)</seealso> + </p> + </section> +--> + +</erlref> diff --git a/lib/inets/doc/src/httpd_conf.xml b/lib/inets/doc/src/httpd_conf.xml index a1ad76a8ae..fc34f14ec3 100644 --- a/lib/inets/doc/src/httpd_conf.xml +++ b/lib/inets/doc/src/httpd_conf.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -33,11 +33,14 @@ Web server API programmer.</modulesummary> <description> <p>This module provides the Erlang Webserver API programmer with - utility functions for adding run-time configuration directives.</p> + utility functions for adding run-time configuration directives.</p> + + <marker id="check_enum"></marker> </description> + <funcs> <func> - <name>check_enum(EnumString,ValidEnumStrings) -> Result</name> + <name>check_enum(EnumString, ValidEnumStrings) -> Result</name> <fsummary>Check if string is a valid enumeration.</fsummary> <type> <v>EnumString = string()</v> @@ -47,10 +50,13 @@ <desc> <marker id="check_enum"></marker> <p><c>check_enum/2</c> checks if <c>EnumString</c> is a valid - enumeration of <c>ValidEnumStrings</c> in which case it is - returned as an atom.</p> + enumeration of <c>ValidEnumStrings</c> in which case it is + returned as an atom.</p> + + <marker id="clean"></marker> </desc> </func> + <func> <name>clean(String) -> Stripped</name> <fsummary>Remove leading and/or trailing white spaces.</fsummary> @@ -60,9 +66,12 @@ <desc> <marker id="clean"></marker> <p><c>clean/1</c> removes leading and/or trailing white spaces - from <c>String</c>.</p> + from <c>String</c>.</p> + + <marker id="custom_clean"></marker> </desc> </func> + <func> <name>custom_clean(String,Before,After) -> Stripped</name> <fsummary>Remove leading and/or trailing white spaces and custom characters.</fsummary> @@ -73,11 +82,14 @@ <desc> <marker id="custom_clean"></marker> <p><c>custom_clean/3</c> removes leading and/or trailing white - spaces and custom characters from <c>String</c>. <c>Before</c> - and <c>After</c> are regular expressions, as defined in - <c>regexp(3)</c>, describing the custom characters.</p> + spaces and custom characters from <c>String</c>. <c>Before</c> + and <c>After</c> are regular expressions, as defined in + <c>regexp(3)</c>, describing the custom characters.</p> + + <marker id="is_directory"></marker> </desc> </func> + <func> <name>is_directory(FilePath) -> Result</name> <fsummary>Check if a file path is a directory.</fsummary> @@ -91,13 +103,16 @@ <desc> <marker id="is_directory"></marker> <p><c>is_directory/1</c> checks if <c>FilePath</c> is a - directory in which case it is returned. Please read - <c>file(3)</c> for a description of <c>enoent</c>, - <c>eaccess</c> and <c>enotdir</c>. The definition of - the file info record can be found by including <c>file.hrl</c> - from the kernel application, see file(3).</p> + directory in which case it is returned. Please read + <c>file(3)</c> for a description of <c>enoent</c>, + <c>eaccess</c> and <c>enotdir</c>. The definition of + the file info record can be found by including <c>file.hrl</c> + from the kernel application, see file(3).</p> + + <marker id="is_file"></marker> </desc> </func> + <func> <name>is_file(FilePath) -> Result</name> <fsummary>Check if a file path is a regular file.</fsummary> @@ -111,13 +126,16 @@ <desc> <marker id="is_file"></marker> <p><c>is_file/1</c> checks if <c>FilePath</c> is a regular - file in which case it is returned. Read <c>file(3)</c> for a - description of <c>enoent</c>, <c>eaccess</c> and - <c>enotdir</c>. The definition of the file info record can be - found by including <c>file.hrl</c> from the kernel application, - see file(3).</p> + file in which case it is returned. Read <c>file(3)</c> for a + description of <c>enoent</c>, <c>eaccess</c> and + <c>enotdir</c>. The definition of the file info record can be + found by including <c>file.hrl</c> from the kernel application, + see file(3).</p> + + <marker id="make_integer"></marker> </desc> </func> + <func> <name>make_integer(String) -> Result</name> <fsummary>Return an integer representation of a string.</fsummary> diff --git a/lib/inets/doc/src/httpd_socket.xml b/lib/inets/doc/src/httpd_socket.xml index fba1a58d3a..58cd2ec575 100644 --- a/lib/inets/doc/src/httpd_socket.xml +++ b/lib/inets/doc/src/httpd_socket.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -33,10 +33,13 @@ Web server API programmer.</modulesummary> <description> <p>This module provides the Erlang Web server API module programmer - with utility functions for generic sockets communication. The - appropriate communication mechanism is transparently used, that - is <c>ip_comm</c> or <c>ssl</c>.</p> + with utility functions for generic sockets communication. The + appropriate communication mechanism is transparently used, that + is <c>ip_comm</c> or <c>ssl</c>.</p> + + <marker id="deliver"></marker> </description> + <funcs> <func> <name>deliver(SocketType, Socket, Data) -> Result</name> @@ -50,11 +53,14 @@ <desc> <marker id="deliver"></marker> <p><c>deliver/3</c> sends the <c>Binary</c> over the - <c>Socket</c> using the specified <c>SocketType</c>. Socket - and SocketType should be the socket and the socket_type form - the mod record as defined in httpd.hrl</p> + <c>Socket</c> using the specified <c>SocketType</c>. Socket + and SocketType should be the socket and the socket_type form + the mod record as defined in httpd.hrl</p> + + <marker id="peername"></marker> </desc> </func> + <func> <name>peername(SocketType,Socket) -> {Port,IPAddress}</name> <fsummary>Return the port and IP-address of the remote socket.</fsummary> @@ -67,9 +73,12 @@ <desc> <marker id="peername"></marker> <p><c>peername/3</c> returns the <c>Port</c> and - <c>IPAddress</c> of the remote <c>Socket</c>. </p> + <c>IPAddress</c> of the remote <c>Socket</c>. </p> + + <marker id="resolve"></marker> </desc> </func> + <func> <name>resolve() -> HostName</name> <fsummary>Return the official name of the current host.</fsummary> @@ -79,7 +88,7 @@ <desc> <marker id="resolve"></marker> <p><c>resolve/0</c> returns the official <c>HostName</c> of - the current host. </p> + the current host. </p> </desc> </func> </funcs> diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml index 6ac2b13c72..9f290084d2 100644 --- a/lib/inets/doc/src/httpd_util.xml +++ b/lib/inets/doc/src/httpd_util.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1997</year><year>2010</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/inets_services.xml b/lib/inets/doc/src/inets_services.xml index c274d67f19..e282050b12 100644 --- a/lib/inets/doc/src/inets_services.xml +++ b/lib/inets/doc/src/inets_services.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/mod_alias.xml b/lib/inets/doc/src/mod_alias.xml index c783b99b23..265a1b8e76 100644 --- a/lib/inets/doc/src/mod_alias.xml +++ b/lib/inets/doc/src/mod_alias.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,8 +32,11 @@ <modulesummary>URL aliasing.</modulesummary> <description> <p>Erlang Webserver Server internal API for handling of things - such as interaction data exported by the mod_alias module.</p> + such as interaction data exported by the mod_alias module.</p> + + <marker id="default_index"></marker> </description> + <funcs> <func> <name>default_index(ConfigDB, Path) -> NewPath</name> @@ -45,17 +48,20 @@ <desc> <marker id="default_index"></marker> <p>If <c>Path</c> is a directory, <c>default_index/2</c>, it starts - searching for resources or files that are specified in the config - directive DirectoryIndex. - If an appropriate resource or file is found, it is appended to - the end of <c>Path</c> and then returned. <c>Path</c> is - returned unaltered, if no appropriate - file is found, or if <c>Path</c> is not a directory. - <c>config_db()</c> is the server config file in ETS table format - as described in - <seealso marker="http_server">Inets Users Guide.</seealso>.</p> + searching for resources or files that are specified in the config + directive DirectoryIndex. + If an appropriate resource or file is found, it is appended to + the end of <c>Path</c> and then returned. <c>Path</c> is + returned unaltered, if no appropriate + file is found, or if <c>Path</c> is not a directory. + <c>config_db()</c> is the server config file in ETS table format + as described in + <seealso marker="http_server">Inets Users Guide.</seealso>.</p> + + <marker id="path"></marker> </desc> </func> + <func> <name>path(PathData, ConfigDB, RequestURI) -> Path</name> <fsummary>Return the actual file path to a URL.</fsummary> @@ -67,15 +73,19 @@ <desc> <marker id="path"></marker> <p><c>path/3</c> returns the actual file <c>Path</c> in the - <c>RequestURI</c> (See RFC 1945). If the interaction data - <c>{real_name,{Path,AfterPath}}</c> has been exported by - mod_alias; - <c>Path</c> is returned. If no interaction data has been - exported, ServerRoot is used to - generate a file <c>Path</c>. <c>config_db()</c> and - <c>interaction_data()</c> are as defined in <seealso marker="http_server">Inets Users Guide</seealso>.</p> + <c>RequestURI</c> (See RFC 1945). If the interaction data + <c>{real_name,{Path,AfterPath}}</c> has been exported by + mod_alias; + <c>Path</c> is returned. If no interaction data has been + exported, ServerRoot is used to + generate a file <c>Path</c>. <c>config_db()</c> and + <c>interaction_data()</c> are as defined in + <seealso marker="http_server">Inets Users Guide</seealso>.</p> + + <marker id="real_name"></marker> </desc> </func> + <func> <name>real_name(ConfigDB, RequestURI, Aliases) -> Ret</name> <fsummary>Expand a request uri using Alias config directives.</fsummary> @@ -89,18 +99,24 @@ <desc> <marker id="real_name"></marker> <p><c>real_name/3</c> traverses <c>Aliases</c>, typically - extracted from <c>ConfigDB</c>, and matches each - <c>FakeName</c> with <c>RequestURI</c>. If a match is found - <c>FakeName</c> is replaced with <c>RealName</c> in the - match. The resulting path is split into two parts, that - is <c>ShortPath</c> and <c>AfterPath</c> as defined in <seealso marker="httpd_util#split_path">httpd_util:split_path/1</seealso>. - <c>Path</c> is generated from <c>ShortPath</c>, that is - the result from <seealso marker="#default_index">default_index/2</seealso> with - <c>ShortPath</c> as an argument. - <c>config_db()</c> is the server config file in ETS table - format as described in <seealso marker="http_server">Inets User Guide.</seealso>. </p> + extracted from <c>ConfigDB</c>, and matches each + <c>FakeName</c> with <c>RequestURI</c>. If a match is found + <c>FakeName</c> is replaced with <c>RealName</c> in the + match. The resulting path is split into two parts, that + is <c>ShortPath</c> and <c>AfterPath</c> as defined in + <seealso marker="httpd_util#split_path">httpd_util:split_path/1</seealso>. + <c>Path</c> is generated from <c>ShortPath</c>, that is + the result from + <seealso marker="#default_index">default_index/2</seealso> with + <c>ShortPath</c> as an argument. + <c>config_db()</c> is the server config file in ETS table + format as described in + <seealso marker="http_server">Inets User Guide.</seealso>. </p> + + <marker id="real_script_name"></marker> </desc> </func> + <func> <name>real_script_name(ConfigDB,RequestURI,ScriptAliases) -> Ret</name> <fsummary>Expand a request uri using ScriptAlias config directives.</fsummary> @@ -114,15 +130,15 @@ <desc> <marker id="real_script_name"></marker> <p><c>real_name/3</c> traverses <c>ScriptAliases</c>, - typically extracted from <c>ConfigDB</c>, and matches each - <c>FakeName</c> with <c>RequestURI</c>. If a match is found - <c>FakeName</c> is replaced with <c>RealName</c> in the - match. If the resulting match is not an executable script - <c>not_a_script</c> is returned. If it is a script the - resulting script path is in two parts, that is - <c>ShortPath</c> and <c>AfterPath</c> as defined in <seealso marker="httpd_util#split_script_path">httpd_util:split_script_path/1</seealso>. - <c>config_db()</c> is the server config file in ETS table - format as described in <seealso marker="http_server">Inets Users Guide.</seealso>.</p> + typically extracted from <c>ConfigDB</c>, and matches each + <c>FakeName</c> with <c>RequestURI</c>. If a match is found + <c>FakeName</c> is replaced with <c>RealName</c> in the + match. If the resulting match is not an executable script + <c>not_a_script</c> is returned. If it is a script the + resulting script path is in two parts, that is + <c>ShortPath</c> and <c>AfterPath</c> as defined in <seealso marker="httpd_util#split_script_path">httpd_util:split_script_path/1</seealso>. + <c>config_db()</c> is the server config file in ETS table + format as described in <seealso marker="http_server">Inets Users Guide.</seealso>.</p> </desc> </func> </funcs> diff --git a/lib/inets/doc/src/mod_auth.xml b/lib/inets/doc/src/mod_auth.xml index 2134ebeeae..7801567862 100644 --- a/lib/inets/doc/src/mod_auth.xml +++ b/lib/inets/doc/src/mod_auth.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -32,8 +32,11 @@ <modulesummary>User authentication using text files, dets or mnesia database.</modulesummary> <description> <p>This module provides for basic user authentication using - textual files, dets databases as well as mnesia databases. </p> + textual files, dets databases as well as mnesia databases. </p> + + <marker id="add_user"></marker> </description> + <funcs> <func> <name>add_user(UserName, Options) -> true| {error, Reason}</name> @@ -55,12 +58,17 @@ <desc> <marker id="user_api"></marker> <marker id="add_user"></marker> - <p><c>add_user/2, add_user/5</c> and <c>add_user/6</c> adds a user to the user - database. If the operation is successful, this function returns - <c>true</c>. If an error occurs, <c>{error,Reason}</c> is returned. When <c>add_user/2</c> - is called the Password, UserData Port and Dir options is mandatory.</p> + <p><c>add_user/2, add_user/5</c> and <c>add_user/6</c> adds a + user to the user + database. If the operation is successful, this function returns + <c>true</c>. If an error occurs, <c>{error,Reason}</c> is returned. + When <c>add_user/2</c> is called the Password, + UserData Port and Dir options is mandatory.</p> + + <marker id="delete_user"></marker> </desc> </func> + <func> <name>delete_user(UserName,Options) -> true | {error, Reason}</name> <name>delete_user(UserName, Port, Dir) -> true | {error, Reason}</name> @@ -79,13 +87,16 @@ <desc> <marker id="delete_user"></marker> <p><c>delete_user/2, delete_user/3</c> and <c>delete_user/4</c> - deletes a user - from the user database. If the operation is successful, this - function returns <c>true</c>. If an error occurs, - <c>{error,Reason}</c> is returned. When <c>delete_user/2</c> is - called the Port and Dir options are mandatory.</p> + deletes a user from the user database. + If the operation is successful, this function returns <c>true</c>. + If an error occurs, <c>{error,Reason}</c> is returned. + When <c>delete_user/2</c> is called the Port and Dir options + are mandatory.</p> + + <marker id="get_user"></marker> </desc> </func> + <func> <name>get_user(UserName,Options) -> {ok, #httpd_user} |{error, Reason}</name> <name>get_user(UserName, Port, Dir) -> {ok, #httpd_user} | {error, Reason}</name> @@ -104,12 +115,15 @@ <desc> <marker id="get_user"></marker> <p><c>get_user/2, get_user/3</c> and <c>get_user/4</c> returns a - <c>httpd_user</c> record containing the userdata for a - specific user. If the user cannot be found, <c>{error, Reason}</c> - is returned. When <c>get_user/2</c> is called the Port and Dir - options are mandatory.</p> + <c>httpd_user</c> record containing the userdata for a + specific user. If the user cannot be found, <c>{error, Reason}</c> + is returned. When <c>get_user/2</c> is called the Port and Dir + options are mandatory.</p> + + <marker id="list_users"></marker> </desc> </func> + <func> <name>list_users(Options) -> {ok, Users} | {error, Reason}</name> <name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name> @@ -127,12 +141,16 @@ </type> <desc> <marker id="list_users"></marker> - <p><c>list_users/1, list_users/2</c> and <c>list_users/3</c> returns a list - of users in the user database for a specific <c>Port/Dir</c>. - When <c>list_users/1</c> is called the Port and Dir - options are mandatory.</p> + <p><c>list_users/1, list_users/2</c> and <c>list_users/3</c> + returns a list + of users in the user database for a specific <c>Port/Dir</c>. + When <c>list_users/1</c> is called the Port and Dir + options are mandatory.</p> + + <marker id="add_group_member"></marker> </desc> </func> + <func> <name>add_group_member(GroupName, UserName, Options) -> true | {error, Reason}</name> <name>add_group_member(GroupName, UserName, Port, Dir) -> true | {error, Reason}</name> @@ -151,13 +169,18 @@ </type> <desc> <marker id="add_group_member"></marker> - <p><c>add_group_member/3, add_group_member/4</c> and <c>add_group_member/5</c> - adds a user to a group. If the group does not exist, it - is created and the user is added to the group. Upon successful - operation, this function returns <c>true</c>. When <c>add_group_members/3</c> - is called the Port and Dir options are mandatory.</p> + <p><c>add_group_member/3, add_group_member/4</c> and + <c>add_group_member/5</c> + adds a user to a group. If the group does not exist, it + is created and the user is added to the group. Upon successful + operation, this function returns <c>true</c>. + When <c>add_group_members/3</c> + is called the Port and Dir options are mandatory.</p> + + <marker id="delete_group_member"></marker> </desc> </func> + <func> <name>delete_group_member(GroupName, UserName, Options) -> true | {error, Reason}</name> <name>delete_group_member(GroupName, UserName, Port, Dir) -> true | {error, Reason}</name> @@ -176,13 +199,17 @@ </type> <desc> <marker id="delete_group_member"></marker> - <p><c>delete_group_member/3, delete_group_member/4</c> and <c>delete_group_member/5</c> deletes a user from a group. - If the group or the user does not exist, - this function returns an error, otherwise it returns <c>true</c>. - When <c>delete_group_member/3</c> is called the Port and Dir options - are mandatory.</p> + <p><c>delete_group_member/3, delete_group_member/4</c> and + <c>delete_group_member/5</c> deletes a user from a group. + If the group or the user does not exist, + this function returns an error, otherwise it returns <c>true</c>. + When <c>delete_group_member/3</c> is called the Port and Dir options + are mandatory.</p> + + <marker id="list_group_members"></marker> </desc> </func> + <func> <name>list_group_members(GroupName, Options) -> {ok, Users} | {error, Reason}</name> <name>list_group_members(GroupName, Port, Dir) -> {ok, Users} | {error, Reason}</name> @@ -201,13 +228,17 @@ </type> <desc> <marker id="list_group_members"></marker> - <p><c>list_group_members/2, list_group_members/3</c> and <c>list_group_members/4</c> - lists the members of a specified group. If the group does not - exist or there is an error, <c>{error, Reason}</c> is returned. - When <c>list_group_members/2</c> is called the Port and Dir options - are mandatory.</p> + <p><c>list_group_members/2, list_group_members/3</c> and + <c>list_group_members/4</c> + lists the members of a specified group. If the group does not + exist or there is an error, <c>{error, Reason}</c> is returned. + When <c>list_group_members/2</c> is called the Port and Dir options + are mandatory.</p> + + <marker id="list_groups"></marker> </desc> </func> + <func> <name>list_groups(Options) -> {ok, Groups} | {error, Reason}</name> <name>list_groups(Port, Dir) -> {ok, Groups} | {error, Reason}</name> @@ -225,12 +256,16 @@ </type> <desc> <marker id="list_groups"></marker> - <p><c>list_groups/1, list_groups/2</c> and <c>list_groups/3</c> lists all - the groups available. If there is an error, <c>{error, Reason}</c> - is returned. When <c>list_groups/1</c> is called the Port and Dir options - are mandatory.</p> + <p><c>list_groups/1, list_groups/2</c> and <c>list_groups/3</c> + lists all the groups available. + If there is an error, <c>{error, Reason}</c> is returned. + When <c>list_groups/1</c> is called the Port and Dir options + are mandatory.</p> + + <marker id="delete_group"></marker> </desc> </func> + <func> <name>delete_group(GroupName, Options) -> true | {error,Reason} <name>delete_group(GroupName, Port, Dir) -> true | {error, Reason}</name> <name>delete_group(GroupName, Address, Port, Dir) -> true | {error, Reason}</name> @@ -247,12 +282,16 @@ </type> <desc> <marker id="delete_group"></marker> - <p><c>delete_group/2, delete_group/3</c> and <c>delete_group/4</c> deletes the - group specified and returns <c>true</c>. If there is an error, - <c>{error, Reason}</c> is returned. When <c>delete_group/2</c> is called the - Port and Dir options are mandatory.</p> + <p><c>delete_group/2, delete_group/3</c> and <c>delete_group/4</c> + deletes the group specified and returns <c>true</c>. + If there is an error, <c>{error, Reason}</c> is returned. + When <c>delete_group/2</c> is called the + Port and Dir options are mandatory.</p> + + <marker id="update_password"></marker> </desc> </func> + <func> <name>update_password(Port, Dir, OldPassword, NewPassword, NewPassword) -> ok | {error, Reason}</name> <name>update_password(Address,Port, Dir, OldPassword, NewPassword, NewPassword) -> ok | {error, Reason}</name> @@ -268,10 +307,12 @@ </type> <desc> <marker id="update_password"></marker> - <p><c>update_password/5</c> and <c>update_password/6</c> Updates the AuthAccessPassword - for the specified directory. If NewPassword is equal to "NoPassword" no password is requires to - change authorisation data. If NewPassword is equal to "DummyPassword" no changes can be done - without changing the password first.</p> + <p><c>update_password/5</c> and <c>update_password/6</c> + Updates the AuthAccessPassword for the specified directory. + If NewPassword is equal to "NoPassword" no password is requires to + change authorisation data. + If NewPassword is equal to "DummyPassword" no changes can be done + without changing the password first.</p> </desc> </func> </funcs> diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index f2cd03b6a8..dfdeb4016c 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -70,6 +70,18 @@ <p>Own Id: OTP-9979</p> </item> + <item> + <p>Utility module + <seealso marker="http_uri">http_uri</seealso> + now officially supported. </p> + <p>Also, the + <seealso marker="http_uri#parse">parse</seealso> + function has been extended with more + scheme support and a way to provide your own scheme info. </p> + <p>Own Id: OTP-9983</p> + <p>Aux Id: Seq 12022</p> + </item> + </list> </section> diff --git a/lib/inets/doc/src/notes_history.xml b/lib/inets/doc/src/notes_history.xml index 151bec375e..bd59c1ba47 100644 --- a/lib/inets/doc/src/notes_history.xml +++ b/lib/inets/doc/src/notes_history.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2004</year><year>2011</year> + <year>2004</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/part.xml b/lib/inets/doc/src/part.xml index 36955df6b3..3b6734a9b8 100644 --- a/lib/inets/doc/src/part.xml +++ b/lib/inets/doc/src/part.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2004</year><year>2009</year> + <year>2004</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/part_notes.xml b/lib/inets/doc/src/part_notes.xml index 21f464318b..81b0dedbfa 100644 --- a/lib/inets/doc/src/part_notes.xml +++ b/lib/inets/doc/src/part_notes.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2002</year><year>2009</year> + <year>2002</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/part_notes_history.xml b/lib/inets/doc/src/part_notes_history.xml index 3c1e6f5232..f714a6d2e3 100644 --- a/lib/inets/doc/src/part_notes_history.xml +++ b/lib/inets/doc/src/part_notes_history.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part> <header> <copyright> - <year>2004</year><year>2009</year> + <year>2004</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/inets/doc/src/ref_man.xml b/lib/inets/doc/src/ref_man.xml index 45d5dfcd0e..e44829827c 100644 --- a/lib/inets/doc/src/ref_man.xml +++ b/lib/inets/doc/src/ref_man.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE application SYSTEM "application.dtd"> <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1997</year><year>2010</year> + <year>1997</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -30,8 +30,8 @@ </header> <description> <p>Inets is a container for Internet clients and - servers. Currently a FTP client, a HTTP client and server, and - a tftp client and server has been incorporated in Inets.</p> + servers. Currently a FTP client, a HTTP client and server, and + a tftp client and server has been incorporated in Inets.</p> </description> <xi:include href="inets.xml"/> <xi:include href="ftp.xml"/> @@ -45,6 +45,7 @@ <xi:include href="mod_auth.xml"/> <xi:include href="mod_esi.xml"/> <xi:include href="mod_security.xml"/> + <xi:include href="http_uri.xml"/> </application> diff --git a/lib/inets/doc/src/tftp.xml b/lib/inets/doc/src/tftp.xml index 96d6ae0dd5..0b3e93a153 100644 --- a/lib/inets/doc/src/tftp.xml +++ b/lib/inets/doc/src/tftp.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>2006</year><year>2009</year> + <year>2006</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -218,6 +218,8 @@ <c>5</c> times when the timeout expires.</p> </item> </taglist> + + <marker id="start1"></marker> </section> <funcs> @@ -231,11 +233,14 @@ </type> <desc> <p>Starts a daemon process which listens for udp packets on a - port. When it receives a request for read or write it spawns - a temporary server process which handles the actual transfer - of the (virtual) file.</p> + port. When it receives a request for read or write it spawns + a temporary server process which handles the actual transfer + of the (virtual) file.</p> + + <marker id="read_file"></marker> </desc> </func> + <func> <name>read_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name> <fsummary>Read a (virtual) file from a TFTP server</fsummary> @@ -248,23 +253,26 @@ </type> <desc> <p>Reads a (virtual) file <c>RemoteFilename</c> from a TFTP - server.</p> - <p>If <c>LocalFilename</c> is the atom <c>binary</c>, - <c>tftp_binary</c> is used as callback module. It concatenates - all transferred blocks and returns them as one single binary - in <c>LastCallbackState</c>.</p> - <p>If <c>LocalFilename</c> is a string and there are no - registered callback modules, <c>tftp_file</c> is used as - callback module. It writes each transferred block to the file - named <c>LocalFilename</c> and returns the number of - transferred bytes in <c>LastCallbackState</c>.</p> - <p>If <c>LocalFilename</c> is a string and there are registered - callback modules, <c>LocalFilename</c> is tested against - the regexps of these and the callback module corresponding to - the first match is used, or an error tuple is returned if no - matching regexp is found.</p> + server.</p> + <p>If <c>LocalFilename</c> is the atom <c>binary</c>, + <c>tftp_binary</c> is used as callback module. It concatenates + all transferred blocks and returns them as one single binary + in <c>LastCallbackState</c>.</p> + <p>If <c>LocalFilename</c> is a string and there are no + registered callback modules, <c>tftp_file</c> is used as + callback module. It writes each transferred block to the file + named <c>LocalFilename</c> and returns the number of + transferred bytes in <c>LastCallbackState</c>.</p> + <p>If <c>LocalFilename</c> is a string and there are registered + callback modules, <c>LocalFilename</c> is tested against + the regexps of these and the callback module corresponding to + the first match is used, or an error tuple is returned if no + matching regexp is found.</p> </desc> + + <marker id="write_file"></marker> </func> + <func> <name>write_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name> <fsummary>Write a (virtual) file to a TFTP server</fsummary> @@ -288,10 +296,12 @@ block by block and returns the number of transferred bytes in <c>LastCallbackState</c>.</p> <p>If <c>LocalFilename</c> is a string and there are registered - callback modules, <c>LocalFilename</c> is tested against - the regexps of these and the callback module corresponding to - the first match is used, or an error tuple is returned if no - matching regexp is found.</p> + callback modules, <c>LocalFilename</c> is tested against + the regexps of these and the callback module corresponding to + the first match is used, or an error tuple is returned if no + matching regexp is found.</p> + + <marker id="info_daemons"></marker> </desc> </func> @@ -304,8 +314,9 @@ <v>Reason = term()</v> </type> <desc> - <p>Returns info about all TFTP daemon processes. - </p> + <p>Returns info about all TFTP daemon processes. </p> + + <marker id="info_servers"></marker> </desc> </func> @@ -318,8 +329,9 @@ <v>Reason = term()</v> </type> <desc> - <p>Returns info about all TFTP server processes. - </p> + <p>Returns info about all TFTP server processes. </p> + + <marker id="info_pid"></marker> </desc> </func> @@ -332,6 +344,8 @@ </type> <desc> <p>Returns info about a TFTP daemon, server or client process.</p> + + <marker id="change_config_daemons"></marker> </desc> </func> @@ -346,8 +360,9 @@ <v>Reason = term()</v> </type> <desc> - <p>Changes config for all TFTP daemon processes - </p> + <p>Changes config for all TFTP daemon processes. </p> + + <marker id="change_config_servers"></marker> </desc> </func> @@ -362,8 +377,9 @@ <v>Reason = term()</v> </type> <desc> - <p>Changes config for all TFTP server processes - </p> + <p>Changes config for all TFTP server processes. </p> + + <marker id="change_config_pid"></marker> </desc> </func> @@ -378,8 +394,11 @@ </type> <desc> <p>Changes config for a TFTP daemon, server or client process</p> + + <marker id="start2"></marker> </desc> </func> + <func> <name>start() -> ok | {error, Reason}</name> <fsummary>Start the Inets application</fsummary> @@ -442,8 +461,9 @@ by the already ongoing connection on the server side. By not setting up yet another connection, in parallel with the ongoing one, the server will - consumer lesser resources. - </p> + consumer lesser resources. </p> + + <marker id="prepare"></marker> </section> <funcs> @@ -468,17 +488,20 @@ <v>Text = string()</v> </type> <desc> - <p>Prepares to open a file on the client side.</p> - <p>No new options may be added, but the ones that are present in - <c>SuggestedOptions</c> may be omitted or replaced with new - values in <c>AcceptedOptions</c>.</p> - <p>Will be followed by a call to <c>open/4</c> before any - read/write access is performed. <c>AcceptedOptions</c> is - sent to the server which replies with those options that it - accepts. These will be forwarded to <c>open/4</c> as - <c>SuggestedOptions</c>.</p> + <p>Prepares to open a file on the client side.</p> + <p>No new options may be added, but the ones that are present in + <c>SuggestedOptions</c> may be omitted or replaced with new + values in <c>AcceptedOptions</c>.</p> + <p>Will be followed by a call to <c>open/4</c> before any + read/write access is performed. <c>AcceptedOptions</c> is + sent to the server which replies with those options that it + accepts. These will be forwarded to <c>open/4</c> as + <c>SuggestedOptions</c>.</p> + + <marker id="open"></marker> </desc> </func> + <func> <name>open(Peer, Access, Filename, Mode, SuggestedOptions, State) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name> <fsummary>Open a file for read or write access</fsummary> @@ -503,14 +526,17 @@ <desc> <p>Opens a file for read or write access.</p> <p>On the client side where the <c>open/5</c> call has been - preceded by a call to <c>prepare/5</c>, all options must be - accepted or rejected.</p> - <p>On the server side, where there is no preceding - <c>prepare/5</c> call, no new options may be added, but - the ones that are present in <c>SuggestedOptions</c> may be - omitted or replaced with new values in <c>AcceptedOptions</c>.</p> + preceded by a call to <c>prepare/5</c>, all options must be + accepted or rejected.</p> + <p>On the server side, where there is no preceding + <c>prepare/5</c> call, no new options may be added, but + the ones that are present in <c>SuggestedOptions</c> may be + omitted or replaced with new values in <c>AcceptedOptions</c>.</p> + + <marker id="read"></marker> </desc> </func> + <func> <name>read(State) -> {more, Bin, NewState} | {last, Bin, FileSize} | {error, {Code, Text}}</name> <fsummary>Read a chunk from the file</fsummary> @@ -526,15 +552,18 @@ <desc> <p>Read a chunk from the file.</p> <p>The callback function is expected to close - the file when the last file chunk is - encountered. When an error is encountered - the callback function is expected to clean - up after the aborted file transfer, such as - closing open file descriptors etc. In both - cases there will be no more calls to any of - the callback functions.</p> + the file when the last file chunk is + encountered. When an error is encountered + the callback function is expected to clean + up after the aborted file transfer, such as + closing open file descriptors etc. In both + cases there will be no more calls to any of + the callback functions.</p> + + <marker id="write"></marker> </desc> </func> + <func> <name>write(Bin, State) -> {more, NewState} | {last, FileSize} | {error, {Code, Text}}</name> <fsummary>Write a chunk to the file</fsummary> @@ -550,15 +579,18 @@ <desc> <p>Write a chunk to the file.</p> <p>The callback function is expected to close - the file when the last file chunk is - encountered. When an error is encountered - the callback function is expected to clean - up after the aborted file transfer, such as - closing open file descriptors etc. In both - cases there will be no more calls to any of - the callback functions.</p> + the file when the last file chunk is + encountered. When an error is encountered + the callback function is expected to clean + up after the aborted file transfer, such as + closing open file descriptors etc. In both + cases there will be no more calls to any of + the callback functions.</p> + + <marker id="abort"></marker> </desc> </func> + <func> <name>abort(Code, Text, State) -> ok</name> <fsummary>Abort the file transfer</fsummary> @@ -572,14 +604,14 @@ <desc> <p>Invoked when the file transfer is aborted.</p> <p>The callback function is expected to clean - up its used resources after the aborted file - transfer, such as closing open file - descriptors etc. The function will not be - invoked if any of the other callback - functions returns an error, as it is - expected that they already have cleaned up - the necessary resources. It will however be - invoked if the functions fails (crashes).</p> + up its used resources after the aborted file + transfer, such as closing open file + descriptors etc. The function will not be + invoked if any of the other callback + functions returns an error, as it is + expected that they already have cleaned up + the necessary resources. It will however be + invoked if the functions fails (crashes).</p> </desc> </func> </funcs> @@ -589,7 +621,9 @@ <title>LOGGER FUNCTIONS</title> <p>A <c>tftp_logger</c> callback module should be implemented as a - <c>tftp_logger</c> behavior and export the functions listed below.</p> + <c>tftp_logger</c> behavior and export the functions listed below.</p> + + <marker id="error_msg"></marker> </section> <funcs> @@ -602,7 +636,10 @@ <v>Reason = term()</v> </type> <desc> - <p>Log an error message. See <c>error_logger:error_msg/2 for details.</c> </p> + <p>Log an error message. + See <c>error_logger:error_msg/2 for details.</c> </p> + + <marker id="warning_msg"></marker> </desc> </func> @@ -615,7 +652,10 @@ <v>Reason = term()</v> </type> <desc> - <p>Log a warning message. See <c>error_logger:warning_msg/2 for details.</c> </p> + <p>Log a warning message. + See <c>error_logger:warning_msg/2 for details.</c> </p> + + <marker id="info_msg"></marker> </desc> </func> @@ -628,7 +668,8 @@ <v>Reason = term()</v> </type> <desc> - <p>Log an info message. See <c>error_logger:info_msg/2 for details.</c> </p> + <p>Log an info message. + See <c>error_logger:info_msg/2 for details.</c> </p> </desc> </func> </funcs> diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index 5ed2d98ba6..0a30fe1e20 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -158,7 +158,7 @@ request(Method, {http_options, HTTPOptions}, {options, Options}, {profile, Profile}]), - case http_uri:parse(Url, Options) of + case uri_parse(Url, Options) of {error, Reason} -> {error, Reason}; {ok, ParsedUrl} -> @@ -179,7 +179,7 @@ request(Method, {http_options, HTTPOptions}, {options, Options}, {profile, Profile}]), - case http_uri:parse(Url, Options) of + case uri_parse(Url, Options) of {error, Reason} -> {error, Reason}; {ok, ParsedUrl} -> @@ -328,7 +328,7 @@ store_cookies(SetCookieHeaders, Url, Profile) %% Since the Address part is not actually used %% by the manager when storing cookies, we dont %% care about ipv6-host-with-brackets. - {ok, {_, _, Host, Port, Path, _}} = http_uri:parse(Url), + {ok, {_, _, Host, Port, Path, _}} = uri_parse(Url), Address = {Host, Port}, ProfileName = profile_name(Profile), Cookies = httpc_cookie:cookies(SetCookieHeaders, Path, Host), @@ -1198,6 +1198,22 @@ validate_headers(RequestHeaders, _, _) -> RequestHeaders. +%%-------------------------------------------------------------------------- +%% These functions is just simple wrappers to parse specifically HTTP URIs +%%-------------------------------------------------------------------------- + +scheme_defaults() -> + [{http, 80}, {https, 443}]. + +uri_parse(URI) -> + http_uri:parse(URI, [{scheme_defaults, scheme_defaults()}]). + +uri_parse(URI, Opts) -> + http_uri:parse(URI, [{scheme_defaults, scheme_defaults()} | Opts]). + + +%%-------------------------------------------------------------------------- + child_name2info(undefined) -> {error, no_such_service}; child_name2info(httpc_manager) -> diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index 33b5dfe046..b225b43214 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -446,7 +446,7 @@ handle_call(which_cookies, _, #state{cookie_db = CookieDb} = State) -> handle_call({which_cookies, Url, Options}, _, #state{cookie_db = CookieDb} = State) -> ?hcrv("which cookies", [{url, Url}, {options, Options}]), - case http_uri:parse(Url, Options) of + case uri_parse(Url, Options) of {ok, {Scheme, _, Host, Port, Path, _}} -> CookieHeaders = httpc_cookie:header(CookieDb, Scheme, {Host, Port}, Path), @@ -894,6 +894,19 @@ make_db_name(ProfileName, Post) -> list_to_atom(atom_to_list(ProfileName) ++ Post). +%%-------------------------------------------------------------------------- +%% These functions is just simple wrappers to parse specifically HTTP URIs +%%-------------------------------------------------------------------------- + +scheme_defaults() -> + [{http, 80}, {https, 443}]. + +uri_parse(URI, Opts) -> + http_uri:parse(URI, [{scheme_defaults, scheme_defaults()} | Opts]). + + +%%-------------------------------------------------------------------------- + call(ProfileName, Msg) -> Timeout = infinity, diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl index 919115a23a..23924e355e 100644 --- a/lib/inets/src/http_client/httpc_response.erl +++ b/lib/inets/src/http_client/httpc_response.erl @@ -342,7 +342,7 @@ redirect(Response = {StatusLine, Headers, Body}, Request) -> RedirUrl -> UrlParseOpts = [{ipv6_host_with_brackets, Request#request.ipv6_host_with_brackets}], - case http_uri:parse(RedirUrl, UrlParseOpts) of + case uri_parse(RedirUrl, UrlParseOpts) of {error, no_scheme} when (Request#request.settings)#http_options.relaxed -> NewLocation = fix_relative_uri(Request, RedirUrl), @@ -437,3 +437,17 @@ format_response({StatusLine, Headers, Body}) -> end, {{StatusLine, http_response:header_list(Headers), NewBody}, Data}. +%%-------------------------------------------------------------------------- +%% These functions is just simple wrappers to parse specifically HTTP URIs +%%-------------------------------------------------------------------------- + +scheme_defaults() -> + [{http, 80}, {https, 443}]. + +uri_parse(URI, Opts) -> + http_uri:parse(URI, [{scheme_defaults, scheme_defaults()} | Opts]). + + +%%-------------------------------------------------------------------------- + + diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index 32c6305a79..5962001c3a 100644 --- a/lib/inets/src/http_lib/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -17,39 +17,95 @@ %% %CopyrightEnd% %% %% -%% RFC 3986 +%% This is from chapter 3, Syntax Components, of RFC 3986: +%% +%% The generic URI syntax consists of a hierarchical sequence of +%% components referred to as the scheme, authority, path, query, and +%% fragment. +%% +%% URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] +%% +%% hier-part = "//" authority path-abempty +%% / path-absolute +%% / path-rootless +%% / path-empty +%% +%% The scheme and path components are required, though the path may be +%% empty (no characters). When authority is present, the path must +%% either be empty or begin with a slash ("/") character. When +%% authority is not present, the path cannot begin with two slash +%% characters ("//"). These restrictions result in five different ABNF +%% rules for a path (Section 3.3), only one of which will match any +%% given URI reference. +%% +%% The following are two example URIs and their component parts: +%% +%% foo://example.com:8042/over/there?name=ferret#nose +%% \_/ \______________/\_________/ \_________/ \__/ +%% | | | | | +%% scheme authority path query fragment +%% | _____________________|__ +%% / \ / \ +%% urn:example:animal:ferret:nose +%% +%% scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) +%% authority = [ userinfo "@" ] host [ ":" port ] +%% userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) +%% %% -module(http_uri). -export([parse/1, parse/2, + scheme_defaults/0, encode/1, decode/1]). +-export_type([scheme/0, default_scheme_port_number/0]). + %%%========================================================================= %%% API %%%========================================================================= + +-type scheme() :: atom(). +-type default_scheme_port_number() :: pos_integer(). + +-spec scheme_defaults() -> + [{scheme(), default_scheme_port_number()}]. + +scheme_defaults() -> + [{http, 80}, + {https, 443}, + {ftp, 21}, + {ssh, 22}, + {sftp, 22}, + {tftp, 69}]. + parse(AbsURI) -> parse(AbsURI, []). parse(AbsURI, Opts) -> - case parse_scheme(AbsURI) of + case parse_scheme(AbsURI, Opts) of {error, Reason} -> {error, Reason}; - {Scheme, Rest} -> - case (catch parse_uri_rest(Scheme, Rest, Opts)) of - {UserInfo, Host, Port, Path, Query} -> + {Scheme, DefaultPort, Rest} -> + case (catch parse_uri_rest(Scheme, DefaultPort, Rest, Opts)) of + {ok, {UserInfo, Host, Port, Path, Query}} -> {ok, {Scheme, UserInfo, Host, Port, Path, Query}}; + {error, Reason} -> + {error, {Reason, Scheme, AbsURI}}; _ -> - {error, {malformed_url, AbsURI}} + {error, {malformed_url, Scheme, AbsURI}} end end. +reserved() -> + sets:from_list([$;, $:, $@, $&, $=, $+, $,, $/, $?, + $#, $[, $], $<, $>, $\", ${, $}, $|, + $\\, $', $^, $%, $ ]). + encode(URI) -> - Reserved = sets:from_list([$;, $:, $@, $&, $=, $+, $,, $/, $?, - $#, $[, $], $<, $>, $\", ${, $}, $|, - $\\, $', $^, $%, $ ]), - %% lists:append(lists:map(fun(Char) -> uri_encode(Char, Reserved) end, URI)). + Reserved = reserved(), lists:append([uri_encode(Char, Reserved) || Char <- URI]). decode(String) -> @@ -67,20 +123,31 @@ do_decode([]) -> %%% Internal functions %%%======================================================================== -parse_scheme(AbsURI) -> +which_scheme_defaults(Opts) -> + Key = scheme_defaults, + case lists:keysearch(Key, 1, Opts) of + {value, {Key, SchemeDefaults}} -> + SchemeDefaults; + false -> + scheme_defaults() + end. + +parse_scheme(AbsURI, Opts) -> case split_uri(AbsURI, ":", {error, no_scheme}, 1, 1) of {error, no_scheme} -> {error, no_scheme}; - {StrScheme, Rest} -> - case list_to_atom(http_util:to_lower(StrScheme)) of - Scheme when (Scheme =:= http) orelse (Scheme =:= https) -> - {Scheme, Rest}; - Scheme -> - {error, {not_supported_scheme, Scheme}} + {SchemeStr, Rest} -> + Scheme = list_to_atom(http_util:to_lower(SchemeStr)), + SchemeDefaults = which_scheme_defaults(Opts), + case lists:keysearch(Scheme, 1, SchemeDefaults) of + {value, {Scheme, DefaultPort}} -> + {Scheme, DefaultPort, Rest}; + false -> + {Scheme, no_default_port, Rest} end end. -parse_uri_rest(Scheme, "//" ++ URIPart, Opts) -> +parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) -> {Authority, PathQuery} = case split_uri(URIPart, "/", URIPart, 1, 0) of Split = {_, _} -> @@ -93,26 +160,25 @@ parse_uri_rest(Scheme, "//" ++ URIPart, Opts) -> {URIPart,""} end end, - {UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1), - {Host, Port} = parse_host_port(Scheme, HostPort, Opts), + {Host, Port} = parse_host_port(Scheme, DefaultPort, HostPort, Opts), {Path, Query} = parse_path_query(PathQuery), - {UserInfo, Host, Port, Path, Query}. + {ok, {UserInfo, Host, Port, Path, Query}}. parse_path_query(PathQuery) -> {Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0), {path(Path), Query}. -parse_host_port(Scheme,"[" ++ HostPort, Opts) -> %ipv6 - DefaultPort = default_port(Scheme), +%% In this version of the function, we no longer need +%% the Scheme argument, but just in case... +parse_host_port(_Scheme, DefaultPort, "[" ++ HostPort, Opts) -> %ipv6 {Host, ColonPort} = split_uri(HostPort, "\\]", {HostPort, ""}, 1, 1), Host2 = maybe_ipv6_host_with_brackets(Host, Opts), {_, Port} = split_uri(ColonPort, ":", {"", DefaultPort}, 0, 1), {Host2, int_port(Port)}; -parse_host_port(Scheme, HostPort, _Opts) -> - DefaultPort = default_port(Scheme), +parse_host_port(_Scheme, DefaultPort, HostPort, _Opts) -> {Host, Port} = split_uri(HostPort, ":", {HostPort, DefaultPort}, 1, 1), {Host, int_port(Port)}. @@ -133,15 +199,14 @@ maybe_ipv6_host_with_brackets(Host, Opts) -> Host end. -default_port(http) -> - 80; -default_port(https) -> - 443. int_port(Port) when is_integer(Port) -> Port; int_port(Port) when is_list(Port) -> - list_to_integer(Port). + list_to_integer(Port); +%% This is the case where no port was found and there was no default port +int_port(no_default_port) -> + throw({error, no_default_port}). path("") -> "/"; diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index 61bb5214f3..a116edef77 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -1974,7 +1974,7 @@ parse_url(Config) when is_list(Config) -> http_uri:parse("http://[2010:836B:4179::836B:4179]/foobar.html", [{foo, false}]), {error, - {malformed_url,"http://2010:836B:4179::836B:4179/foobar.html"}} = + {malformed_url, _, "http://2010:836B:4179::836B:4179/foobar.html"}} = http_uri:parse("http://2010:836B:4179::836B:4179/foobar.html"), %% ipv4 @@ -1990,8 +1990,8 @@ parse_url(Config) when is_list(Config) -> http_uri:parse("http://nisse:foobar@localhost:8888/foobar.html"), %% Scheme error - {error,no_scheme} = http_uri:parse("localhost/foobar.html"), - {error,{not_supported_scheme,localhost}} = + {error, no_scheme} = http_uri:parse("localhost/foobar.html"), + {error, {malformed_url, _, _}} = http_uri:parse("localhost:8888/foobar.html"), %% Query |