diff options
author | Micael Karlberg <[email protected]> | 2011-03-04 14:52:29 +0100 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2011-03-04 14:52:29 +0100 |
commit | 546d0fd69519682e92b6493b6d092e4591ae5010 (patch) | |
tree | cbaf90442128f008e6a4636d220400ac57d613eb /lib/inets/src/http_client/httpc.erl | |
parent | 840026b8a94e7575e07ba6da2d74be22cf9d8bdf (diff) | |
parent | 6951ed1075b8c36d5b6f51e5e5df7bd14602c1d8 (diff) | |
download | otp-546d0fd69519682e92b6493b6d092e4591ae5010.tar.gz otp-546d0fd69519682e92b6493b6d092e4591ae5010.tar.bz2 otp-546d0fd69519682e92b6493b6d092e4591ae5010.zip |
Merge branch 'fm/httpc-upload-body-streaming' into bmk/inets/httpc/support_upload_body_streaming/OTP-OTP-9094
Conflicts:
lib/inets/src/http_client/httpc.erl
lib/inets/test/httpc_SUITE.erl
Diffstat (limited to 'lib/inets/src/http_client/httpc.erl')
-rw-r--r-- | lib/inets/src/http_client/httpc.erl | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index 04fae13b20..7490bb0e46 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,11 +429,20 @@ 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], + NewHeaders0 = [{http_util:to_lower(Key), Val} || {Key, Val} <- Headers0], + + {NewHeaders, Body} = case Body0 of + {chunkify, BodyFun, Acc} -> + NewHeaders1 = lists:keystore("transfer-encoding", 1, + NewHeaders0, {"transfer-encoding", "chunked"}), + {NewHeaders1, {chunkify_fun(BodyFun), Acc}}; + _ -> + {NewHeaders0, Body0} + end, try begin @@ -458,8 +470,8 @@ 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 @@ -481,6 +493,23 @@ url_encode(URI, true) -> url_encode(URI, false) -> URI. +chunkify_fun(BodyFun) -> + fun(eof_body_fun) -> + eof; + (Acc) -> + case BodyFun(Acc) of + eof -> + {ok, <<"0\r\n\r\n">>, eof_body_fun}; + {ok, Data, NewAcc} -> + Bin = iolist_to_binary(Data), + Chunk = [hex_size(Bin), "\r\n", Bin, "\r\n"], + {ok, iolist_to_binary(Chunk), NewAcc} + end + end. + +hex_size(Bin) -> + hd(io_lib:format("~.16B", [size(Bin)])). + handle_answer(RequestId, false, _) -> {ok, RequestId}; handle_answer(RequestId, true, Options) -> |