mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00
Support 'Content-Length' in parse_header/2
This commit is contained in:
parent
68c1d886e5
commit
04bcbc444d
2 changed files with 49 additions and 7 deletions
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
%% Parsing.
|
%% Parsing.
|
||||||
-export([list/2, nonempty_list/2,
|
-export([list/2, nonempty_list/2,
|
||||||
media_range/2, charset/2,
|
media_range/2, charset/2, digits/1,
|
||||||
token/2, token_ci/2, quoted_string/2]).
|
token/2, token_ci/2, quoted_string/2]).
|
||||||
|
|
||||||
%% Interpretation.
|
%% Interpretation.
|
||||||
|
@ -28,6 +28,11 @@
|
||||||
|
|
||||||
%% Parsing.
|
%% Parsing.
|
||||||
|
|
||||||
|
%% Use only as a guard.
|
||||||
|
-define(IS_DIGIT(C),
|
||||||
|
C =:= $0; C =:= $1; C =:= $2; C =:= $3; C =:= $4;
|
||||||
|
C =:= $5; C =:= $6; C =:= $7; C =:= $8; C =:= $9).
|
||||||
|
|
||||||
%% @doc Parse a non-empty list of the given type.
|
%% @doc Parse a non-empty list of the given type.
|
||||||
-spec nonempty_list(binary(), fun()) -> [any(), ...] | {error, badarg}.
|
-spec nonempty_list(binary(), fun()) -> [any(), ...] | {error, badarg}.
|
||||||
nonempty_list(Data, Fun) ->
|
nonempty_list(Data, Fun) ->
|
||||||
|
@ -240,6 +245,31 @@ whitespace(<< C, Rest/bits >>, Fun)
|
||||||
whitespace(Data, Fun) ->
|
whitespace(Data, Fun) ->
|
||||||
Fun(Data).
|
Fun(Data).
|
||||||
|
|
||||||
|
%% @doc Parse a list of digits as a non negative integer.
|
||||||
|
-spec digits(binary()) -> non_neg_integer() | {error, badarg}.
|
||||||
|
digits(Data) ->
|
||||||
|
digits(Data,
|
||||||
|
fun (Rest, I) ->
|
||||||
|
whitespace(Rest,
|
||||||
|
fun (<<>>) ->
|
||||||
|
I;
|
||||||
|
(_Rest2) ->
|
||||||
|
{error, badarg}
|
||||||
|
end)
|
||||||
|
end).
|
||||||
|
|
||||||
|
-spec digits(binary(), fun()) -> any().
|
||||||
|
digits(<< C, Rest/bits >>, Fun) when ?IS_DIGIT(C) ->
|
||||||
|
digits(Rest, Fun, C - $0);
|
||||||
|
digits(_Data, _Fun) ->
|
||||||
|
{error, badarg}.
|
||||||
|
|
||||||
|
-spec digits(binary(), fun(), non_neg_integer()) -> any().
|
||||||
|
digits(<< C, Rest/bits >>, Fun, Acc) when ?IS_DIGIT(C) ->
|
||||||
|
digits(Rest, Fun, Acc * 10 + (C - $0));
|
||||||
|
digits(Data, Fun, Acc) ->
|
||||||
|
Fun(Data, Acc).
|
||||||
|
|
||||||
%% @doc Parse a case-insensitive token.
|
%% @doc Parse a case-insensitive token.
|
||||||
%%
|
%%
|
||||||
%% Changes all characters to lowercase.
|
%% Changes all characters to lowercase.
|
||||||
|
@ -303,9 +333,7 @@ qvalue(_Data, _Fun) ->
|
||||||
-spec qvalue(binary(), fun(), integer(), 1 | 10 | 100) -> any().
|
-spec qvalue(binary(), fun(), integer(), 1 | 10 | 100) -> any().
|
||||||
qvalue(Data, Fun, Q, 0) ->
|
qvalue(Data, Fun, Q, 0) ->
|
||||||
Fun(Data, Q);
|
Fun(Data, Q);
|
||||||
qvalue(<< C, Rest/bits >>, Fun, Q, M)
|
qvalue(<< C, Rest/bits >>, Fun, Q, M) when ?IS_DIGIT(C) ->
|
||||||
when C =:= $0; C =:= $1; C =:= $2; C =:= $3; C =:= $4;
|
|
||||||
C =:= $5; C =:= $6; C =:= $7; C =:= $8; C =:= $9 ->
|
|
||||||
qvalue(Rest, Fun, Q + (C - $0) * M, M div 10);
|
qvalue(Rest, Fun, Q + (C - $0) * M, M div 10);
|
||||||
qvalue(Data, Fun, Q, _M) ->
|
qvalue(Data, Fun, Q, _M) ->
|
||||||
Fun(Data, Q).
|
Fun(Data, Q).
|
||||||
|
@ -405,4 +433,13 @@ connection_to_atom_test_() ->
|
||||||
[{lists:flatten(io_lib:format("~p", [T])),
|
[{lists:flatten(io_lib:format("~p", [T])),
|
||||||
fun() -> R = connection_to_atom(T) end} || {T, R} <- Tests].
|
fun() -> R = connection_to_atom(T) end} || {T, R} <- Tests].
|
||||||
|
|
||||||
|
digits_test_() ->
|
||||||
|
%% {Digits, Result}
|
||||||
|
Tests = [
|
||||||
|
{<<"42 ">>, 42},
|
||||||
|
{<<"69\t">>, 69},
|
||||||
|
{<<"1337">>, 1337}
|
||||||
|
],
|
||||||
|
[{V, fun() -> R = digits(V) end} || {V, R} <- Tests].
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
|
@ -231,6 +231,11 @@ parse_header(Name, Req, Default) when Name =:= 'Connection' ->
|
||||||
fun (Value) ->
|
fun (Value) ->
|
||||||
cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2)
|
cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2)
|
||||||
end);
|
end);
|
||||||
|
parse_header(Name, Req, Default) when Name =:= 'Content-Length' ->
|
||||||
|
parse_header(Name, Req, Default,
|
||||||
|
fun (Value) ->
|
||||||
|
cowboy_http:digits(Value)
|
||||||
|
end);
|
||||||
parse_header(Name, Req, Default) ->
|
parse_header(Name, Req, Default) ->
|
||||||
{Value, Req2} = header(Name, Req, Default),
|
{Value, Req2} = header(Name, Req, Default),
|
||||||
{undefined, Value, Req2}.
|
{undefined, Value, Req2}.
|
||||||
|
@ -292,12 +297,12 @@ cookies(Req=#http_req{cookies=Cookies}) ->
|
||||||
%% @todo We probably want to allow a max length.
|
%% @todo We probably want to allow a max length.
|
||||||
-spec body(#http_req{}) -> {ok, binary(), #http_req{}} | {error, atom()}.
|
-spec body(#http_req{}) -> {ok, binary(), #http_req{}} | {error, atom()}.
|
||||||
body(Req) ->
|
body(Req) ->
|
||||||
{Length, Req2} = cowboy_http_req:header('Content-Length', Req),
|
{Length, Req2} = cowboy_http_req:parse_header('Content-Length', Req),
|
||||||
case Length of
|
case Length of
|
||||||
undefined -> {error, badarg};
|
undefined -> {error, badarg};
|
||||||
|
{error, badarg} -> {error, badarg};
|
||||||
_Any ->
|
_Any ->
|
||||||
Length2 = list_to_integer(binary_to_list(Length)),
|
body(Length, Req2)
|
||||||
body(Length2, Req2)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc Return <em>Length</em> bytes of the request body.
|
%% @doc Return <em>Length</em> bytes of the request body.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue