diff options
Diffstat (limited to 'src/cowboy_req.erl')
-rw-r--r-- | src/cowboy_req.erl | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl index 67d2a0f..2d45a59 100644 --- a/src/cowboy_req.erl +++ b/src/cowboy_req.erl @@ -183,15 +183,13 @@ new(Socket, Transport, Method, Path, Query, Fragment, method=Method, path=Path, qs=Query, fragment=Fragment, version=Version, headers=Headers, host=Host, port=Port, buffer=Buffer, onresponse=OnResponse}, - case CanKeepalive of + case CanKeepalive and (Version =:= {1, 1}) of false -> Req#http_req{connection=close}; true -> case lists:keyfind(<<"connection">>, 1, Headers) of - false when Version =:= {1, 1} -> - Req; %% keepalive false -> - Req#http_req{connection=close}; + Req; %% keepalive {_, ConnectionHeader} -> Tokens = parse_connection_before(ConnectionHeader, []), Connection = connection_to_atom(Tokens), @@ -1138,8 +1136,18 @@ response_merge_headers(Headers, RespHeaders, DefaultHeaders) -> -spec merge_headers(cowboy_http:headers(), cowboy_http:headers()) -> cowboy_http:headers(). + +%% Merge headers by prepending the tuples in the second list to the +%% first list. It also handles Set-Cookie properly, which supports +%% duplicated entries. Notice that, while the RFC2109 does allow more +%% than one cookie to be set per Set-Cookie header, we are following +%% the implementation of common web servers and applications which +%% return many distinct headers per each Set-Cookie entry to avoid +%% issues with clients/browser which may not support it. merge_headers(Headers, []) -> Headers; +merge_headers(Headers, [{<<"set-cookie">>, Value}|Tail]) -> + merge_headers([{<<"set-cookie">>, Value}|Headers], Tail); merge_headers(Headers, [{Name, Value}|Tail]) -> Headers2 = case lists:keymember(Name, 1, Headers) of true -> Headers; @@ -1333,4 +1341,26 @@ connection_to_atom_test_() -> [{lists:flatten(io_lib:format("~p", [T])), fun() -> R = connection_to_atom(T) end} || {T, R} <- Tests]. +merge_headers_test() -> + Left0 = [{<<"content-length">>,<<"13">>},{<<"server">>,<<"Cowboy">>}], + Right0 = [{<<"set-cookie">>,<<"foo=bar">>},{<<"content-length">>,<<"11">>}], + + ?assertMatch( + [{<<"set-cookie">>,<<"foo=bar">>}, + {<<"content-length">>,<<"13">>}, + {<<"server">>,<<"Cowboy">>}], + merge_headers(Left0, Right0)), + + Left1 = [{<<"content-length">>,<<"13">>},{<<"server">>,<<"Cowboy">>}], + Right1 = [{<<"set-cookie">>,<<"foo=bar">>},{<<"set-cookie">>,<<"bar=baz">>}], + + ?assertMatch( + [{<<"set-cookie">>,<<"bar=baz">>}, + {<<"set-cookie">>,<<"foo=bar">>}, + {<<"content-length">>,<<"13">>}, + {<<"server">>,<<"Cowboy">>}], + merge_headers(Left1, Right1)), + + ok. + -endif. |