Browse Source

Fix cancelling undefined settings timer

when settings_timeout is infinity
Bing Han 7 years ago
parent
commit
e9fd2925ae
2 changed files with 21 additions and 1 deletions
  1. 4 1
      src/cowboy_http2.erl
  2. 17 0
      test/http2_SUITE.erl

+ 4 - 1
src/cowboy_http2.erl

@@ -485,7 +485,10 @@ frame(State0=#state{socket=Socket, transport=Transport, opts=Opts,
 %% Ack for a previously sent SETTINGS frame.
 %% Ack for a previously sent SETTINGS frame.
 frame(State0=#state{local_settings=Local0, next_settings=NextSettings,
 frame(State0=#state{local_settings=Local0, next_settings=NextSettings,
 		next_settings_timer=TRef}, settings_ack) ->
 		next_settings_timer=TRef}, settings_ack) ->
-	ok = erlang:cancel_timer(TRef, [{async, true}, {info, false}]),
+	ok = case TRef of
+		undefined -> ok;
+		_ -> erlang:cancel_timer(TRef, [{async, true}, {info, false}])
+	end,
 	Local = maps:merge(Local0, NextSettings),
 	Local = maps:merge(Local0, NextSettings),
 	State1 = State0#state{local_settings=Local, next_settings=#{},
 	State1 = State0#state{local_settings=Local, next_settings=#{},
 		next_settings_timer=undefined},
 		next_settings_timer=undefined},

+ 17 - 0
test/http2_SUITE.erl

@@ -159,3 +159,20 @@ resp_iolist_body(Config) ->
 	{ok, RespBody} = gun:await_body(ConnPid, Ref),
 	{ok, RespBody} = gun:await_body(ConnPid, Ref),
 	Len = iolist_size(RespBody),
 	Len = iolist_size(RespBody),
 	gun:close(ConnPid).
 	gun:close(ConnPid).
+
+settings_timeout_infinity(Config) ->
+	doc("Ensure infinity for settings_timeout is accepted."),
+	ProtoOpts = #{
+		env => #{dispatch => cowboy_router:compile(init_routes(Config))},
+		settings_timeout => infinity
+	},
+	{ok, Pid} = cowboy:start_clear(name(), [{port, 0}], ProtoOpts),
+	Ref = erlang:monitor(process, Pid),
+	Port = ranch:get_port(name()),
+	{ok, _} = do_handshake([{port, Port}|Config]),
+	receive
+		{'DOWN', Ref, process, Pid, Reason} ->
+			error(Reason)
+	after 1000 ->
+		cowboy:stop_listener(name())
+	end.