aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http.erl
diff options
context:
space:
mode:
authorBoris Pozdnyakov <[email protected]>2023-02-17 16:34:54 +0400
committerLoïc Hoguin <[email protected]>2023-12-15 17:12:37 +0100
commite2002721784a8c4fa0cb1486eb88438c92d8a251 (patch)
tree19b43d2c906a97bbadbeec6b543db1b64a2073cb /src/cowboy_http.erl
parent1547e9b93e9a2b40e03edc6e84015dcbf9dccadb (diff)
downloadcowboy-e2002721784a8c4fa0cb1486eb88438c92d8a251.tar.gz
cowboy-e2002721784a8c4fa0cb1486eb88438c92d8a251.tar.bz2
cowboy-e2002721784a8c4fa0cb1486eb88438c92d8a251.zip
Reject invalid Connection header
LH: Small tweaks and added an HTTP/1.0 test.
Diffstat (limited to 'src/cowboy_http.erl')
-rw-r--r--src/cowboy_http.erl30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index 02051cd..8dd2870 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -350,11 +350,17 @@ after_parse({request, Req=#{streamid := StreamID, method := Method,
TE = maps:get(<<"te">>, Headers, undefined),
Streams = [#stream{id=StreamID, state=StreamState,
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}
+ State1 = State0#state{streams=Streams, flow=Flow},
+ State2 = case maybe_req_close(State1, Headers, Version) of
+ close ->
+ State1#state{last_streamid=StreamID};
+ keepalive ->
+ State1;
+ bad_connection_header ->
+ error_terminate(400, State1, {connection_error, protocol_error,
+ 'The Connection header is invalid. (RFC7230 6.1)'})
end,
- State = set_timeout(State1, idle_timeout),
+ State = set_timeout(State2, idle_timeout),
parse(Buffer, commands(State, StreamID, Commands))
catch Class:Exception:Stacktrace ->
cowboy:log(cowboy_stream:make_error_log(init,
@@ -1353,17 +1359,23 @@ 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 cow_http_hd:parse_connection(Conn) of
+ Conns ->
+ case lists:member(<<"keep-alive">>, Conns) of
+ true -> keepalive;
+ false -> close
+ end
+ catch _:_ ->
+ bad_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
+ try connection_hd_is_close(Conn) of
true -> close;
false -> keepalive
+ catch _:_ ->
+ bad_connection_header
end;
maybe_req_close(_, _, _) ->
keepalive.