Skip to content

Instantly share code, notes, and snippets.

@ngerakines
Created February 25, 2009 07:42
Show Gist options
  • Save ngerakines/70068 to your computer and use it in GitHub Desktop.
Save ngerakines/70068 to your computer and use it in GitHub Desktop.
%% @spec recv_body(integer()) -> binary()
%% @doc Receive the body of the HTTP request (defined by Content-Length).
%% Will receive up to MaxBody bytes.
recv_body(MaxBody) ->
<<<<<<< HEAD:src/mochiweb_request.erl
case erlang:get(?SAVE_BODY) of
undefined ->
case get_header_value("expect") of
"100-continue" ->
start_raw_response({100, gb_trees:empty()});
_Else ->
ok
end,
Body = case body_length() of
undefined ->
undefined;
{unknown_transfer_encoding, Unknown} ->
exit({unknown_transfer_encoding, Unknown});
chunked ->
read_chunked_body(MaxBody, []);
0 ->
<<>>;
Length when is_integer(Length), Length =< MaxBody ->
recv(Length);
Length ->
exit({body_too_large, Length})
end,
put(?SAVE_BODY, Body),
Body;
X -> X
=======
% we could use a sane constant for max chunk size
Body = stream_body(?MAX_RECV_BODY, fun
({0, _ChunkedFooter}, {_LengthAcc, BinAcc}) ->
iolist_to_binary(lists:reverse(BinAcc));
({Length, Bin}, {LengthAcc, BinAcc}) ->
NewLength = Length + LengthAcc,
if NewLength > MaxBody ->
exit({body_too_large, chunked});
true ->
{NewLength, [Bin | BinAcc]}
end
end, {0, []}, MaxBody),
put(?SAVE_BODY, Body),
Body.
stream_body(MaxChunkSize, ChunkFun, FunState) ->
stream_body(MaxChunkSize, ChunkFun, FunState, undefined).
stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength) ->
case get_header_value("expect") of
"100-continue" ->
start_raw_response({100, gb_trees:empty()});
_Else ->
ok
end,
case body_length() of
undefined ->
undefined;
{unknown_transfer_encoding, Unknown} ->
exit({unknown_transfer_encoding, Unknown});
chunked ->
% In this case the MaxBody is actually used to
% determine the maximum allowed size of a single
% chunk.
stream_chunked_body(MaxChunkSize, ChunkFun, FunState);
0 ->
<<>>;
Length when is_integer(Length) ->
case MaxBodyLength of
MaxBodyLength when is_integer(MaxBodyLength), MaxBodyLength < Length ->
exit({body_too_large, content_length});
_ ->
stream_unchunked_body(Length, MaxChunkSize, ChunkFun, FunState)
end;
Length ->
exit({length_not_integer, Length})
>>>>>>> 77762dd48c34e469ac3974582ee8a8478043163a:src/mochiweb_request.erl
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment