aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asn1/doc/src/notes.xml2
-rw-r--r--lib/common_test/doc/src/notes.xml2
-rw-r--r--lib/compiler/doc/src/notes.xml2
-rw-r--r--lib/crypto/doc/src/notes.xml2
-rw-r--r--lib/debugger/doc/src/notes.xml2
-rwxr-xr-xlib/dialyzer/doc/src/notes.xml2
-rw-r--r--lib/edoc/doc/src/notes.xml2
-rw-r--r--lib/erl_interface/doc/src/notes.xml2
-rw-r--r--lib/hipe/doc/src/notes.xml2
-rw-r--r--lib/inets/doc/src/httpc.xml48
-rw-r--r--lib/inets/doc/src/notes.xml38
-rw-r--r--lib/inets/src/ftp/ftp.erl259
-rw-r--r--lib/inets/src/http_client/httpc.erl82
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl18
-rw-r--r--lib/inets/src/http_client/httpc_request.erl102
-rw-r--r--lib/inets/src/inets_app/inets.appup.src32
-rw-r--r--lib/inets/test/ftp_SUITE.erl53
-rw-r--r--lib/inets/test/httpc_SUITE.erl151
-rw-r--r--lib/jinterface/doc/src/notes.xml2
-rw-r--r--lib/kernel/doc/src/notes.xml2
-rw-r--r--lib/mnesia/doc/src/notes.xml2
-rw-r--r--lib/observer/doc/src/notes.xml2
-rw-r--r--lib/odbc/doc/src/notes.xml2
-rw-r--r--lib/public_key/doc/src/notes.xml2
-rw-r--r--lib/runtime_tools/doc/src/notes.xml2
-rw-r--r--lib/sasl/doc/src/notes.xml2
-rw-r--r--lib/stdlib/doc/src/notes.xml2
-rw-r--r--lib/test_server/doc/src/notes.xml2
-rw-r--r--lib/tools/doc/src/notes.xml2
-rw-r--r--lib/wx/doc/src/notes.xml2
-rw-r--r--lib/xmerl/doc/src/notes.xml2
31 files changed, 656 insertions, 171 deletions
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index 77769afcd4..ccff9892c6 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index fef1222fcb..15c7e2a9f2 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 25a6db4ce0..5757d0c1cb 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 5e9bda3920..044eb9e992 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2010</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 3aa169a135..93e447848a 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index f132a50e0d..0dadf647c3 100755
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2010</year>
+ <year>2006</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index c18a126264..630271b115 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2007</year><year>2010</year>
+ <year>2007</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index 784ba78d3e..d83a8307e4 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 434bfac64c..5c06e5e558 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2010</year>
+ <year>2006</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index 8f68087871..532f5eefde 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -76,21 +76,29 @@ socket_opt() = See the Options used by gen_tcp(3) and
<p>For more information about HTTP see rfc 2616</p>
<code type="none"><![CDATA[
-method() = head | get | put | post | trace | options | delete
-request() = {url(), headers()} |
- {url(), headers(), content_type(), body()}
-url() = string() - Syntax according to the URI definition in rfc 2396, ex: "http://www.erlang.org"
-status_line() = {http_version(), status_code(), reason_phrase()}
-http_version() = string() ex: "HTTP/1.1"
-status_code() = integer()
-reason_phrase() = string()
-content_type() = string()
-headers() = [header()]
-header() = {field(), value()}
-field() = string()
-value() = string()
-body() = string() | binary()
-filename() = string()
+method() = head | get | put | post | trace | options | delete
+request() = {url(), headers()} |
+ {url(), headers(), content_type(), body()}
+url() = string() - Syntax according to the URI definition in rfc 2396, ex: "http://www.erlang.org"
+status_line() = {http_version(), status_code(), reason_phrase()}
+http_version() = string() ex: "HTTP/1.1"
+status_code() = integer()
+reason_phrase() = string()
+content_type() = string()
+headers() = [header()]
+header() = {field(), value()}
+field() = string()
+value() = string()
+body() = string() |
+ binary() |
+ {fun(accumulator()) -> body_processing_result(),
+ accumulator()} |
+ {chunkify,
+ fun(accumulator()) -> body_processing_result(),
+ accumulator()}
+body_processing_result() = eof | {ok, iolist(), accumulator()}
+accumulator() = term()
+filename() = string()
]]></code>
</section>
@@ -142,8 +150,9 @@ ssl_options() = {verify, code()} |
<fsummary>Sends a get HTTP-request</fsummary>
<type>
<v>Url = url() </v>
- <v>Result = {status_line(), headers(), body()} |
- {status_code(), body()} | request_id() </v>
+ <v>Result = {status_line(), headers(), Body} |
+ {status_code(), Body} | request_id() </v>
+ <v>Body = string() | binary()</v>
<v>Profile = profile()</v>
<v>Reason = term() </v>
</type>
@@ -191,8 +200,9 @@ ssl_options() = {verify, code()} |
<v>Function = atom() </v>
<v>Args = list() </v>
<v>body_format() = string | binary </v>
- <v>Result = {status_line(), headers(), body()} |
- {status_code(), body()} | request_id() </v>
+ <v>Result = {status_line(), headers(), Body} |
+ {status_code(), Body} | request_id() </v>
+ <v>Body = string() | binary()</v>
<v>Profile = profile() </v>
<v>Reason = {connect_failed, term()} |
{send_failed, term()} | term() </v>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 50dbb7d3da..5343d28976 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -38,37 +38,47 @@
<!--
<p>-</p>
-->
-
<list>
<item>
+ <p>[httpc] Add support for upload body streaming (PUT and POST).</p>
+ <p>For more info,
+ see the definition of the <c>Body</c> argument of the
+ <seealso marker="httpc#request2">request/4,5</seealso>
+ function. </p>
+ <p>Filipe David Manana</p>
+ <p>Own Id: OTP-9094</p>
+ </item>
+
+ <item>
+ <p>[ftp] Added (type) spec for all exported functions.</p>
+ <p>Own Id: OTP-9114 Aux Id: seq11799</p>
+
+ <item>
<p>[httpd]
<seealso marker="mod_esi#deliver">mod_esi:deliver/2</seealso>
made to accept binary data. </p>
<p>Bernard Duggan</p>
<p>Own Id: OTP-9123</p>
</item>
+ </item>
</list>
-
</section>
<section><title>Fixed Bugs and Malfunctions</title>
<p>-</p>
+
<!--
- <list>
- <item>
- <p>[httpd] httpd_response:send_chunk handles empty list and
- empty binary - i.e. no chunk is sent, but it does
- not handle a list with an empty binary [&lt;&lt;&gt;&gt;].
- This will be sent as an empty chunk - which in turn
- will be encoded by http_chunk to the same as a final
- chunk, which will make the http client believe that
- the end of the page is reached.</p>
- <p>Own Id: OTP-8906</p>
- </item>
- </list>
+ <list>
+ <item>
+ <p>[httpc] Pipelined and queued requests not processed when
+ connection closed remotelly.</p>
+ <p>Own Id: OTP-8906</p>
+ </item>
+ </list>
-->
</section>
+
</section> <!-- 5.6 -->
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index 5ad74851c8..fe6cb0c191 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -92,6 +92,12 @@
}).
+-type shortage_reason() :: 'etnospc' | 'epnospc'.
+-type restriction_reason() :: 'epath' | 'efnamena' | 'elogin' | 'enotbinary'.
+-type common_reason() :: 'econn' | 'eclosed' | term().
+-type file_write_error_reason() :: term(). % See file:write for more info
+
+
%%%=========================================================================
%%% API - CLIENT FUNCTIONS
%%%=========================================================================
@@ -106,6 +112,9 @@
%% Description: Start an ftp client and connect to a host.
%%--------------------------------------------------------------------------
+-spec open(Host :: string() | inet:ip_address()) ->
+ {'ok', Pid :: pid()} | {'error', Reason :: 'ehost' | term()}.
+
%% <BACKWARD-COMPATIBILLITY>
open({option_list, Options}) when is_list(Options) ->
try
@@ -126,6 +135,9 @@ open({option_list, Options}) when is_list(Options) ->
open(Host) ->
open(Host, []).
+-spec open(Host :: string() | inet:ip_address(), Opts :: list()) ->
+ {'ok', Pid :: pid()} | {'error', Reason :: 'ehost' | term()}.
+
%% <BACKWARD-COMPATIBILLITY>
open(Host, Port) when is_integer(Port) ->
open(Host, [{port, Port}]);
@@ -161,12 +173,24 @@ open(Host, Opts) when is_list(Opts) ->
%%
%% Description: Login with or without a supplied account name.
%%--------------------------------------------------------------------------
+-spec user(Pid :: pid(),
+ User :: string(),
+ Pass :: string()) ->
+ 'ok' | {'error', Reason :: 'euser' | common_reason()}.
+
user(Pid, User, Pass) ->
call(Pid, {user, User, Pass}, atom).
+-spec user(Pid :: pid(),
+ User :: string(),
+ Pass :: string(),
+ Acc :: string()) ->
+ 'ok' | {'error', Reason :: 'euser' | common_reason()}.
+
user(Pid, User, Pass, Acc) ->
call(Pid, {user, User, Pass, Acc}, atom).
+
%%--------------------------------------------------------------------------
%% account(Pid, Acc) -> ok | {error, eacct}
%% Pid = pid()
@@ -174,9 +198,14 @@ user(Pid, User, Pass, Acc) ->
%%
%% Description: Set a user Account.
%%--------------------------------------------------------------------------
+
+-spec account(Pid :: pid(), Acc :: string()) ->
+ 'ok' | {'error', Reason :: 'eacct' | common_reason()}.
+
account(Pid, Acc) ->
call(Pid, {account, Acc}, atom).
+
%%--------------------------------------------------------------------------
%% pwd(Pid) -> {ok, Dir} | {error, elogin} | {error, econn}
%% Pid = pid()
@@ -184,19 +213,30 @@ account(Pid, Acc) ->
%%
%% Description: Get the current working directory at remote server.
%%--------------------------------------------------------------------------
+
+-spec pwd(Pid :: pid()) ->
+ {'ok', Dir :: string()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
pwd(Pid) ->
call(Pid, pwd, ctrl).
+
%%--------------------------------------------------------------------------
-%% lpwd(Pid) -> {ok, Dir} | {error, elogin}
+%% lpwd(Pid) -> {ok, Dir}
%% Pid = pid()
%% Dir = string()
%%
%% Description: Get the current working directory at local server.
%%--------------------------------------------------------------------------
+
+-spec lpwd(Pid :: pid()) ->
+ {'ok', Dir :: string()}.
+
lpwd(Pid) ->
call(Pid, lpwd, string).
+
%%--------------------------------------------------------------------------
%% cd(Pid, Dir) -> ok | {error, epath} | {error, elogin} | {error, econn}
%% Pid = pid()
@@ -204,9 +244,14 @@ lpwd(Pid) ->
%%
%% Description: Change current working directory at remote server.
%%--------------------------------------------------------------------------
+
+-spec cd(Pid :: pid(), Dir :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
cd(Pid, Dir) ->
call(Pid, {cd, Dir}, atom).
+
%%--------------------------------------------------------------------------
%% lcd(Pid, Dir) -> ok | {error, epath}
%% Pid = pid()
@@ -214,9 +259,14 @@ cd(Pid, Dir) ->
%%
%% Description: Change current working directory for the local client.
%%--------------------------------------------------------------------------
+
+-spec lcd(Pid :: pid(), Dir :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason()}.
+
lcd(Pid, Dir) ->
call(Pid, {lcd, Dir}, string).
+
%%--------------------------------------------------------------------------
%% ls(Pid) -> Result
%% ls(Pid, <Dir>) -> Result
@@ -229,11 +279,22 @@ lcd(Pid, Dir) ->
%%
%% Description: Returns a list of files in long format.
%%--------------------------------------------------------------------------
+
+-spec ls(Pid :: pid()) ->
+ {'ok', Listing :: string()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
ls(Pid) ->
ls(Pid, "").
+
+-spec ls(Pid :: pid(), Dir :: string()) ->
+ {'ok', Listing :: string()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
ls(Pid, Dir) ->
call(Pid, {dir, long, Dir}, string).
+
%%--------------------------------------------------------------------------
%% nlist(Pid) -> Result
%% nlist(Pid, Pathname) -> Result
@@ -246,21 +307,37 @@ ls(Pid, Dir) ->
%%
%% Description: Returns a list of files in short format
%%--------------------------------------------------------------------------
+
+-spec nlist(Pid :: pid()) ->
+ {'ok', Listing :: string()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
nlist(Pid) ->
nlist(Pid, "").
+
+-spec nlist(Pid :: pid(), Pathname :: string()) ->
+ {'ok', Listing :: string()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
nlist(Pid, Dir) ->
call(Pid, {dir, short, Dir}, string).
+
%%--------------------------------------------------------------------------
-%% rename(Pid, CurrFile, NewFile) -> ok | {error, epath} | {error, elogin}
-%% | {error, econn}
+%% rename(Pid, Old, New) -> ok | {error, epath} | {error, elogin}
+%% | {error, econn}
%% Pid = pid()
%% CurrFile = NewFile = string()
%%
%% Description: Rename a file at remote server.
%%--------------------------------------------------------------------------
-rename(Pid, CurrFile, NewFile) ->
- call(Pid, {rename, CurrFile, NewFile}, string).
+
+-spec rename(Pid :: pid(), Old :: string(), New :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
+rename(Pid, Old, New) ->
+ call(Pid, {rename, Old, New}, string).
+
%%--------------------------------------------------------------------------
%% delete(Pid, File) -> ok | {error, epath} | {error, elogin} |
@@ -270,9 +347,14 @@ rename(Pid, CurrFile, NewFile) ->
%%
%% Description: Remove file at remote server.
%%--------------------------------------------------------------------------
+
+-spec delete(Pid :: pid(), File :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
delete(Pid, File) ->
call(Pid, {delete, File}, string).
+
%%--------------------------------------------------------------------------
%% mkdir(Pid, Dir) -> ok | {error, epath} | {error, elogin} | {error, econn}
%% Pid = pid(),
@@ -280,9 +362,14 @@ delete(Pid, File) ->
%%
%% Description: Make directory at remote server.
%%--------------------------------------------------------------------------
+
+-spec mkdir(Pid :: pid(), Dir :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
mkdir(Pid, Dir) ->
call(Pid, {mkdir, Dir}, atom).
+
%%--------------------------------------------------------------------------
%% rmdir(Pid, Dir) -> ok | {error, epath} | {error, elogin} | {error, econn}
%% Pid = pid(),
@@ -290,9 +377,14 @@ mkdir(Pid, Dir) ->
%%
%% Description: Remove directory at remote server.
%%--------------------------------------------------------------------------
+
+-spec rmdir(Pid :: pid(), Dir :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
rmdir(Pid, Dir) ->
call(Pid, {rmdir, Dir}, atom).
+
%%--------------------------------------------------------------------------
%% type(Pid, Type) -> ok | {error, etype} | {error, elogin} | {error, econn}
%% Pid = pid()
@@ -300,23 +392,41 @@ rmdir(Pid, Dir) ->
%%
%% Description: Set transfer type.
%%--------------------------------------------------------------------------
+
+-spec type(Pid :: pid(), Type :: ascii | binary) ->
+ 'ok' |
+ {'error', Reason :: 'etype' | restriction_reason() | common_reason()}.
+
type(Pid, Type) ->
call(Pid, {type, Type}, atom).
+
%%--------------------------------------------------------------------------
-%% recv(Pid, RemoteFileName <LocalFileName>) -> ok | {error, epath} |
+%% recv(Pid, RemoteFileName [, LocalFileName]) -> ok | {error, epath} |
%% {error, elogin} | {error, econn}
%% Pid = pid()
%% RemoteFileName = LocalFileName = string()
%%
%% Description: Transfer file from remote server.
%%--------------------------------------------------------------------------
+
+-spec recv(Pid :: pid(), RemoteFileName :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() |
+ common_reason() |
+ file_write_error_reason()}.
+
recv(Pid, RemotFileName) ->
recv(Pid, RemotFileName, RemotFileName).
+-spec recv(Pid :: pid(),
+ RemoteFileName :: string(),
+ LocalFileName :: string()) ->
+ 'ok' | {'error', Reason :: term()}.
+
recv(Pid, RemotFileName, LocalFileName) ->
call(Pid, {recv, RemotFileName, LocalFileName}, atom).
+
%%--------------------------------------------------------------------------
%% recv_bin(Pid, RemoteFile) -> {ok, Bin} | {error, epath} | {error, elogin}
%% | {error, econn}
@@ -326,9 +436,16 @@ recv(Pid, RemotFileName, LocalFileName) ->
%%
%% Description: Transfer file from remote server into binary.
%%--------------------------------------------------------------------------
+
+-spec recv_bin(Pid :: pid(),
+ RemoteFile :: string()) ->
+ {'ok', Bin :: binary()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
recv_bin(Pid, RemoteFile) ->
call(Pid, {recv_bin, RemoteFile}, bin).
+
%%--------------------------------------------------------------------------
%% recv_chunk_start(Pid, RemoteFile) -> ok | {error, elogin} | {error, epath}
%% | {error, econn}
@@ -337,9 +454,15 @@ recv_bin(Pid, RemoteFile) ->
%%
%% Description: Start receive of chunks of remote file.
%%--------------------------------------------------------------------------
+
+-spec recv_chunk_start(Pid :: pid(),
+ RemoteFile :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
recv_chunk_start(Pid, RemoteFile) ->
call(Pid, {recv_chunk_start, RemoteFile}, atom).
+
%%--------------------------------------------------------------------------
%% recv_chunk(Pid, RemoteFile) -> ok | {ok, Bin} | {error, Reason}
%% Pid = pid()
@@ -347,24 +470,47 @@ recv_chunk_start(Pid, RemoteFile) ->
%%
%% Description: Transfer file from remote server into binary in chunks
%%--------------------------------------------------------------------------
+
+-spec recv_chunk(Pid :: pid()) ->
+ 'ok' |
+ {'ok', Bin :: binary()} |
+ {'error', Reason :: restriction_reason() | common_reason()}.
+
recv_chunk(Pid) ->
call(Pid, recv_chunk, atom).
+
%%--------------------------------------------------------------------------
-%% send(Pid, LocalFileName <RemotFileName>) -> ok | {error, epath}
-%% | {error, elogin}
-%% | {error, econn}
+%% send(Pid, LocalFileName [, RemotFileName]) -> ok | {error, epath}
+%% | {error, elogin}
+%% | {error, econn}
%% Pid = pid()
%% LocalFileName = RemotFileName = string()
%%
%% Description: Transfer file to remote server.
%%--------------------------------------------------------------------------
+
+-spec send(Pid :: pid(), LocalFileName :: string()) ->
+ 'ok' |
+ {'error', Reason :: restriction_reason() |
+ common_reason() |
+ shortage_reason()}.
+
send(Pid, LocalFileName) ->
send(Pid, LocalFileName, LocalFileName).
+-spec send(Pid :: pid(),
+ LocalFileName :: string(),
+ RemoteFileName :: string()) ->
+ 'ok' |
+ {'error', Reason :: restriction_reason() |
+ common_reason() |
+ shortage_reason()}.
+
send(Pid, LocalFileName, RemotFileName) ->
call(Pid, {send, LocalFileName, RemotFileName}, atom).
+
%%--------------------------------------------------------------------------
%% send_bin(Pid, Bin, RemoteFile) -> ok | {error, epath} | {error, elogin}
%% | {error, enotbinary} | {error, econn}
@@ -374,11 +520,19 @@ send(Pid, LocalFileName, RemotFileName) ->
%%
%% Description: Transfer a binary to a remote file.
%%--------------------------------------------------------------------------
+
+-spec send_bin(Pid :: pid(), Bin :: binary(), RemoteFile :: string()) ->
+ 'ok' |
+ {'error', Reason :: restriction_reason() |
+ common_reason() |
+ shortage_reason()}.
+
send_bin(Pid, Bin, RemoteFile) when is_binary(Bin) ->
call(Pid, {send_bin, Bin, RemoteFile}, atom);
send_bin(_Pid, _Bin, _RemoteFile) ->
{error, enotbinary}.
+
%%--------------------------------------------------------------------------
%% send_chunk_start(Pid, RemoteFile) -> ok | {error, elogin} | {error, epath}
%% | {error, econn}
@@ -387,9 +541,14 @@ send_bin(_Pid, _Bin, _RemoteFile) ->
%%
%% Description: Start transfer of chunks to remote file.
%%--------------------------------------------------------------------------
+
+-spec send_chunk_start(Pid :: pid(), RemoteFile :: string()) ->
+ 'ok' | {'error', Reason :: restriction_reason() | common_reason()}.
+
send_chunk_start(Pid, RemoteFile) ->
call(Pid, {send_chunk_start, RemoteFile}, atom).
+
%%--------------------------------------------------------------------------
%% append_chunk_start(Pid, RemoteFile) -> ok | {error, elogin} |
%% {error, epath} | {error, econn}
@@ -398,9 +557,14 @@ send_chunk_start(Pid, RemoteFile) ->
%%
%% Description: Start append chunks of data to remote file.
%%--------------------------------------------------------------------------
+
+-spec append_chunk_start(Pid :: pid(), RemoteFile :: string()) ->
+ 'ok' | {'error', Reason :: term()}.
+
append_chunk_start(Pid, RemoteFile) ->
call(Pid, {append_chunk_start, RemoteFile}, atom).
+
%%--------------------------------------------------------------------------
%% send_chunk(Pid, Bin) -> ok | {error, elogin} | {error, enotbinary}
%% | {error, echunk} | {error, econn}
@@ -409,11 +573,19 @@ append_chunk_start(Pid, RemoteFile) ->
%%
%% Purpose: Send chunk to remote file.
%%--------------------------------------------------------------------------
+
+-spec send_chunk(Pid :: pid(), Bin :: binary()) ->
+ 'ok' |
+ {'error', Reason :: 'echunk' |
+ restriction_reason() |
+ common_reason()}.
+
send_chunk(Pid, Bin) when is_binary(Bin) ->
call(Pid, {transfer_chunk, Bin}, atom);
send_chunk(_Pid, _Bin) ->
{error, enotbinary}.
+
%%--------------------------------------------------------------------------
%% append_chunk(Pid, Bin) -> ok | {error, elogin} | {error, enotbinary}
%% | {error, echunk} | {error, econn}
@@ -422,11 +594,19 @@ send_chunk(_Pid, _Bin) ->
%%
%% Description: Append chunk to remote file.
%%--------------------------------------------------------------------------
+
+-spec append_chunk(Pid :: pid(), Bin :: binary()) ->
+ 'ok' |
+ {'error', Reason :: 'echunk' |
+ restriction_reason() |
+ common_reason()}.
+
append_chunk(Pid, Bin) when is_binary(Bin) ->
call(Pid, {transfer_chunk, Bin}, atom);
append_chunk(_Pid, _Bin) ->
{error, enotbinary}.
+
%%--------------------------------------------------------------------------
%% send_chunk_end(Pid) -> ok | {error, elogin} | {error, echunk}
%% | {error, econn}
@@ -434,9 +614,17 @@ append_chunk(_Pid, _Bin) ->
%%
%% Description: End sending of chunks to remote file.
%%--------------------------------------------------------------------------
+
+-spec send_chunk_end(Pid :: pid()) ->
+ 'ok' |
+ {'error', Reason :: restriction_reason() |
+ common_reason() |
+ shortage_reason()}.
+
send_chunk_end(Pid) ->
call(Pid, chunk_end, atom).
+
%%--------------------------------------------------------------------------
%% append_chunk_end(Pid) -> ok | {error, elogin} | {error, echunk}
%% | {error, econn}
@@ -444,23 +632,47 @@ send_chunk_end(Pid) ->
%%
%% Description: End appending of chunks to remote file.
%%--------------------------------------------------------------------------
+
+-spec append_chunk_end(Pid :: pid()) ->
+ 'ok' |
+ {'error', Reason :: restriction_reason() |
+ common_reason() |
+ shortage_reason()}.
+
append_chunk_end(Pid) ->
call(Pid, chunk_end, atom).
+
%%--------------------------------------------------------------------------
-%% append(Pid, LocalFileName, RemotFileName) -> ok | {error, epath}
-%% | {error, elogin} | {error, econn}
+%% append(Pid, LocalFileName [, RemotFileName]) -> ok | {error, epath}
+%% | {error, elogin}
+%% | {error, econn}
%% Pid = pid()
%% LocalFileName = RemotFileName = string()
%%
%% Description: Append the local file to the remote file
%%--------------------------------------------------------------------------
+
+-spec append(Pid :: pid(), LocalFileName :: string()) ->
+ 'ok' |
+ {'error', Reason :: 'epath' |
+ 'elogin' |
+ 'etnospc' |
+ 'epnospc' |
+ 'efnamena' | common_reason()}.
+
append(Pid, LocalFileName) ->
append(Pid, LocalFileName, LocalFileName).
+-spec append(Pid :: pid(),
+ LocalFileName :: string(),
+ RemoteFileName :: string()) ->
+ 'ok' | {'error', Reason :: term()}.
+
append(Pid, LocalFileName, RemotFileName) ->
call(Pid, {append, LocalFileName, RemotFileName}, atom).
+
%%--------------------------------------------------------------------------
%% append_bin(Pid, Bin, RemoteFile) -> ok | {error, epath} | {error, elogin}
%% | {error, enotbinary} | {error, econn}
@@ -470,27 +682,44 @@ append(Pid, LocalFileName, RemotFileName) ->
%%
%% Purpose: Append a binary to a remote file.
%%--------------------------------------------------------------------------
+
+-spec append_bin(Pid :: pid(),
+ Bin :: binary(),
+ RemoteFile :: string()) ->
+ 'ok' |
+ {'error', Reason :: restriction_reason() |
+ common_reason() |
+ shortage_reason()}.
+
append_bin(Pid, Bin, RemoteFile) when is_binary(Bin) ->
call(Pid, {append_bin, Bin, RemoteFile}, atom);
append_bin(_Pid, _Bin, _RemoteFile) ->
{error, enotbinary}.
+
%%--------------------------------------------------------------------------
-%% quote(Pid, Cmd) -> ok
+%% quote(Pid, Cmd) -> list()
%% Pid = pid()
%% Cmd = string()
%%
%% Description: Send arbitrary ftp command.
%%--------------------------------------------------------------------------
+
+-spec quote(Pid :: pid(), Cmd :: string()) -> list().
+
quote(Pid, Cmd) when is_list(Cmd) ->
call(Pid, {quote, Cmd}, atom).
+
%%--------------------------------------------------------------------------
%% close(Pid) -> ok
%% Pid = pid()
%%
%% Description: End the ftp session.
%%--------------------------------------------------------------------------
+
+-spec close(Pid :: pid()) -> 'ok'.
+
close(Pid) ->
cast(Pid, close),
ok.
@@ -502,9 +731,13 @@ close(Pid) ->
%%
%% Description: Return diagnostics.
%%--------------------------------------------------------------------------
+
+-spec formaterror(Tag :: term()) -> string().
+
formaterror(Tag) ->
ftp_response:error_string(Tag).
+
info(Pid) ->
call(Pid, info, list).
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
index 04fae13b20..b70b16f57f 100644
--- a/lib/inets/src/http_client/httpc.erl
+++ b/lib/inets/src/http_client/httpc.erl
@@ -126,7 +126,10 @@ request(Url, Profile) ->
%% Header = {Field, Value}
%% Field = string()
%% Value = string()
-%% Body = string() | binary() - HTLM-code
+%% Body = string() | binary() | {fun(SendAcc) -> SendFunResult, SendAcc} |
+%% {chunkify, fun(SendAcc) -> SendFunResult, SendAcc} - HTLM-code
+%% SendFunResult = eof | {ok, iolist(), NewSendAcc}
+%% SendAcc = NewSendAcc = term()
%%
%% Description: Sends a HTTP-request. The function can be both
%% syncronus and asynchronous in the later case the function will
@@ -426,26 +429,44 @@ service_info(Pid) ->
handle_request(Method, Url,
{Scheme, UserInfo, Host, Port, Path, Query},
- Headers, ContentType, Body,
+ Headers0, ContentType, Body0,
HTTPOptions0, Options0, Profile) ->
- Started = http_util:timestamp(),
- NewHeaders = [{http_util:to_lower(Key), Val} || {Key, Val} <- Headers],
+ Started = http_util:timestamp(),
+ NewHeaders0 = [{http_util:to_lower(Key), Val} || {Key, Val} <- Headers0],
try
begin
+ ?hcrt("begin processing", [{started, Started},
+ {new_headers, NewHeaders0}]),
+
+ {NewHeaders, Body} =
+ case Body0 of
+ {chunkify, ProcessBody, Acc}
+ when is_function(ProcessBody, 1) ->
+ NewHeaders1 = ensure_chunked_encoding(NewHeaders0),
+ Body1 = {mk_chunkify_fun(ProcessBody), Acc},
+ {NewHeaders1, Body1};
+ {ProcessBody, _}
+ when is_function(ProcessBody, 1) ->
+ {NewHeaders0, Body0};
+ _ when is_list(Body0) orelse is_binary(Body0) ->
+ {NewHeaders0, Body0};
+ _ ->
+ throw({error, {bad_body, Body0}})
+ end,
+
HTTPOptions = http_options(HTTPOptions0),
Options = request_options(Options0),
Sync = proplists:get_value(sync, Options),
Stream = proplists:get_value(stream, Options),
Host2 = header_host(Scheme, Host, Port),
HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions),
- Receiver = proplists:get_value(receiver, Options),
- SocketOpts = proplists:get_value(socket_opts, Options),
- UrlEncodeBool = HTTPOptions#http_options.url_encode,
- MaybeEscPath = url_encode(Path, UrlEncodeBool),
- MaybeEscQuery = url_encode(Query, UrlEncodeBool),
- AbsUri = url_encode(Url, UrlEncodeBool),
+ Receiver = proplists:get_value(receiver, Options),
+ SocketOpts = proplists:get_value(socket_opts, Options),
+ MaybeEscPath = maybe_encode_uri(HTTPOptions, Path),
+ MaybeEscQuery = maybe_encode_uri(HTTPOptions, Query),
+ AbsUri = maybe_encode_uri(HTTPOptions, Url),
Request = #request{from = Receiver,
scheme = Scheme,
@@ -458,38 +479,71 @@ handle_request(Method, Url,
settings = HTTPOptions,
abs_uri = AbsUri,
userinfo = UserInfo,
- stream = Stream,
- headers_as_is = headers_as_is(Headers, Options),
+ stream = Stream,
+ headers_as_is = headers_as_is(Headers0, Options),
socket_opts = SocketOpts,
started = Started},
+
case httpc_manager:request(Request, profile_name(Profile)) of
{ok, RequestId} ->
handle_answer(RequestId, Sync, Options);
{error, Reason} ->
+ ?hcrd("request failed", [{reason, Reason}]),
{error, Reason}
end
end
catch
error:{noproc, _} ->
+ ?hcrv("noproc", [{profile, Profile}]),
{error, {not_started, Profile}};
throw:Error ->
+ ?hcrv("throw", [{error, Error}]),
Error
end.
-url_encode(URI, true) ->
+ensure_chunked_encoding(Hdrs) ->
+ Key = "transfer-encoding",
+ lists:keystore(Key, 1, Hdrs, {Key, "chunked"}).
+
+maybe_encode_uri(#http_options{url_encode = true}, URI) ->
http_uri:encode(URI);
-url_encode(URI, false) ->
+maybe_encode_uri(_, URI) ->
URI.
+mk_chunkify_fun(ProcessBody) ->
+ fun(eof_body) ->
+ eof;
+ (Acc) ->
+ case ProcessBody(Acc) of
+ eof ->
+ {ok, <<"0\r\n\r\n">>, eof_body};
+ {ok, Data, NewAcc} ->
+ {ok, mk_chunk_bin(Data), NewAcc}
+ end
+ end.
+
+mk_chunk_bin(Data) ->
+ Bin = iolist_to_binary(Data),
+ iolist_to_binary([hex_size(Bin), "\r\n", Bin, "\r\n"]).
+
+hex_size(Bin) ->
+ hd(io_lib:format("~.16B", [size(Bin)])).
+
+
handle_answer(RequestId, false, _) ->
{ok, RequestId};
handle_answer(RequestId, true, Options) ->
receive
{http, {RequestId, saved_to_file}} ->
+ ?hcrt("received saved-to-file", [{request_id, RequestId}]),
{ok, saved_to_file};
{http, {RequestId, {_,_,_} = Result}} ->
+ ?hcrt("received answer", [{request_id, RequestId},
+ {result, Result}]),
return_answer(Options, Result);
{http, {RequestId, {error, Reason}}} ->
+ ?hcrt("received error", [{request_id, RequestId},
+ {reason, Reason}]),
{error, Reason}
end.
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index cb6f3e2841..5e22400fe0 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1724,9 +1724,27 @@ handle_verbose(_) ->
%% ok.
+send_raw(#session{socket = Socket, socket_type = SocketType},
+ {ProcessBody, Acc}) when is_function(ProcessBody, 1) ->
+ ?hcrt("send raw", [{acc, Acc}]),
+ send_raw(SocketType, Socket, ProcessBody, Acc);
send_raw(#session{socket = Socket, socket_type = SocketType}, Body) ->
http_transport:send(SocketType, Socket, Body).
+send_raw(SocketType, Socket, ProcessBody, Acc) ->
+ case ProcessBody(Acc) of
+ eof ->
+ ok;
+ {ok, Data, NewAcc} ->
+ DataBin = iolist_to_binary(Data),
+ ?hcrd("send", [{data, DataBin}]),
+ case http_transport:send(SocketType, Socket, DataBin) of
+ ok ->
+ send_raw(SocketType, Socket, ProcessBody, NewAcc);
+ Error ->
+ Error
+ end
+ end.
call(Msg, Pid) ->
diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl
index d4df97ad40..0d602adb11 100644
--- a/lib/inets/src/http_client/httpc_request.erl
+++ b/lib/inets/src/http_client/httpc_request.erl
@@ -79,37 +79,65 @@ send(SendAddr, Socket, SocketType,
{settings, HttpOptions},
{userinfo, UserInfo}]),
- TmpHeaders = handle_user_info(UserInfo, Headers),
+ TmpHdrs = handle_user_info(UserInfo, Headers),
- {TmpHeaders2, Body} =
- post_data(Method, TmpHeaders, Content, HeadersAsIs),
+ {TmpHdrs2, Body} = post_data(Method, TmpHdrs, Content, HeadersAsIs),
- {NewHeaders, Uri} = case Address of
- SendAddr ->
- {TmpHeaders2, Path ++ Query};
- _Proxy ->
- TmpHeaders3 =
- handle_proxy(HttpOptions, TmpHeaders2),
- {TmpHeaders3, AbsUri}
- end,
-
- FinalHeaders = case NewHeaders of
- HeaderList when is_list(HeaderList) ->
- http_headers(HeaderList, []);
- _ ->
- http_request:http_headers(NewHeaders)
- end,
+ {NewHeaders, Uri} =
+ case Address of
+ SendAddr ->
+ {TmpHdrs2, Path ++ Query};
+ _Proxy ->
+ TmpHdrs3 = handle_proxy(HttpOptions, TmpHdrs2),
+ {TmpHdrs3, AbsUri}
+ end,
+
+ FinalHeaders =
+ case NewHeaders of
+ HeaderList when is_list(HeaderList) ->
+ http_headers(HeaderList, []);
+ _ ->
+ http_request:http_headers(NewHeaders)
+ end,
Version = HttpOptions#http_options.version,
- Message = [method(Method), " ", Uri, " ",
- version(Version), ?CRLF,
- headers(FinalHeaders, Version), ?CRLF, Body],
+ do_send_body(SocketType, Socket, Method, Uri, Version, FinalHeaders, Body).
+
+
+do_send_body(SocketType, Socket, Method, Uri, Version, Headers,
+ {ProcessBody, Acc}) when is_function(ProcessBody, 1) ->
+ ?hcrt("send", [{acc, Acc}]),
+ case do_send_body(SocketType, Socket, Method, Uri, Version, Headers, []) of
+ ok ->
+ do_send_body(SocketType, Socket, ProcessBody, Acc);
+ Error ->
+ Error
+ end;
+do_send_body(SocketType, Socket, Method, Uri, Version, Headers, Body) ->
+ ?hcrt("create message", [{body, Body}]),
+ Message = [method(Method), " ", Uri, " ",
+ version(Version), ?CRLF,
+ headers(Headers, Version), ?CRLF, Body],
?hcrd("send", [{message, Message}]),
-
http_transport:send(SocketType, Socket, lists:append(Message)).
+do_send_body(SocketType, Socket, ProcessBody, Acc) ->
+ case ProcessBody(Acc) of
+ eof ->
+ ok;
+ {ok, Data, NewAcc} ->
+ DataBin = iolist_to_binary(Data),
+ ?hcrd("send", [{data, DataBin}]),
+ case http_transport:send(SocketType, Socket, DataBin) of
+ ok ->
+ do_send_body(SocketType, Socket, ProcessBody, NewAcc);
+ Error ->
+ Error
+ end
+ end.
+
%%-------------------------------------------------------------------------
%% is_idempotent(Method) ->
@@ -161,7 +189,6 @@ is_client_closing(Headers) ->
%%%========================================================================
post_data(Method, Headers, {ContentType, Body}, HeadersAsIs)
when (Method =:= post) orelse (Method =:= put) ->
- ContentLength = body_length(Body),
NewBody = case Headers#http_request_h.expect of
"100-continue" ->
"";
@@ -170,14 +197,22 @@ post_data(Method, Headers, {ContentType, Body}, HeadersAsIs)
end,
NewHeaders = case HeadersAsIs of
- [] ->
- Headers#http_request_h{'content-type' =
- ContentType,
- 'content-length' =
- ContentLength};
- _ ->
- HeadersAsIs
- end,
+ [] ->
+ Headers#http_request_h{
+ 'content-type' = ContentType,
+ 'content-length' = case body_length(Body) of
+ undefined ->
+ % on upload streaming the caller must give a
+ % value to the Content-Length header
+ % (or use chunked Transfer-Encoding)
+ Headers#http_request_h.'content-length';
+ Len when is_list(Len) ->
+ Len
+ end
+ };
+ _ ->
+ HeadersAsIs
+ end,
{NewHeaders, NewBody};
@@ -190,7 +225,10 @@ body_length(Body) when is_binary(Body) ->
integer_to_list(size(Body));
body_length(Body) when is_list(Body) ->
- integer_to_list(length(Body)).
+ integer_to_list(length(Body));
+
+body_length({DataFun, _Acc}) when is_function(DataFun, 1) ->
+ undefined.
method(Method) ->
http_util:to_upper(atom_to_list(Method)).
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index b75277706f..02b1826c5f 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -20,12 +20,22 @@
[
{"5.5.2",
[
- {load_module, mod_esi, soft_purge, soft_purge, []}
+ {load_module, ftp, soft_purge, soft_purge, []},
+ {load_module, mod_esi, soft_purge, soft_purge, []},
+ {load_module, httpc, soft_purge, soft_purge, [httpc_handler]},
+ {load_module, httpc_request, soft_purge, soft_purge, []},
+ {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_request]}
]
},
{"5.5.1",
[
- {load_module, http_chunk, soft_purge, soft_purge, []}
+ {load_module, ftp, soft_purge, soft_purge, []},
+ {load_module, http_chunk, soft_purge, soft_purge, []},
+ {load_module, mod_esi, soft_purge, soft_purge, []},
+ {load_module, httpc, soft_purge, soft_purge, [httpc_handler]},
+ {load_module, httpc_request, soft_purge, soft_purge, []},
+ {update, httpc_handler, soft, soft_purge, soft_purge,
+ [httpc_request, http_chunk]}
]
},
{"5.5",
@@ -40,14 +50,24 @@
}
],
[
- {"5.5.2",
+ {"5.5.2",
[
- {load_module, mod_esi, soft_purge, soft_purge, []}
+ {load_module, ftp, soft_purge, soft_purge, []},
+ {load_module, mod_esi, soft_purge, soft_purge, []},
+ {load_module, httpc, soft_purge, soft_purge, [httpc_handler]},
+ {load_module, httpc_request, soft_purge, soft_purge, []},
+ {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_request]}
]
- },
+ },
{"5.5.1",
[
- {load_module, http_chunk, soft_purge, soft_purge, []}
+ {load_module, ftp, soft_purge, soft_purge, []},
+ {load_module, http_chunk, soft_purge, soft_purge, []},
+ {load_module, mod_esi, soft_purge, soft_purge, []},
+ {load_module, httpc, soft_purge, soft_purge, [httpc_handler]},
+ {load_module, httpc_request, soft_purge, soft_purge, []},
+ {update, httpc_handler, soft, soft_purge, soft_purge,
+ [httpc_request, http_chunk]}
]
},
{"5.5",
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
index 4bafdbfef8..17e5f6777e 100644
--- a/lib/inets/test/ftp_SUITE.erl
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -57,35 +57,42 @@
%% Description: Returns documentation/test cases in this test suite
%% or a skip tuple if the platform is not supported.
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() -> [{ct_hooks, [ts_install_cth]}].
all() ->
- [{group, solaris8_test}, {group, solaris9_test},
- {group, solaris10_test}, {group, linux_x86_test},
- {group, linux_ppc_test}, {group, macosx_x86_test},
- {group, macosx_ppc_test}, {group, openbsd_test},
- {group, freebsd_test}, {group, netbsd_test},
+ [
+ {group, solaris8_test},
+ {group, solaris9_test},
+ {group, solaris10_test},
+ {group, linux_x86_test},
+ {group, linux_ppc_test},
+ {group, macosx_x86_test},
+ {group, macosx_ppc_test},
+ {group, openbsd_test},
+ {group, freebsd_test},
+ {group, netbsd_test},
{group, windows_xp_test},
{group, windows_2003_server_test},
- {group, ticket_tests}].
+ {group, ticket_tests}
+ ].
groups() ->
- [{solaris8_test, [], [{ftp_solaris8_sparc_test, all}]},
- {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]},
- {solaris10_test, [],
- [{ftp_solaris10_sparc_test, all},
- {ftp_solaris10_x86_test, all}]},
- {linux_x86_test, [], [{ftp_linux_x86_test, all}]},
- {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]},
- {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]},
- {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]},
- {openbsd_test, [], [{ftp_openbsd_x86_test, all}]},
- {freebsd_test, [], [{ftp_freebsd_x86_test, all}]},
- {netbsd_test, [], [{ftp_netbsd_x86_test, all}]},
- {windows_xp_test, [], [{ftp_windows_xp_test, all}]},
- {windows_2003_server_test, [],
- [{ftp_windows_2003_server_test, all}]},
- {ticket_tests, [], [{ftp_ticket_test, all}]}].
+ [
+ {solaris8_test, [], [{ftp_solaris8_sparc_test, all}]},
+ {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]},
+ {solaris10_test, [], [{ftp_solaris10_sparc_test, all},
+ {ftp_solaris10_x86_test, all}]},
+ {linux_x86_test, [], [{ftp_linux_x86_test, all}]},
+ {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]},
+ {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]},
+ {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]},
+ {openbsd_test, [], [{ftp_openbsd_x86_test, all}]},
+ {freebsd_test, [], [{ftp_freebsd_x86_test, all}]},
+ {netbsd_test, [], [{ftp_netbsd_x86_test, all}]},
+ {windows_xp_test, [], [{ftp_windows_xp_test, all}]},
+ {windows_2003_server_test, [], [{ftp_windows_2003_server_test, all}]},
+ {ticket_tests, [], [{ftp_ticket_test, all}]}
+ ].
init_per_group(_GroupName, Config) ->
Config.
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 2c8febf5ed..c1a36d23de 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -62,36 +62,82 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [proxy_options, proxy_head, proxy_get, proxy_trace,
- proxy_post, proxy_put, proxy_delete, proxy_auth,
- proxy_headers, proxy_emulate_lower_versions,
- http_options, http_head, http_get, http_post,
- http_dummy_pipe, http_inets_pipe, http_trace,
- http_async, http_save_to_file, http_save_to_file_async,
- http_headers, http_headers_dummy, http_bad_response,
- ssl_head, ossl_head, essl_head, ssl_get, ossl_get,
- essl_get, ssl_trace, ossl_trace, essl_trace,
- http_redirect, http_redirect_loop,
- http_internal_server_error, http_userinfo, http_cookie,
- http_server_does_not_exist, http_invalid_http,
- http_emulate_lower_versions, http_relaxed,
- page_does_not_exist, proxy_page_does_not_exist,
- proxy_https_not_supported, http_stream,
- http_stream_once, proxy_stream, parse_url, options,
- ipv6, headers_as_is, {group, tickets}].
+ [
+ proxy_options,
+ proxy_head,
+ proxy_get,
+ proxy_trace,
+ proxy_post,
+ proxy_put,
+ proxy_delete,
+ proxy_auth,
+ proxy_headers,
+ proxy_emulate_lower_versions,
+ http_options,
+ http_head,
+ http_get,
+ http_post,
+ http_post_streaming,
+ http_dummy_pipe,
+ http_inets_pipe,
+ http_trace,
+ http_async,
+ http_save_to_file,
+ http_save_to_file_async,
+ http_headers,
+ http_headers_dummy,
+ http_bad_response,
+ ssl_head,
+ ossl_head,
+ essl_head,
+ ssl_get,
+ ossl_get,
+ essl_get,
+ ssl_trace,
+ ossl_trace,
+ essl_trace,
+ http_redirect,
+ http_redirect_loop,
+ http_internal_server_error,
+ http_userinfo, http_cookie,
+ http_server_does_not_exist,
+ http_invalid_http,
+ http_emulate_lower_versions,
+ http_relaxed,
+ page_does_not_exist,
+ proxy_page_does_not_exist,
+ proxy_https_not_supported,
+ http_stream,
+ http_stream_once,
+ proxy_stream,
+ parse_url,
+ options,
+ ipv6,
+ headers_as_is,
+ {group, tickets}
+ ].
groups() ->
- [{tickets, [],
- [hexed_query_otp_6191, empty_body_otp_6243,
- empty_response_header_otp_6830,
- transfer_encoding_otp_6807, proxy_not_modified_otp_6821,
- no_content_204_otp_6982, missing_CR_otp_7304,
- {group, otp_7883}, {group, otp_8154}, {group, otp_8106},
- otp_8056, otp_8352, otp_8371, otp_8739]},
- {otp_7883, [], [otp_7883_1, otp_7883_2]},
+ [{tickets, [], [hexed_query_otp_6191,
+ empty_body_otp_6243,
+ empty_response_header_otp_6830,
+ transfer_encoding_otp_6807,
+ proxy_not_modified_otp_6821,
+ no_content_204_otp_6982,
+ missing_CR_otp_7304,
+ {group, otp_7883},
+ {group, otp_8154},
+ {group, otp_8106},
+ otp_8056,
+ otp_8352,
+ otp_8371,
+ otp_8739]},
+ {otp_7883, [], [otp_7883_1,
+ otp_7883_2]},
{otp_8154, [], [otp_8154_1]},
- {otp_8106, [],
- [otp_8106_pid, otp_8106_fun, otp_8106_mfa]}].
+ {otp_8106, [], [otp_8106_pid,
+ otp_8106_fun,
+ otp_8106_mfa]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -138,6 +184,7 @@ init_per_suite(Config) ->
{local_port, ?IP_PORT},
{local_ssl_port, ?SSL_PORT} | Config].
+
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -151,6 +198,7 @@ end_per_suite(Config) ->
application:stop(ssl),
ok.
+
%%--------------------------------------------------------------------
%% Function: init_per_testcase(Case, Config) -> Config
%% Case - atom()
@@ -395,6 +443,53 @@ http_post(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
+http_post_streaming(doc) ->
+ ["Test streaming http post request against local server. "
+ "We only care about the client side of the the post. "
+ "The server script will not actually use the post data."];
+http_post_streaming(suite) ->
+ [];
+http_post_streaming(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ Port = ?config(local_port, Config),
+ URL = case test_server:os_type() of
+ {win32, _} ->
+ ?URL_START ++ integer_to_list(Port) ++
+ "/cgi-bin/cgi_echo.exe";
+ _ ->
+ ?URL_START ++ integer_to_list(Port) ++
+ "/cgi-bin/cgi_echo"
+ end,
+ %% Cgi-script expects the body length to be 100
+ BodyFun = fun(0) ->
+ io:format("~w:http_post_streaming_fun -> "
+ "zero~n", [?MODULE]),
+ eof;
+ (LenLeft) ->
+ io:format("~w:http_post_streaming_fun -> "
+ "LenLeft: ~p~n", [?MODULE, LenLeft]),
+ {ok, lists:duplicate(10, "1"), LenLeft - 10}
+ end,
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ httpc:request(post, {URL,
+ [{"expect", "100-continue"},
+ {"content-length", "100"}],
+ "text/plain", {BodyFun, 100}}, [], []),
+
+ {ok, {{_,504,_}, [_ | _], []}} =
+ httpc:request(post, {URL,
+ [{"expect", "100-continue"},
+ {"content-length", "10"}],
+ "text/plain", {BodyFun, 10}}, [], []);
+
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+%%-------------------------------------------------------------------------
http_emulate_lower_versions(doc) ->
["Perform request as 0.9 and 1.0 clients."];
http_emulate_lower_versions(suite) ->
@@ -2573,7 +2668,7 @@ otp_8739_dummy_server_init(Parent) ->
Parent ! {port, Port},
otp_8739_dummy_server_main(Parent, ListenSocket).
-otp_8739_dummy_server_main(Parent, ListenSocket) ->
+otp_8739_dummy_server_main(_Parent, ListenSocket) ->
case gen_tcp:accept(ListenSocket) of
{ok, Sock} ->
%% Ignore the request, and simply wait for the socket to close
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index 962be63968..11fcc5f387 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 065b24c53d..f92837dfe5 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index ccf70b8373..f800868c01 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index b3b9937f1c..73eb992323 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index b88c7cf1cd..e15e7dea7d 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index 14b43041ce..30326da114 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2010</year>
+ <year>2011</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index b27a3a0996..599be62241 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index 7941e371a0..73c4825458 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index 8cd499f960..c2676b1de5 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index 9c62b0fcf6..3a10bb209d 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 118800e44a..93bb6b71c9 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 3d27cf671b..4282e19769 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year><year>2010</year>
+ <year>2009</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 8542435456..654bbbc05d 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>