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.
This commit is contained in:
Gilbert 2019-06-14 11:33:44 +08:00 committed by Shawn
parent c4de0b1792
commit d3e7d1f0c9
3 changed files with 25 additions and 11 deletions

View File

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

View File

@ -301,7 +301,6 @@ websocket_info(Info, State) ->
terminate(SockError, _Req, #state{keepalive = Keepalive, terminate(SockError, _Req, #state{keepalive = Keepalive,
proto_state = ProtoState, proto_state = ProtoState,
shutdown = Shutdown}) -> shutdown = Shutdown}) ->
?LOG(debug, "[WS Connection] Terminated for ~p, sockerror: ~p", [Shutdown, SockError]), ?LOG(debug, "[WS Connection] Terminated for ~p, sockerror: ~p", [Shutdown, SockError]),
emqx_keepalive:cancel(Keepalive), emqx_keepalive:cancel(Keepalive),
case {ProtoState, Shutdown} of case {ProtoState, Shutdown} of
@ -327,7 +326,9 @@ ensure_stats_timer(State) ->
State. State.
shutdown(Reason, 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() -> wsock_stats() ->
[{Key, emqx_pd:get_counter(Key)} || Key <- ?SOCK_STATS]. [{Key, emqx_pd:get_counter(Key)} || Key <- ?SOCK_STATS].

View File

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