summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plop_httputil.erl52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/plop_httputil.erl b/src/plop_httputil.erl
index 37e25c1..99d26de 100644
--- a/src/plop_httputil.erl
+++ b/src/plop_httputil.erl
@@ -76,11 +76,7 @@ request(DebugTag, URL, Headers, RequestBody) ->
lager:debug("~s: connected to ~p",
[DebugTag, URL]),
{ok, StatusCode, RespHeaders, ClientRef} =
- hackney:send_request(ConnRef,
- {post, Path,
- add_auth("POST", Path, Headers,
- RequestBody),
- RequestBody}),
+ make_request(ConnRef, Path, Headers, RequestBody),
lager:debug("~s: received headers for ~p: ~p",
[DebugTag, URL, RespHeaders]),
{ok, Body} = hackney:body(ClientRef),
@@ -96,3 +92,49 @@ request(DebugTag, URL, Headers, RequestBody) ->
{error, Error} ->
{error, Error}
end.
+
+-define(CHUNKSIZE, 512*1024).
+make_request(ConnRef, Path, Headers, RequestBody) ->
+ %% Large bodies are "streamed" (i.e. HTTP chunking, in chunks of
+ %% CHUNKSIZE octets) if they're more than CHUNKSIZE octets in
+ %% size.
+ case byte_size(RequestBody) of
+ N when N > ?CHUNKSIZE ->
+ Req = {post, Path,
+ add_auth("POST", Path,
+ Headers ++ [{<<"Transfer-Encoding">>, <<"chunked">>}],
+ RequestBody),
+ stream},
+ {ok, ConnRef2} = hackney:send_request(ConnRef, Req),
+ ok = hackney:send_body(ConnRef2, body_sender_fun(RequestBody)),
+ hackney:start_response(ConnRef2);
+ _ ->
+ Req = {post, Path,
+ add_auth("POST", Path, Headers, RequestBody),
+ RequestBody},
+ hackney:send_request(ConnRef, Req)
+ end.
+
+chunk_it(Data) when byte_size(Data) > ?CHUNKSIZE ->
+ split_binary(Data, ?CHUNKSIZE);
+chunk_it(Data) ->
+ {Data, <<>>}.
+
+send_some_body(Table) ->
+ [{body, Data}] = ets:lookup(Table, body),
+ case byte_size(Data) of
+ N when N =:= 0 ->
+ true = ets:delete(Table),
+ eof;
+ _ ->
+ {ToSend, TheRest} = chunk_it(Data),
+ true = ets:insert(Table, {body, TheRest}),
+ {ok, ToSend}
+ end.
+
+body_sender_fun(Body) ->
+ Table = ets:new(bodytable, []),
+ true = ets:insert(Table, {body, Body}),
+ fun() ->
+ send_some_body(Table)
+ end.