diff options
-rw-r--r-- | src/cowboy_http.erl | 38 | ||||
-rw-r--r-- | src/cowboy_http_req.erl | 8 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index 1fd220f..6d14961 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -17,7 +17,7 @@ %% Parsing. -export([list/2, nonempty_list/2, - media_range/2, conneg/2, language_range/2, + media_range/2, conneg/2, language_range/2, entity_tag_match/1, http_date/1, rfc1123_date/1, rfc850_date/1, asctime_date/1, digits/1, token/2, token_ci/2, quoted_string/2]). @@ -238,6 +238,30 @@ maybe_qparam(Data, Fun) -> qparam(<< Q, $=, Data/bits >>, Fun) when Q =:= $q; Q =:= $Q -> qvalue(Data, Fun). +%% @doc Parse either a list of entity tags or a "*". +-spec entity_tag_match(binary()) -> any(). +entity_tag_match(<< $*, Rest/bits >>) -> + whitespace(Rest, + fun (<<>>) -> '*'; + (_Any) -> {error, badarg} + end); +entity_tag_match(Data) -> + nonempty_list(Data, fun entity_tag/2). + +%% @doc Parse an entity-tag. +-spec entity_tag(binary(), fun()) -> any(). +entity_tag(<< "W/", Rest/bits >>, Fun) -> + opaque_tag(Rest, Fun, weak); +entity_tag(Data, Fun) -> + opaque_tag(Data, Fun, strong). + +-spec opaque_tag(binary(), fun(), weak | strong) -> any(). +opaque_tag(Data, Fun, Strength) -> + quoted_string(Data, + fun (_Rest, <<>>) -> {error, badarg}; + (Rest, OpaqueTag) -> Fun(Rest, {Strength, OpaqueTag}) + end). + %% @doc Parse an HTTP date (RFC1123, RFC850 or asctime date). %% @end %% @@ -693,6 +717,18 @@ media_range_list_test_() -> ], [{V, fun() -> R = list(V, fun media_range/2) end} || {V, R} <- Tests]. +entity_tag_match_test_() -> + %% {Tokens, Result} + Tests = [ + {<<"\"xyzzy\"">>, [{strong, <<"xyzzy">>}]}, + {<<"\"xyzzy\", W/\"r2d2xxxx\", \"c3piozzzz\"">>, + [{strong, <<"xyzzy">>}, + {weak, <<"r2d2xxxx">>}, + {strong, <<"c3piozzzz">>}]}, + {<<"*">>, '*'} + ], + [{V, fun() -> R = entity_tag_match(V) end} || {V, R} <- Tests]. + http_date_test_() -> %% {Tokens, Result} Tests = [ diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index feb795c..12d117f 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -205,6 +205,8 @@ parse_header_default('Accept-Charset') -> []; parse_header_default('Accept-Encoding') -> []; parse_header_default('Accept-Language') -> []; parse_header_default('Connection') -> []; +parse_header_default('If-Match') -> '*'; +parse_header_default('If-None-Match') -> '*'; parse_header_default(_Name) -> undefined. %% @doc Semantically parse headers. @@ -243,6 +245,12 @@ parse_header(Name, Req, Default) when Name =:= 'Content-Length' -> cowboy_http:digits(Value) end); parse_header(Name, Req, Default) + when Name =:= 'If-Match'; Name =:= 'If-None-Match' -> + parse_header(Name, Req, Default, + fun (Value) -> + cowboy_http:entity_tag_match(Value) + end); +parse_header(Name, Req, Default) when Name =:= 'If-Modified-Since'; Name =:= 'If-Unmodified-Since' -> parse_header(Name, Req, Default, fun (Value) -> |