aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2011-11-09 21:41:33 +0100
committerLoïc Hoguin <[email protected]>2011-11-09 21:41:33 +0100
commit2f27b046d71ed439e8a58e2f661e2a84a1d9bea4 (patch)
tree7e137d6f3b6052d81df1742026d72d8752d7e836
parent12b9ca352616afcf865670df9e2186df213bd9f1 (diff)
downloadcowboy-2f27b046d71ed439e8a58e2f661e2a84a1d9bea4.tar.gz
cowboy-2f27b046d71ed439e8a58e2f661e2a84a1d9bea4.tar.bz2
cowboy-2f27b046d71ed439e8a58e2f661e2a84a1d9bea4.zip
Add 'If-Match' and 'If-None-Match' to parse_header/2
-rw-r--r--src/cowboy_http.erl38
-rw-r--r--src/cowboy_http_req.erl8
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) ->