diff options
-rw-r--r-- | src/cowboy_http_req.erl | 30 | ||||
-rw-r--r-- | test/http_SUITE.erl | 2 |
2 files changed, 27 insertions, 5 deletions
diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index 66f2da4..a1a37bd 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -318,6 +318,7 @@ body_qs(Req) -> reply(Code, Headers, Body, Req=#http_req{socket=Socket, transport=Transport, connection=Connection, method=Method, resp_state=waiting}) -> + RespConn = response_connection(Headers, Connection), Head = response_head(Code, Headers, [ {<<"Connection">>, atom_to_connection(Connection)}, {<<"Content-Length">>, @@ -329,22 +330,23 @@ reply(Code, Headers, Body, Req=#http_req{socket=Socket, 'HEAD' -> Transport:send(Socket, Head); _ -> Transport:send(Socket, [Head, Body]) end, - {ok, Req#http_req{resp_state=done}}. + {ok, Req#http_req{connection=RespConn, resp_state=done}}. %% @doc Initiate the sending of a chunked reply to the client. %% @see cowboy_http_req:chunk/2 -spec chunked_reply(http_status(), http_headers(), #http_req{}) -> {ok, #http_req{}}. chunked_reply(Code, Headers, Req=#http_req{socket=Socket, transport=Transport, - resp_state=waiting}) -> + connection=Connection, resp_state=waiting}) -> + RespConn = response_connection(Headers, Connection), Head = response_head(Code, Headers, [ - {<<"Connection">>, <<"close">>}, + {<<"Connection">>, atom_to_connection(Connection)}, {<<"Transfer-Encoding">>, <<"chunked">>}, {<<"Date">>, cowboy_clock:rfc1123()}, {<<"Server">>, <<"Cowboy">>} ]), Transport:send(Socket, Head), - {ok, Req#http_req{resp_state=chunks}}. + {ok, Req#http_req{connection=RespConn, resp_state=chunks}}. %% @doc Send a chunk of data. %% @@ -381,6 +383,26 @@ parse_qs(Qs) -> [Name, Value] -> {quoted:from_url(Name), quoted:from_url(Value)} end || Token <- Tokens]. +-spec response_connection(http_headers(), keepalive | close) + -> keepalive | close. +response_connection([], Connection) -> + Connection; +response_connection([{Name, Value}|Tail], Connection) -> + case Name of + 'Connection' -> response_connection_parse(Value); + Name -> + Name2 = cowboy_bstr:to_lower(Name), + case Name2 of + <<"connection">> -> response_connection_parse(Value); + _Any -> response_connection(Tail, Connection) + end + end. + +-spec response_connection_parse(binary()) -> keepalive | close. +response_connection_parse(ReplyConn) -> + Tokens = cowboy_http:parse_tokens_list(ReplyConn), + cowboy_http:connection_to_atom(Tokens). + -spec response_head(http_status(), http_headers(), http_headers()) -> iolist(). response_head(Code, Headers, DefaultHeaders) -> StatusLine = <<"HTTP/1.1 ", (status(Code))/binary, "\r\n">>, diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl index 8bfebaa..cb70ff3 100644 --- a/test/http_SUITE.erl +++ b/test/http_SUITE.erl @@ -117,7 +117,7 @@ headers_dupe(Config) -> {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {_Start, _Length} = binary:match(Data, <<"Connection: close">>), nomatch = binary:match(Data, <<"Connection: keep-alive">>), - ok = gen_tcp:close(Socket). + {error, closed} = gen_tcp:recv(Socket, 0, 1000). headers_huge(Config) -> Cookie = lists:flatten(["whatever_man_biiiiiiiiiiiig_cookie_me_want_77=" |