Skip to content

Commit

Permalink
handle passing function in the request body
Browse files Browse the repository at this point in the history
Body requeste can now be streamed using a function callback:

`Fun` when function is without argument
`{Func, InitState}`: whith arity 1 functions

Return from functions are:

Func() -> {ok, Data}, eof, Error
Func(state) -> {ok, Data, NewState}, eof, Error

When eof is passed the respoinse start to be parsed.
  • Loading branch information
benoitc committed Oct 26, 2012
1 parent 64329fb commit efd877f
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/hackney_request.erl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,34 @@ stream_body(eof, Client) ->
{ok, Client#client{response_state=waiting}};
stream_body(<<>>, Client) ->
{ok, Client#client{response_state=waiting}};
stream_body(Func, Client) when is_function(Func) ->
case Func() of
{ok, Data} ->
case stream_body(Data, Client) of
{ok, Client1} ->
stream_body(Func, Client1);
Error ->
Error
end;
eof ->
stream_body(eof, Client);
Err ->
Err
end;
stream_body({Func, State}, Client) when is_function(Func) ->
case Func(State) of
{ok, Data, NewState} ->
case stream_body(Data, Client) of
{ok, Client1} ->
stream_body({Func, NewState}, Client1);
Error ->
Error
end;
eof ->
stream_body(eof, Client);
Err ->
Err
end;
stream_body(Body, #client{req_chunk_size=ChunkSize, send_fun=Send}=Client)
when is_binary(Body) ->

Expand Down Expand Up @@ -170,6 +198,19 @@ handle_body(Headers, ReqType0, Body0, Client) ->
S= filelib:file_size(FileName),
CT = hackney_util:content_type(FileName),
{S, CT, Body0};
Func when is_function(Func) ->
CT = hackney_headers:get_value(<<"content-type">>, Headers,
<<"application/octet-stream">>),
S = hackney_headers:get_value(<<"content-length">>,
Headers),
{S, CT, Body0};
{Func, _} when is_function(Func) ->
CT = hackney_headers:get_value(<<"content-type">>, Headers,
<<"application/octet-stream">>),
S = hackney_headers:get_value(<<"content-length">>,
Headers),
{S, CT, Body0};

_ when is_list(Body0) -> % iolist case
S = erlang:length(Body0),
CT = hackney_headers:get_value(<<"content-type">>, Headers,
Expand All @@ -190,12 +231,30 @@ handle_body(Headers, ReqType0, Body0, Client) ->
Headers1 = hackney_headers:delete(<<"transfer-encoding">>,
Headers),
{hackney_headers:update(Headers1, NewHeadersKV), normal};
{chunked, F} when is_function(F) ->
NewHeadersKV = [{<<"Content-Type">>, CType}],
Headers1 = hackney_headers:delete(<<"content-length">>,
Headers),
{hackney_headers:update(Headers1, NewHeadersKV), chunked};
{chunked, {F, _}} when is_function(F) ->
NewHeadersKV = [{<<"Content-Type">>, CType}],
Headers1 = hackney_headers:delete(<<"content-length">>,
Headers),
{hackney_headers:update(Headers1, NewHeadersKV), chunked};

{chunked, _} ->
NewHeadersKV = [{<<"Content-Type">>, CType}],
Headers1 = hackney_headers:delete(<<"content-length">>,
Headers),
{hackney_headers:update(Headers1, NewHeadersKV), chunked};

{_, _} when CLen =:= undefined ->
NewHeadersKV = [{<<"Content-Type">>, CType},
{<<"Transfer-Encoding">>, <<"chunked">>}],
Headers1 = hackney_headers:delete(<<"content-length">>,
Headers),
{hackney_headers:update(Headers1, NewHeadersKV), chunked};

{_, _} ->
NewHeadersKV = [{<<"Content-Type">>, CType},
{<<"Content-Length">>, CLen}],
Expand Down

0 comments on commit efd877f

Please sign in to comment.