Explorar o código

Fix websocket bug (#2615)

Fix websocket bug.

Prior to this change, websocket connection would be closed directly
without sending connack packet when acl check fails.

This change fix this bug.
Gilbert %!s(int64=6) %!d(string=hai) anos
pai
achega
d3e7d1f0c9
Modificáronse 3 ficheiros con 25 adicións e 11 borrados
  1. 6 6
      Makefile
  2. 3 2
      src/emqx_ws_connection.erl
  3. 16 3
      test/emqx_ws_connection_SUITE.erl

+ 6 - 6
Makefile

@@ -45,8 +45,8 @@ deps:
 eunit:
 	@rebar3 eunit -v
 
-.PHONY: ct-setup
-ct-setup:
+.PHONY: ct_setup
+ct_setup:
 	rebar3 as test compile
 	@mkdir -p data
 	@if [ ! -f data/loaded_plugins ]; then touch data/loaded_plugins; fi
@@ -54,14 +54,14 @@ ct-setup:
 	@ln -s -f '../../../../data' _build/test/lib/emqx/
 
 .PHONY: ct
-ct: ct-setup
+ct: ct_setup
 	@rebar3 ct -v --readable=false --name $(CT_NODE_NAME) --suite=$(shell echo $(foreach var,$(CT_SUITES),test/$(var)_SUITE) | tr ' ' ',')
 
 ## Run one single CT with rebar3
 ## e.g. make ct-one-suite suite=emqx_bridge
-.PHONY: ct-one-suite
-ct-one-suite: ct-setup
-	@rebar3 ct -v --readable=false --name $(CT_NODE_NAME) --suite=$(suite)_SUITE
+.PHONY: $(SUITES:%=ct-%)
+$(CT_SUITES:%=ct-%): ct_setup
+	@rebar3 ct -v --readable=false --name $(CT_NODE_NAME) --suite=$(@:ct-%=%)_SUITE
 
 .PHONY: app.config
 app.config: $(CUTTLEFISH_SCRIPT) etc/gen.emqx.conf

+ 3 - 2
src/emqx_ws_connection.erl

@@ -301,7 +301,6 @@ websocket_info(Info, State) ->
 terminate(SockError, _Req, #state{keepalive   = Keepalive,
                                   proto_state = ProtoState,
                                   shutdown    = Shutdown}) ->
-
     ?LOG(debug, "[WS Connection] Terminated for ~p, sockerror: ~p", [Shutdown, SockError]),
     emqx_keepalive:cancel(Keepalive),
     case {ProtoState, Shutdown} of
@@ -327,7 +326,9 @@ ensure_stats_timer(State) ->
     State.
 
 shutdown(Reason, State) ->
-    {stop, State#state{shutdown = Reason}}.
+    %% Fix the issue#2591(https://github.com/emqx/emqx/issues/2591#issuecomment-500278696)
+    self() ! {stop, State#state{shutdown = Reason}},
+    {ok, State}.
 
 wsock_stats() ->
     [{Key, emqx_pd:get_counter(Key)} || Key <- ?SOCK_STATS].

+ 16 - 3
test/emqx_ws_connection_SUITE.erl

@@ -36,7 +36,9 @@
 -define(PUBQOS, 1).
 
 all() ->
-    [t_ws_connect_api].
+    [ t_ws_connect_api
+    , t_ws_auth_failure
+    ].
 
 init_per_suite(Config) ->
     emqx_ct_helpers:start_apps([]),
@@ -45,13 +47,24 @@ init_per_suite(Config) ->
 end_per_suite(_Config) ->
     emqx_ct_helpers:stop_apps([]).
 
+t_ws_auth_failure(_Config) ->
+    application:set_env(emqx, allow_anonymous, false),
+    WS = rfc6455_client:new("ws://127.0.0.1:8083" ++ "/mqtt", self()),
+    {ok, _} = rfc6455_client:open(WS),
+    Packet = raw_send_serialize(?CLIENT),
+    ok = rfc6455_client:send_binary(WS, Packet),
+    {binary, CONNACK} = rfc6455_client:recv(WS),
+    {ok, ?CONNACK_PACKET(?CONNACK_AUTH), _} = raw_recv_pase(CONNACK),
+    application:set_env(emqx, allow_anonymous, true),
+    ok.
+
 t_ws_connect_api(_Config) ->
     WS = rfc6455_client:new("ws://127.0.0.1:8083" ++ "/mqtt", self()),
     {ok, _} = rfc6455_client:open(WS),
     Packet = raw_send_serialize(?CLIENT),
     ok = rfc6455_client:send_binary(WS, Packet),
-    {binary, CONACK} = rfc6455_client:recv(WS),
-    {ok, ?CONNACK_PACKET(?CONNACK_ACCEPT), _} = raw_recv_pase(CONACK),
+    {binary, CONNACK} = rfc6455_client:recv(WS),
+    {ok, ?CONNACK_PACKET(?CONNACK_ACCEPT), _} = raw_recv_pase(CONNACK),
     Pid = emqx_cm:lookup_conn_pid(<<"mqtt_client">>),
     ConnInfo = emqx_ws_connection:info(Pid),
     ok = t_info(ConnInfo),