Browse Source

Document how to recover from cookie parsing errors

Loïc Hoguin 5 years ago
parent
commit
62836cdddc

+ 5 - 0
doc/src/manual/cowboy_req.match_cookies.asciidoc

@@ -31,6 +31,10 @@ be converted through the use of constraints, making this
 function able to extract, validate and convert values all
 function able to extract, validate and convert values all
 in one step.
 in one step.
 
 
+This function will crash on invalid cookie data. How to
+handle this is explained in details in the manual page for
+link:man:cowboy_req:parse_cookies(3)[cowboy_req:parse_cookies(3)].
+
 == Arguments
 == Arguments
 
 
 Fields::
 Fields::
@@ -85,4 +89,5 @@ An exception is triggered when the match fails.
 == See also
 == See also
 
 
 link:man:cowboy_req(3)[cowboy_req(3)],
 link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:filter_cookies(3)[cowboy_req:filter_cookies(3)],
 link:man:cowboy_req:parse_cookies(3)[cowboy_req:parse_cookies(3)]
 link:man:cowboy_req:parse_cookies(3)[cowboy_req:parse_cookies(3)]

+ 30 - 4
doc/src/manual/cowboy_req.parse_cookies.asciidoc

@@ -18,10 +18,35 @@ Parse cookie headers.
 
 
 Alias for link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(<<"cookie">>, Req)].
 Alias for link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(<<"cookie">>, Req)].
 
 
-When the cookie header is missing, `[]` is returned.
-
-While an empty cookie header is not valid, some clients do
-send it. Cowboy will in this case also return `[]`.
+When the cookie header is missing or empty, `[]` is returned.
+
+This function will crash on invalid cookie data. Because
+invalid cookies are fairly common when dealing with browsers
+(because of the string interface that the Javascript API provides),
+it is recommended to filter the cookie header value before
+attempting to parse it. This can be accomplished by calling
+the function link:man:cowboy_req:filter_cookies(3)[cowboy_req:filter_cookies(3)]
+first. This does not guarantee that parsing succeeds. If it
+still fails it is recommended to send an error response or
+redirect with instructions to delete the relevant cookies:
+
+.Recover from cookie parsing errors
+[source,erlang]
+----
+Req1 = cowboy_req:filter_cookies([session_id, token], Req0),
+try cowboy_req:parse_cookies(Req1) of
+    Cookies ->
+        do_something(Req1, Cookies)
+catch _:_ ->
+    %% We can't parse the cookies we need, unset them
+    %% otherwise the browser will continue sending them.
+    Req2 = cowboy_req:set_resp_cookie(<<"session_id">>,
+        <<>>, Req1, #{max_age => 0}),
+    Req = cowboy_req:set_resp_cookie(<<"token">>,
+        <<>>, Req2, #{max_age => 0}),
+    cowboy_req:reply(500, Req)
+end.
+----
 
 
 == Arguments
 == Arguments
 
 
@@ -52,4 +77,5 @@ Cookies = cowboy_req:parse_cookies(Req),
 
 
 link:man:cowboy_req(3)[cowboy_req(3)],
 link:man:cowboy_req(3)[cowboy_req(3)],
 link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(3)],
 link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(3)],
+link:man:cowboy_req:filter_cookies(3)[cowboy_req:filter_cookies(3)],
 link:man:cowboy_req:match_cookies(3)[cowboy_req:match_cookies(3)]
 link:man:cowboy_req:match_cookies(3)[cowboy_req:match_cookies(3)]