diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index c9bceed8..099a188b 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -357,7 +357,10 @@ after_parse({request, Req=#{streamid := StreamID, method := Method, method=Method, version=Version, te=TE}|Streams0], State1 = case maybe_req_close(State0, Headers, Version) of close -> State0#state{streams=Streams, last_streamid=StreamID, flow=Flow}; - keepalive -> State0#state{streams=Streams, flow=Flow} + keepalive -> State0#state{streams=Streams, flow=Flow}; + invalid_connection_header -> + error_terminate(400, State0, + {stream_error, protocol_error, 'The Connection header is invalid. (RFC7230 3.2.6) (RFC7230 6.1)'}) end, State = set_timeout(State1, idle_timeout), parse(Buffer, commands(State, StreamID, Commands)) @@ -1341,17 +1344,25 @@ stream_call_terminate(StreamID, Reason, StreamState, #state{opts=Opts}) -> maybe_req_close(#state{opts=#{http10_keepalive := false}}, _, 'HTTP/1.0') -> close; maybe_req_close(_, #{<<"connection">> := Conn}, 'HTTP/1.0') -> - Conns = cow_http_hd:parse_connection(Conn), - case lists:member(<<"keep-alive">>, Conns) of - true -> keepalive; - false -> close + try + Conns = cow_http_hd:parse_connection(Conn), + case lists:member(<<"keep-alive">>, Conns) of + true -> keepalive; + false -> close + end + catch _:_ -> + invalid_connection_header end; maybe_req_close(_, _, 'HTTP/1.0') -> close; maybe_req_close(_, #{<<"connection">> := Conn}, 'HTTP/1.1') -> - case connection_hd_is_close(Conn) of - true -> close; - false -> keepalive + try + case connection_hd_is_close(Conn) of + true -> close; + false -> keepalive + end + catch _:_ -> + invalid_connection_header end; maybe_req_close(_, _, _) -> keepalive. diff --git a/test/rfc7230_SUITE.erl b/test/rfc7230_SUITE.erl index 9846a0f8..42fff8ce 100644 --- a/test/rfc7230_SUITE.erl +++ b/test/rfc7230_SUITE.erl @@ -754,6 +754,14 @@ invalid_header_value(Config) -> "Host: localhost\0rm rf the world\r\n" "\r\n"]). +invalid_header_connection(Config) -> + doc("Header field Connection has invalid format. (RFC7230 3.2.6) (RFC7230 6.1)"), + #{code := 400} = do_raw(Config, [ + "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: jndi{ldap127\r\n" + "\r\n"]). + lower_case_header(Config) -> doc("The header field name is case insensitive. (RFC7230 3.2)"), #{code := 200} = do_raw(Config, [