mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00
Add 'Expect' header parsing
At the same time renaming cowboy_http:content_type_params/3 to cowboy_http:params/2 (with a default Acc of []) as this code isn't useful only for content types.
This commit is contained in:
parent
e7b6e2a402
commit
f51493ee37
3 changed files with 58 additions and 31 deletions
|
@ -17,8 +17,8 @@
|
||||||
-module(cowboy_http).
|
-module(cowboy_http).
|
||||||
|
|
||||||
%% Parsing.
|
%% Parsing.
|
||||||
-export([list/2, nonempty_list/2, content_type/1, content_type_params/3,
|
-export([list/2, nonempty_list/2, content_type/1, media_range/2, conneg/2,
|
||||||
media_range/2, conneg/2, language_range/2, entity_tag_match/1,
|
language_range/2, entity_tag_match/1, expectation/2, params/2,
|
||||||
http_date/1, rfc1123_date/1, rfc850_date/1, asctime_date/1,
|
http_date/1, rfc1123_date/1, rfc850_date/1, asctime_date/1,
|
||||||
whitespace/2, digits/1, token/2, token_ci/2, quoted_string/2]).
|
whitespace/2, digits/1, token/2, token_ci/2, quoted_string/2]).
|
||||||
|
|
||||||
|
@ -98,33 +98,9 @@ list(Data, Fun, Acc) ->
|
||||||
content_type(Data) ->
|
content_type(Data) ->
|
||||||
media_type(Data,
|
media_type(Data,
|
||||||
fun (Rest, Type, SubType) ->
|
fun (Rest, Type, SubType) ->
|
||||||
content_type_params(Rest,
|
params(Rest,
|
||||||
fun (Params) -> {Type, SubType, Params} end, [])
|
fun (<<>>, Params) -> {Type, SubType, Params};
|
||||||
end).
|
(_Rest2, _) -> {error, badarg}
|
||||||
|
|
||||||
-spec content_type_params(binary(), fun(), list({binary(), binary()}))
|
|
||||||
-> any().
|
|
||||||
content_type_params(Data, Fun, Acc) ->
|
|
||||||
whitespace(Data,
|
|
||||||
fun (<< $;, Rest/binary >>) -> content_type_param(Rest, Fun, Acc);
|
|
||||||
(<<>>) -> Fun(lists:reverse(Acc));
|
|
||||||
(_Rest) -> {error, badarg}
|
|
||||||
end).
|
|
||||||
|
|
||||||
-spec content_type_param(binary(), fun(), list({binary(), binary()}))
|
|
||||||
-> any().
|
|
||||||
content_type_param(Data, Fun, Acc) ->
|
|
||||||
whitespace(Data,
|
|
||||||
fun (Rest) ->
|
|
||||||
token_ci(Rest,
|
|
||||||
fun (_Rest2, <<>>) -> {error, badarg};
|
|
||||||
(<< $=, Rest2/binary >>, Attr) ->
|
|
||||||
word(Rest2,
|
|
||||||
fun (Rest3, Value) ->
|
|
||||||
content_type_params(Rest3, Fun,
|
|
||||||
[{Attr, Value}|Acc])
|
|
||||||
end);
|
|
||||||
(_Rest2, _Attr) -> {error, badarg}
|
|
||||||
end)
|
end)
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
@ -319,6 +295,50 @@ opaque_tag(Data, Fun, Strength) ->
|
||||||
(Rest, OpaqueTag) -> Fun(Rest, {Strength, OpaqueTag})
|
(Rest, OpaqueTag) -> Fun(Rest, {Strength, OpaqueTag})
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
%% @doc Parse an expectation.
|
||||||
|
-spec expectation(binary(), fun()) -> any().
|
||||||
|
expectation(Data, Fun) ->
|
||||||
|
token_ci(Data,
|
||||||
|
fun (_Rest, <<>>) -> {error, badarg};
|
||||||
|
(<< $=, Rest/binary >>, Expectation) ->
|
||||||
|
word(Rest,
|
||||||
|
fun (Rest2, ExtValue) ->
|
||||||
|
params(Rest2, fun (Rest3, ExtParams) ->
|
||||||
|
Fun(Rest3, {Expectation, ExtValue, ExtParams})
|
||||||
|
end)
|
||||||
|
end);
|
||||||
|
(Rest, Expectation) ->
|
||||||
|
Fun(Rest, Expectation)
|
||||||
|
end).
|
||||||
|
|
||||||
|
%% @doc Parse a list of parameters (a=b;c=d).
|
||||||
|
-spec params(binary(), fun()) -> any().
|
||||||
|
params(Data, Fun) ->
|
||||||
|
params(Data, Fun, []).
|
||||||
|
|
||||||
|
-spec params(binary(), fun(), [{binary(), binary()}]) -> any().
|
||||||
|
params(Data, Fun, Acc) ->
|
||||||
|
whitespace(Data,
|
||||||
|
fun (<< $;, Rest/binary >>) -> param(Rest, Fun, Acc);
|
||||||
|
(Rest) -> Fun(Rest, lists:reverse(Acc))
|
||||||
|
end).
|
||||||
|
|
||||||
|
-spec param(binary(), fun(), [{binary(), binary()}]) -> any().
|
||||||
|
param(Data, Fun, Acc) ->
|
||||||
|
whitespace(Data,
|
||||||
|
fun (Rest) ->
|
||||||
|
token_ci(Rest,
|
||||||
|
fun (_Rest2, <<>>) -> {error, badarg};
|
||||||
|
(<< $=, Rest2/binary >>, Attr) ->
|
||||||
|
word(Rest2,
|
||||||
|
fun (Rest3, Value) ->
|
||||||
|
params(Rest3, Fun,
|
||||||
|
[{Attr, Value}|Acc])
|
||||||
|
end);
|
||||||
|
(_Rest2, _Attr) -> {error, badarg}
|
||||||
|
end)
|
||||||
|
end).
|
||||||
|
|
||||||
%% @doc Parse an HTTP date (RFC1123, RFC850 or asctime date).
|
%% @doc Parse an HTTP date (RFC1123, RFC850 or asctime date).
|
||||||
%% @end
|
%% @end
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -271,6 +271,11 @@ parse_header(Name, Req, Default) when Name =:= 'Content-Type' ->
|
||||||
fun (Value) ->
|
fun (Value) ->
|
||||||
cowboy_http:content_type(Value)
|
cowboy_http:content_type(Value)
|
||||||
end);
|
end);
|
||||||
|
parse_header(Name, Req, Default) when Name =:= 'Expect' ->
|
||||||
|
parse_header(Name, Req, Default,
|
||||||
|
fun (Value) ->
|
||||||
|
cowboy_http:nonempty_list(Value, fun cowboy_http:expectation/2)
|
||||||
|
end);
|
||||||
parse_header(Name, Req, Default)
|
parse_header(Name, Req, Default)
|
||||||
when Name =:= 'If-Match'; Name =:= 'If-None-Match' ->
|
when Name =:= 'If-Match'; Name =:= 'If-None-Match' ->
|
||||||
parse_header(Name, Req, Default,
|
parse_header(Name, Req, Default,
|
||||||
|
|
|
@ -45,8 +45,10 @@ content_disposition(Data) ->
|
||||||
cowboy_http:token_ci(Data,
|
cowboy_http:token_ci(Data,
|
||||||
fun (_Rest, <<>>) -> {error, badarg};
|
fun (_Rest, <<>>) -> {error, badarg};
|
||||||
(Rest, Disposition) ->
|
(Rest, Disposition) ->
|
||||||
cowboy_http:content_type_params(Rest,
|
cowboy_http:params(Rest,
|
||||||
fun (Params) -> {Disposition, Params} end, [])
|
fun (<<>>, Params) -> {Disposition, Params};
|
||||||
|
(_Rest2, _) -> {error, badarg}
|
||||||
|
end)
|
||||||
end).
|
end).
|
||||||
|
|
||||||
%% Internal.
|
%% Internal.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue