aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2012-12-20 14:19:39 +0100
committerLoïc Hoguin <[email protected]>2012-12-20 14:19:39 +0100
commit8858ca240fe42e3fcd0b9c3b1a2388b432301a27 (patch)
tree9654f8bda770961d70061beeb4c42ba39f2fc8c0 /src/cowboy_http.erl
parentf48902cee7f4a08659232ab2d3f30b6e1117752a (diff)
downloadcowboy-8858ca240fe42e3fcd0b9c3b1a2388b432301a27.tar.gz
cowboy-8858ca240fe42e3fcd0b9c3b1a2388b432301a27.tar.bz2
cowboy-8858ca240fe42e3fcd0b9c3b1a2388b432301a27.zip
Fix parsing of the Cookie header
This should be equivalent to what we do in Set-Cookie. Real-world testing is needed to confirm it works as intended.
Diffstat (limited to 'src/cowboy_http.erl')
-rw-r--r--src/cowboy_http.erl64
1 files changed, 54 insertions, 10 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index 4754649..aa94016 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -121,7 +121,7 @@ cookie_list(Data, Acc) ->
fun (<<>>) -> Acc;
(<< $,, Rest/binary >>) -> cookie_list(Rest, Acc);
(<< $;, Rest/binary >>) -> cookie_list(Rest, Acc);
- (Rest) -> param(Rest,
+ (Rest) -> cookie(Rest,
fun (Rest2, << $$, _/bits >>, _) ->
cookie_list(Rest2, Acc);
(Rest2, Name, Value) ->
@@ -129,6 +129,50 @@ cookie_list(Data, Acc) ->
end)
end).
+-spec cookie(binary(), fun()) -> any().
+cookie(Data, Fun) ->
+ whitespace(Data,
+ fun (Rest) ->
+ cookie_name(Rest,
+ fun (_Rest2, <<>>) -> {error, badarg};
+ (<< $=, Rest2/binary >>, Name) ->
+ cookie_value(Rest2,
+ fun (Rest3, Value) ->
+ Fun(Rest3, Name, Value)
+ end);
+ (_Rest2, _Attr) -> {error, badarg}
+ end)
+ end).
+
+-spec cookie_name(binary(), fun()) -> any().
+cookie_name(Data, Fun) ->
+ cookie_name(Data, Fun, <<>>).
+
+-spec cookie_name(binary(), fun(), binary()) -> any().
+cookie_name(<<>>, Fun, Acc) ->
+ Fun(<<>>, Acc);
+cookie_name(Data = << C, _Rest/binary >>, Fun, Acc)
+ when C =:= $=; C =:= $,; C =:= $;; C =:= $\s; C =:= $\t;
+ C =:= $\r; C =:= $\n; C =:= $\013; C =:= $\014 ->
+ Fun(Data, Acc);
+cookie_name(<< C, Rest/binary >>, Fun, Acc) ->
+ C2 = cowboy_bstr:char_to_lower(C),
+ cookie_name(Rest, Fun, << Acc/binary, C2 >>).
+
+-spec cookie_value(binary(), fun()) -> any().
+cookie_value(Data, Fun) ->
+ cookie_value(Data, Fun, <<>>).
+
+-spec cookie_value(binary(), fun(), binary()) -> any().
+cookie_value(<<>>, Fun, Acc) ->
+ Fun(<<>>, Acc);
+cookie_value(Data = << C, _Rest/binary >>, Fun, Acc)
+ when C =:= $,; C =:= $;; C =:= $\s; C =:= $\t;
+ C =:= $\r; C =:= $\n; C =:= $\013; C =:= $\014 ->
+ Fun(Data, Acc);
+cookie_value(<< C, Rest/binary >>, Fun, Acc) ->
+ cookie_value(Rest, Fun, << Acc/binary, C >>).
+
%% @doc Parse a content type.
-spec content_type(binary()) -> any().
content_type(Data) ->
@@ -1016,24 +1060,24 @@ cookie_list_test_() ->
{<<"name">>, <<"value">>},
{<<"name2">>, <<"value2">>}
]},
- {<<"$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"">>, [
+ {<<"$Version=1; Customer=WILE_E_COYOTE; $Path=/acme">>, [
{<<"customer">>, <<"WILE_E_COYOTE">>}
]},
- {<<"$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; "
- "Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"; "
- "Shipping=\"FedEx\"; $Path=\"/acme\"">>, [
+ {<<"$Version=1; Customer=WILE_E_COYOTE; $Path=/acme; "
+ "Part_Number=Rocket_Launcher_0001; $Path=/acme; "
+ "Shipping=FedEx; $Path=/acme">>, [
{<<"customer">>, <<"WILE_E_COYOTE">>},
{<<"part_number">>, <<"Rocket_Launcher_0001">>},
{<<"shipping">>, <<"FedEx">>}
]},
%% Potential edge cases (initially from Mochiweb).
- {<<"foo=\"\\x\"">>, [{<<"foo">>, <<"x">>}]},
+ {<<"foo=\\x">>, [{<<"foo">>, <<"\\x">>}]},
{<<"=">>, {error, badarg}},
{<<" foo ; bar ">>, {error, badarg}},
- {<<"foo=;bar=">>, {error, badarg}},
- {<<"foo=\"\\\";\";bar ">>, {error, badarg}},
- {<<"foo=\"\\\";\";bar=good ">>,
- [{<<"foo">>, <<"\";">>}, {<<"bar">>, <<"good">>}]},
+ {<<"foo=;bar=">>, [{<<"foo">>, <<>>}, {<<"bar">>, <<>>}]},
+ {<<"foo=\\\";;bar ">>, {error, badarg}},
+ {<<"foo=\\\";;bar=good ">>,
+ [{<<"foo">>, <<"\\\"">>}, {<<"bar">>, <<"good">>}]},
{<<"foo=\"\\\";bar">>, {error, badarg}},
{<<"">>, {error, badarg}},
{<<"foo=bar , baz=wibble ">>,