mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Use 'Connection' header only when necessary
Fixes #839 when 'Connection: Keep-Alive' wasn't sent in a HTTP/1.0 response. Now the usage of 'Connection' header is consistent with current protocol version: when this header is not specified explicitly in the response, HTTP/1.0 implies 'Connection: close' and HTTP/1.1 implies 'Connection: Keep-Alive'. So if current 'Connection' value matches the default value of current protocol, we won't state obvious fact in the response; and vice versa. Amended to fix and improve tests, and revert the variable name change from HTTP11Headers to StdHeaders. I think it's still good to leave it as is because it's not really a standard header for HTTP/1.0, and it's gone from HTTP/2 entirely.
This commit is contained in:
parent
19a279dfdc
commit
8c60dd6c1b
2 changed files with 24 additions and 9 deletions
|
@ -820,7 +820,9 @@ reply(Status, Headers, Body, Req=#http_req{
|
|||
resp_state=RespState, resp_headers=RespHeaders})
|
||||
when RespState =:= waiting; RespState =:= waiting_stream ->
|
||||
HTTP11Headers = if
|
||||
Transport =/= cowboy_spdy, Version =:= 'HTTP/1.1' ->
|
||||
Transport =/= cowboy_spdy, Version =:= 'HTTP/1.0', Connection =:= keepalive ->
|
||||
[{<<"connection">>, atom_to_connection(Connection)}];
|
||||
Transport =/= cowboy_spdy, Version =:= 'HTTP/1.1', Connection =:= close ->
|
||||
[{<<"connection">>, atom_to_connection(Connection)}];
|
||||
true ->
|
||||
[]
|
||||
|
@ -1134,13 +1136,20 @@ chunked_response(Status, Headers, Req=#http_req{
|
|||
when RespState =:= waiting; RespState =:= waiting_stream ->
|
||||
RespConn = response_connection(Headers, Connection),
|
||||
HTTP11Headers = if
|
||||
Version =:= 'HTTP/1.0', Connection =:= keepalive ->
|
||||
[{<<"connection">>, atom_to_connection(Connection)}];
|
||||
Version =:= 'HTTP/1.0' -> [];
|
||||
true ->
|
||||
MaybeTE = if
|
||||
RespState =:= waiting_stream -> [];
|
||||
true -> [{<<"transfer-encoding">>, <<"chunked">>}]
|
||||
end,
|
||||
[{<<"connection">>, atom_to_connection(Connection)}|MaybeTE]
|
||||
if
|
||||
Connection =:= close ->
|
||||
[{<<"connection">>, atom_to_connection(Connection)}|MaybeTE];
|
||||
true ->
|
||||
MaybeTE
|
||||
end
|
||||
end,
|
||||
RespState2 = if
|
||||
Version =:= 'HTTP/1.1', RespState =:= 'waiting' -> chunks;
|
||||
|
|
|
@ -432,7 +432,10 @@ http10_keepalive_default(Config) ->
|
|||
ok = raw_send(Client, Normal),
|
||||
case catch raw_recv_head(Client) of
|
||||
{'EXIT', _} -> error(closed);
|
||||
_ -> ok
|
||||
Data ->
|
||||
{'HTTP/1.0', 200, _, Rest} = cow_http:parse_status_line(Data),
|
||||
{Headers, _} = cow_http:parse_headers(Rest),
|
||||
false = lists:keymember(<<"connection">>, 1, Headers)
|
||||
end,
|
||||
ok = raw_send(Client, Normal),
|
||||
case catch raw_recv_head(Client) of
|
||||
|
@ -446,7 +449,10 @@ http10_keepalive_forced(Config) ->
|
|||
ok = raw_send(Client, Keepalive),
|
||||
case catch raw_recv_head(Client) of
|
||||
{'EXIT', _} -> error(closed);
|
||||
_ -> ok
|
||||
Data ->
|
||||
{'HTTP/1.0', 200, _, Rest} = cow_http:parse_status_line(Data),
|
||||
{Headers, _} = cow_http:parse_headers(Rest),
|
||||
{_, <<"keep-alive">>} = lists:keyfind(<<"connection">>, 1, Headers)
|
||||
end,
|
||||
ok = raw_send(Client, Keepalive),
|
||||
case catch raw_recv_head(Client) of
|
||||
|
@ -461,7 +467,7 @@ keepalive_max(Config) ->
|
|||
CloseRef = gun:get(ConnPid, "/", [{<<"connection">>, <<"keep-alive">>}]),
|
||||
_ = [begin
|
||||
{response, nofin, 200, Headers} = gun:await(ConnPid, Ref, MRef),
|
||||
{_, <<"keep-alive">>} = lists:keyfind(<<"connection">>, 1, Headers)
|
||||
false = lists:keymember(<<"connection">>, 1, Headers)
|
||||
end || Ref <- Refs],
|
||||
{response, nofin, 200, Headers} = gun:await(ConnPid, CloseRef, MRef),
|
||||
{_, <<"close">>} = lists:keyfind(<<"connection">>, 1, Headers),
|
||||
|
@ -476,7 +482,7 @@ keepalive_nl(Config) ->
|
|||
end || _ <- lists:seq(1, 10)],
|
||||
_ = [begin
|
||||
{response, nofin, 200, Headers} = gun:await(ConnPid, Ref),
|
||||
{_, <<"keep-alive">>} = lists:keyfind(<<"connection">>, 1, Headers)
|
||||
false = lists:keymember(<<"connection">>, 1, Headers)
|
||||
end || Ref <- Refs],
|
||||
ok.
|
||||
|
||||
|
@ -730,7 +736,7 @@ rest_keepalive(Config) ->
|
|||
Refs = [gun:get(ConnPid, "/simple") || _ <- lists:seq(1, 10)],
|
||||
_ = [begin
|
||||
{response, nofin, 200, Headers} = gun:await(ConnPid, Ref),
|
||||
{_, <<"keep-alive">>} = lists:keyfind(<<"connection">>, 1, Headers)
|
||||
false = lists:keymember(<<"connection">>, 1, Headers)
|
||||
end || Ref <- Refs],
|
||||
ok.
|
||||
|
||||
|
@ -744,9 +750,9 @@ rest_keepalive_post(Config) ->
|
|||
} || _ <- lists:seq(1, 5)],
|
||||
_ = [begin
|
||||
{response, fin, 403, Headers1} = gun:await(ConnPid, Ref1),
|
||||
{_, <<"keep-alive">>} = lists:keyfind(<<"connection">>, 1, Headers1),
|
||||
false = lists:keymember(<<"connection">>, 1, Headers1),
|
||||
{response, fin, 303, Headers2} = gun:await(ConnPid, Ref2),
|
||||
{_, <<"keep-alive">>} = lists:keyfind(<<"connection">>, 1, Headers2)
|
||||
false = lists:keymember(<<"connection">>, 1, Headers2)
|
||||
end || {Ref1, Ref2} <- Refs],
|
||||
ok.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue