aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http_req.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2011-10-05 03:17:13 +0200
committerLoïc Hoguin <[email protected]>2011-10-05 13:32:20 +0200
commitbf5c2717bc49d82f6415536c7ff0be2e1d8361a5 (patch)
treeb5bbbf1e3e25315438c5afc1d21cf017c6e2225b /src/cowboy_http_req.erl
parent9a775cce3c2cdab064dd79df29914296cf642a8d (diff)
downloadcowboy-bf5c2717bc49d82f6415536c7ff0be2e1d8361a5.tar.gz
cowboy-bf5c2717bc49d82f6415536c7ff0be2e1d8361a5.tar.bz2
cowboy-bf5c2717bc49d82f6415536c7ff0be2e1d8361a5.zip
Parse 'Connection' headers as a list of tokens
Replaces the 'Connection' interpretation in cowboy_http_protocol from raw value to the parsed value, looking for a single token matching close/keep-alive instead of the whole raw value (which could contain more than one token, for example with Firefox 6+ using websocket). Introduce the functions cowboy_http_req:parse_header/2 and /3 to semantically parse the header values and return a proper Erlang term.
Diffstat (limited to 'src/cowboy_http_req.erl')
-rw-r--r--src/cowboy_http_req.erl49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl
index 272c8a8..808a108 100644
--- a/src/cowboy_http_req.erl
+++ b/src/cowboy_http_req.erl
@@ -28,6 +28,7 @@
qs_val/2, qs_val/3, qs_vals/1, raw_qs/1,
binding/2, binding/3, bindings/1,
header/2, header/3, headers/1,
+ parse_header/2, parse_header/3,
cookie/2, cookie/3, cookies/1
]). %% Request API.
@@ -182,6 +183,54 @@ header(Name, Req, Default) when is_atom(Name) orelse is_binary(Name) ->
headers(Req) ->
{Req#http_req.headers, Req}.
+%% @doc Semantically parse headers.
+%%
+%% When the value isn't found, a proper default value for the type
+%% returned is used as a return value.
+%% @see parse_header/3
+-spec parse_header(http_header(), #http_req{})
+ -> {tokens, [binary()], #http_req{}}
+ | {undefined, binary(), #http_req{}}
+ | {error, badarg}.
+parse_header('Connection', Req) ->
+ parse_header('Connection', Req, []);
+parse_header(Name, Req) ->
+ parse_header(Name, Req, undefined).
+
+%% @doc Semantically parse headers.
+%%
+%% When the header is known, a named tuple is returned containing
+%% {Type, P, Req} with Type being the type of value found in P.
+%% For example, the header 'Connection' is a list of tokens, therefore
+%% the value returned will be a list of binary values and Type will be
+%% 'tokens'.
+%%
+%% When the header is known but not found, the tuple {Type, Default, Req}
+%% is returned instead.
+%%
+%% When the header is unknown, the value is returned directly as an
+%% 'undefined' tagged tuple.
+-spec parse_header(http_header(), #http_req{}, any())
+ -> {tokens, [binary()], #http_req{}}
+ | {undefined, binary(), #http_req{}}
+ | {error, badarg}.
+parse_header(Name, Req=#http_req{p_headers=PHeaders}, Default)
+ when Name =:= 'Connection' ->
+ case header(Name, Req) of
+ {undefined, Req2} -> {tokens, Default, Req2};
+ {Value, Req2} ->
+ case cowboy_http:parse_tokens_list(Value) of
+ {error, badarg} ->
+ {error, badarg};
+ P ->
+ {tokens, P, Req2#http_req{
+ p_headers=[{Name, P}|PHeaders]}}
+ end
+ end;
+parse_header(Name, Req, Default) ->
+ {Value, Req2} = header(Name, Req, Default),
+ {undefined, Value, Req2}.
+
%% @equiv cookie(Name, Req, undefined)
-spec cookie(binary(), #http_req{})
-> {binary() | true | undefined, #http_req{}}.