0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-16 05:00:24 +00:00

Check the length before reading the body in body/1 and body_qs/1

This commit is contained in:
rambocoder 2013-03-06 08:50:45 -05:00
parent 233cf43ab9
commit 84d7671e91
5 changed files with 168 additions and 17 deletions

View file

@ -82,7 +82,9 @@
-export([stream_body/1]).
-export([skip_body/1]).
-export([body/1]).
-export([body/2]).
-export([body_qs/1]).
-export([body_qs/2]).
-export([multipart_data/1]).
-export([multipart_skip/1]).
@ -729,17 +731,40 @@ content_decode(ContentDecode, Data, Req) ->
{error, Reason} -> {error, Reason}
end.
%% @doc Return the full body sent with the request.
%% @equiv body(8000000, Req)
-spec body(Req) -> {ok, binary(), Req} | {error, atom()} when Req::req().
body(Req) ->
body(Req, <<>>).
body(8000000, Req).
-spec body(Req, binary())
%% @doc Return the body sent with the request.
-spec body(non_neg_integer() | infinity, Req)
-> {ok, binary(), Req} | {error, atom()} when Req::req().
body(Req, Acc) ->
body(infinity, Req) ->
case parse_header(<<"transfer-encoding">>, Req) of
{ok, [<<"identity">>], Req2} ->
read_body(Req2, <<>>);
{ok, _, _} ->
{error, chunked}
end;
body(MaxBodyLength, Req) ->
case parse_header(<<"transfer-encoding">>, Req) of
{ok, [<<"identity">>], Req2} ->
{ok, Length, Req3} = parse_header(<<"content-length">>, Req2, 0),
if Length > MaxBodyLength ->
{error, badlength};
true ->
read_body(Req3, <<>>)
end;
{ok, _, _} ->
{error, chunked}
end.
-spec read_body(Req, binary())
-> {ok, binary(), Req} | {error, atom()} when Req::req().
read_body(Req, Acc) ->
case stream_body(Req) of
{ok, Data, Req2} ->
body(Req2, << Acc/binary, Data/binary >>);
read_body(Req2, << Acc/binary, Data/binary >>);
{done, Req2} ->
{ok, Acc, Req2};
{error, Reason} ->
@ -754,13 +779,21 @@ skip_body(Req) ->
{error, Reason} -> {error, Reason}
end.
%% @doc Return the full body sent with the request, parsed as an
%% application/x-www-form-urlencoded string. Essentially a POST query string.
%% @equiv body_qs(16000, Req)
-spec body_qs(Req)
-> {ok, [{binary(), binary() | true}], Req} | {error, atom()}
when Req::req().
body_qs(Req) ->
case body(Req) of
body_qs(16000, Req).
%% @doc Return the body sent with the request, parsed as an
%% application/x-www-form-urlencoded string.
%% Essentially a POST query string.
-spec body_qs(non_neg_integer() | infinity, Req)
-> {ok, [{binary(), binary() | true}], Req} | {error, atom()}
when Req::req().
body_qs(MaxBodyLength, Req) ->
case body(MaxBodyLength, Req) of
{ok, Body, Req2} ->
{ok, cowboy_http:x_www_form_urlencoded(Body), Req2};
{error, Reason} ->