From 091c49277f0be772248e7376c9f1121a08813405 Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Wed, 14 Jun 2023 10:51:31 +0800 Subject: [PATCH 1/2] fix: api_listener crash when setting max_connnections as string --- apps/emqx/src/emqx_listeners.erl | 10 +++++++++- apps/emqx_management/src/emqx_mgmt_api_listeners.erl | 8 +++++++- .../test/emqx_mgmt_api_listeners_SUITE.erl | 10 ++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/apps/emqx/src/emqx_listeners.erl b/apps/emqx/src/emqx_listeners.erl index 410519a6c..b8205a5f6 100644 --- a/apps/emqx/src/emqx_listeners.erl +++ b/apps/emqx/src/emqx_listeners.erl @@ -116,6 +116,7 @@ format_raw_listeners({Type0, Conf}) -> fun ({LName, LConf0}) when is_map(LConf0) -> Bind = parse_bind(LConf0), + MaxConn = maps:get(<<"max_connections">>, LConf0, default_max_conn()), Running = is_running(Type, listener_id(Type, LName), LConf0#{bind => Bind}), LConf1 = maps:remove(<<"authentication">>, LConf0), LConf2 = maps:put(<<"running">>, Running, LConf1), @@ -124,7 +125,10 @@ format_raw_listeners({Type0, Conf}) -> true -> current_conns(Type, LName, Bind); false -> 0 end, - LConf = maps:put(<<"current_connections">>, CurrConn, LConf2), + LConf = maps:merge(LConf2, #{ + <<"current_connections">> => CurrConn, + <<"max_connections">> => ensure_max_conns(MaxConn) + }), {true, {Type0, LName, LConf}}; ({_LName, _MarkDel}) -> false @@ -994,3 +998,7 @@ unregister_ocsp_stapling_refresh(Type, Name) -> default_max_conn() -> <<"infinity">>. + +ensure_max_conns(<<"infinity">>) -> <<"infinity">>; +ensure_max_conns(MaxConn) when is_binary(MaxConn) -> binary_to_integer(MaxConn); +ensure_max_conns(MaxConn) -> MaxConn. diff --git a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl index fae9228a4..36d911b7f 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl @@ -668,7 +668,13 @@ format_status(Key, Node, Listener, Acc) -> max_conn(_Int1, <<"infinity">>) -> <<"infinity">>; max_conn(<<"infinity">>, _Int) -> <<"infinity">>; -max_conn(Int1, Int2) -> Int1 + Int2. +max_conn(Int1, Int2) -> int(Int1) + int(Int2). + +%% If we set max_connections = “123”, +%% it will be converted to #{<<"max_connections">> => <<"123">>} in the raw_conf with no error. +%% so we need to convert it to integer, we should fix this at hocon lib in the future. +int(Bin) when is_binary(Bin) -> binary_to_integer(Bin); +int(Int) when is_integer(Int) -> Int. listener_type_status_example() -> [ diff --git a/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl b/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl index a4ec3fe92..c47cea07e 100644 --- a/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl +++ b/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl @@ -140,6 +140,16 @@ t_list_listeners(Config) when is_list(Config) -> ?assertMatch(#{<<"max_connections">> := <<"infinity">>}, Create), ?assert(is_running(NewListenerId)), + Update2 = request(put, NewPath, [], Create#{<<"max_connections">> => 100}), + ?assertMatch(#{<<"max_connections">> := 100}, Update2), + Get2 = request(get, NewPath, [], []), + ?assertMatch(#{<<"max_connections">> := 100}, Get2), + + Update3 = request(put, NewPath, [], Create#{<<"max_connections">> => <<"123">>}), + ?assertMatch(#{<<"max_connections">> := 123}, Update3), + Get3 = request(get, NewPath, [], []), + ?assertMatch(#{<<"max_connections">> := 123}, Get3), + %% delete ?assertEqual([], delete(NewPath)), ?assertEqual({error, not_found}, is_running(NewListenerId)), From feb08b1181e4aad268184d558388682769ae532f Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Wed, 14 Jun 2023 11:30:41 +0800 Subject: [PATCH 2/2] chore: update 11042 changelog --- apps/emqx_management/src/emqx_mgmt_api_listeners.erl | 8 +------- changes/ce/fix-11042.en.md | 1 + 2 files changed, 2 insertions(+), 7 deletions(-) create mode 100644 changes/ce/fix-11042.en.md diff --git a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl index 36d911b7f..fae9228a4 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl @@ -668,13 +668,7 @@ format_status(Key, Node, Listener, Acc) -> max_conn(_Int1, <<"infinity">>) -> <<"infinity">>; max_conn(<<"infinity">>, _Int) -> <<"infinity">>; -max_conn(Int1, Int2) -> int(Int1) + int(Int2). - -%% If we set max_connections = “123”, -%% it will be converted to #{<<"max_connections">> => <<"123">>} in the raw_conf with no error. -%% so we need to convert it to integer, we should fix this at hocon lib in the future. -int(Bin) when is_binary(Bin) -> binary_to_integer(Bin); -int(Int) when is_integer(Int) -> Int. +max_conn(Int1, Int2) -> Int1 + Int2. listener_type_status_example() -> [ diff --git a/changes/ce/fix-11042.en.md b/changes/ce/fix-11042.en.md new file mode 100644 index 000000000..07d778d8c --- /dev/null +++ b/changes/ce/fix-11042.en.md @@ -0,0 +1 @@ +Fix crash on `/api/listeners` when listener's max_connections is set to a string.