mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-16 05:00:24 +00:00
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.
This commit is contained in:
parent
9a775cce3c
commit
bf5c2717bc
5 changed files with 184 additions and 20 deletions
|
@ -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{}}.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue