diff options
author | Loïc Hoguin <[email protected]> | 2012-12-20 14:19:39 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2012-12-20 14:19:39 +0100 |
commit | 8858ca240fe42e3fcd0b9c3b1a2388b432301a27 (patch) | |
tree | 9654f8bda770961d70061beeb4c42ba39f2fc8c0 /src/cowboy_http.erl | |
parent | f48902cee7f4a08659232ab2d3f30b6e1117752a (diff) | |
download | cowboy-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.erl | 64 |
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 ">>, |