Skip to content

Commit

Permalink
Merge pull request #10737 from HJianBo/fix-mqtt-sn-bugs
Browse files Browse the repository at this point in the history
Avoid urldecode clientid twice
  • Loading branch information
HJianBo committed May 19, 2023
2 parents ba43a0e + f42cab9 commit 48ceb14
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 28 deletions.
18 changes: 6 additions & 12 deletions apps/emqx_gateway/src/emqx_gateway_api_clients.erl
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,9 @@ clients(get, #{
clients_insta(get, #{
bindings := #{
name := Name0,
clientid := ClientId0
clientid := ClientId
}
}) ->
ClientId = emqx_mgmt_util:urldecode(ClientId0),
with_gateway(Name0, fun(GwName, _) ->
case
emqx_gateway_http:lookup_client(
Expand All @@ -172,10 +171,9 @@ clients_insta(get, #{
clients_insta(delete, #{
bindings := #{
name := Name0,
clientid := ClientId0
clientid := ClientId
}
}) ->
ClientId = emqx_mgmt_util:urldecode(ClientId0),
with_gateway(Name0, fun(GwName, _) ->
_ = emqx_gateway_http:kickout_client(GwName, ClientId),
{204}
Expand All @@ -185,10 +183,9 @@ clients_insta(delete, #{
subscriptions(get, #{
bindings := #{
name := Name0,
clientid := ClientId0
clientid := ClientId
}
}) ->
ClientId = emqx_mgmt_util:urldecode(ClientId0),
with_gateway(Name0, fun(GwName, _) ->
case emqx_gateway_http:list_client_subscriptions(GwName, ClientId) of
{error, not_found} ->
Expand All @@ -203,11 +200,10 @@ subscriptions(get, #{
subscriptions(post, #{
bindings := #{
name := Name0,
clientid := ClientId0
clientid := ClientId
},
body := Body
}) ->
ClientId = emqx_mgmt_util:urldecode(ClientId0),
with_gateway(Name0, fun(GwName, _) ->
case {maps:get(<<"topic">>, Body, undefined), subopts(Body)} of
{undefined, _} ->
Expand All @@ -231,12 +227,10 @@ subscriptions(post, #{
subscriptions(delete, #{
bindings := #{
name := Name0,
clientid := ClientId0,
topic := Topic0
clientid := ClientId,
topic := Topic
}
}) ->
ClientId = emqx_mgmt_util:urldecode(ClientId0),
Topic = emqx_mgmt_util:urldecode(Topic0),
with_gateway(Name0, fun(GwName, _) ->
_ = emqx_gateway_http:client_unsubscribe(GwName, ClientId, Topic),
{204}
Expand Down
21 changes: 7 additions & 14 deletions apps/emqx_gateway/src/emqx_gateway_api_listeners.erl
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,12 @@ listeners(post, #{bindings := #{name := Name0}, body := LConf}) ->
end
end).

listeners_insta(delete, #{bindings := #{name := Name0, id := ListenerId0}}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
listeners_insta(delete, #{bindings := #{name := Name0, id := ListenerId}}) ->
with_gateway(Name0, fun(_GwName, _) ->
ok = emqx_gateway_http:remove_listener(ListenerId),
{204}
end);
listeners_insta(get, #{bindings := #{name := Name0, id := ListenerId0}}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
listeners_insta(get, #{bindings := #{name := Name0, id := ListenerId}}) ->
with_gateway(Name0, fun(_GwName, _) ->
case emqx_gateway_conf:listener(ListenerId) of
{ok, Listener} ->
Expand All @@ -130,9 +128,8 @@ listeners_insta(get, #{bindings := #{name := Name0, id := ListenerId0}}) ->
end);
listeners_insta(put, #{
body := LConf,
bindings := #{name := Name0, id := ListenerId0}
bindings := #{name := Name0, id := ListenerId}
}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(_GwName, _) ->
{ok, RespConf} = emqx_gateway_http:update_listener(ListenerId, LConf),
{200, RespConf}
Expand All @@ -141,10 +138,9 @@ listeners_insta(put, #{
listeners_insta_authn(get, #{
bindings := #{
name := Name0,
id := ListenerId0
id := ListenerId
}
}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(GwName, _) ->
try emqx_gateway_http:authn(GwName, ListenerId) of
Authn -> {200, Authn}
Expand All @@ -157,10 +153,9 @@ listeners_insta_authn(post, #{
body := Conf,
bindings := #{
name := Name0,
id := ListenerId0
id := ListenerId
}
}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(GwName, _) ->
{ok, Authn} = emqx_gateway_http:add_authn(GwName, ListenerId, Conf),
{201, Authn}
Expand All @@ -169,10 +164,9 @@ listeners_insta_authn(put, #{
body := Conf,
bindings := #{
name := Name0,
id := ListenerId0
id := ListenerId
}
}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(GwName, _) ->
{ok, Authn} = emqx_gateway_http:update_authn(
GwName, ListenerId, Conf
Expand All @@ -182,10 +176,9 @@ listeners_insta_authn(put, #{
listeners_insta_authn(delete, #{
bindings := #{
name := Name0,
id := ListenerId0
id := ListenerId
}
}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(GwName, _) ->
ok = emqx_gateway_http:remove_authn(GwName, ListenerId),
{204}
Expand Down
7 changes: 5 additions & 2 deletions apps/emqx_gateway_mqttsn/src/emqx_mqttsn_channel.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1791,14 +1791,14 @@ message_to_packet(
handle_call({subscribe, Topic, SubOpts}, _From, Channel) ->
case do_subscribe({?SN_INVALID_TOPIC_ID, Topic, SubOpts}, Channel) of
{ok, {_, NTopicName, NSubOpts}, NChannel} ->
reply({ok, {NTopicName, NSubOpts}}, NChannel);
reply_and_update({ok, {NTopicName, NSubOpts}}, NChannel);
{error, ?SN_RC2_EXCEED_LIMITATION} ->
reply({error, exceed_limitation}, Channel)
end;
handle_call({unsubscribe, Topic}, _From, Channel) ->
TopicFilters = [emqx_topic:parse(Topic)],
{ok, _, NChannel} = do_unsubscribe(TopicFilters, Channel),
reply(ok, NChannel);
reply_and_update(ok, NChannel);
handle_call(subscriptions, _From, Channel = #channel{session = Session}) ->
reply({ok, maps:to_list(emqx_session:info(subscriptions, Session))}, Channel);
handle_call(kick, _From, Channel) ->
Expand Down Expand Up @@ -2192,6 +2192,9 @@ terminate(_Reason, _Channel) ->
reply(Reply, Channel) ->
{reply, Reply, Channel}.

reply_and_update(Reply, Channel) ->
{reply, Reply, [{event, updated}], Channel}.

shutdown(Reason, Channel) ->
{shutdown, Reason, Channel}.

Expand Down
40 changes: 40 additions & 0 deletions apps/emqx_gateway_mqttsn/test/emqx_sn_protocol_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2259,6 +2259,46 @@ t_clients_subscription_api(_) ->
?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)),
gen_udp:close(Socket).

t_clients_api_complex_id(_) ->
ClientId = <<"!@#$%^&*()_+{}:\"<>?/">>,
ClientIdUriEncoded = cow_qs:urlencode(ClientId),
Path = "/gateways/mqttsn/clients/" ++ binary_to_list(ClientIdUriEncoded),
{ok, Socket} = gen_udp:open(0, [binary]),
send_connect_msg(Socket, ClientId),
?assertEqual(<<3, ?SN_CONNACK, 0>>, receive_response(Socket)),
%% get
{200, Client} = request(get, Path),
?assertMatch(#{clientid := ClientId}, Client),
%% subscription list
{200, []} = request(get, Path ++ "/subscriptions"),
%% kickout
{204, _} = request(delete, Path),
gen_udp:close(Socket).

t_update_info_after_subscribed_via_api(_) ->
ClientId = <<"client_id_test1">>,
Path = "/gateways/mqttsn/clients/client_id_test1/subscriptions",
{ok, Socket} = gen_udp:open(0, [binary]),
send_connect_msg(Socket, ClientId),
?assertEqual(<<3, ?SN_CONNACK, 0>>, receive_response(Socket)),
%% create
SubReq = #{
topic => <<"tx">>,
qos => 1,
nl => 0,
rap => 0,
rh => 0
},
{201, _SubsResp} = request(post, Path, SubReq),
timer:sleep(500),
%% assert
{200, Client} = request(get, "/gateways/mqttsn/clients/client_id_test1"),
?assertMatch(#{subscriptions_cnt := 1}, Client),

send_disconnect_msg(Socket, undefined),
?assertEqual(<<2, ?SN_DISCONNECT>>, receive_response(Socket)),
gen_udp:close(Socket).

%%--------------------------------------------------------------------
%% Helper funcs
%%--------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions changes/ce/fix-10737.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix the issue where the HTTP API interface of Gateway cannot handle ClientIDs with
special characters, such as: `!@#$%^&*()_+{}:"<>?/`.

0 comments on commit 48ceb14

Please sign in to comment.