Web MQTT: Send CONNACK error code before closing connection
"If the Client supplies a zero-byte ClientId with CleanSession set to 0, the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02 (Identifier rejected) and then close the Network Connection" [MQTT-3.1.3-8]. In Web MQTT, the CONNACK was not sent to the client because the Web MQTT connection process terminated before being sending the CONNACK to the client.
This commit is contained in:
		
							parent
							
								
									4cd69b9034
								
							
						
					
					
						commit
						0058380fbd
					
				| 
						 | 
					@ -106,5 +106,5 @@ persist_static_configuration() ->
 | 
				
			||||||
    rabbit_mqtt_util:init_sparkplug(),
 | 
					    rabbit_mqtt_util:init_sparkplug(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {ok, MailboxSoftLimit} = application:get_env(?APP_NAME, mailbox_soft_limit),
 | 
					    {ok, MailboxSoftLimit} = application:get_env(?APP_NAME, mailbox_soft_limit),
 | 
				
			||||||
    ?assert(is_number(MailboxSoftLimit)),
 | 
					    ?assert(is_integer(MailboxSoftLimit)),
 | 
				
			||||||
    ok = persistent_term:put(?PERSISTENT_TERM_MAILBOX_SOFT_LIMIT, MailboxSoftLimit).
 | 
					    ok = persistent_term:put(?PERSISTENT_TERM_MAILBOX_SOFT_LIMIT, MailboxSoftLimit).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,6 @@ groups() ->
 | 
				
			||||||
       quorum_clean_session_true,
 | 
					       quorum_clean_session_true,
 | 
				
			||||||
       classic_clean_session_true,
 | 
					       classic_clean_session_true,
 | 
				
			||||||
       classic_clean_session_false,
 | 
					       classic_clean_session_false,
 | 
				
			||||||
       non_clean_sess_empty_client_id,
 | 
					 | 
				
			||||||
       event_authentication_failure,
 | 
					       event_authentication_failure,
 | 
				
			||||||
       rabbit_mqtt_qos0_queue_overflow
 | 
					       rabbit_mqtt_qos0_queue_overflow
 | 
				
			||||||
      ]}
 | 
					      ]}
 | 
				
			||||||
| 
						 | 
					@ -218,22 +217,6 @@ classic_clean_session_true(Config) ->
 | 
				
			||||||
classic_clean_session_false(Config) ->
 | 
					classic_clean_session_false(Config) ->
 | 
				
			||||||
    validate_durable_queue_type(Config, <<"classicCleanSessionFalse">>, false, rabbit_classic_queue).
 | 
					    validate_durable_queue_type(Config, <<"classicCleanSessionFalse">>, false, rabbit_classic_queue).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%% "If the Client supplies a zero-byte ClientId with CleanSession set to 0,
 | 
					 | 
				
			||||||
%% the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02
 | 
					 | 
				
			||||||
%% (Identifier rejected) and then close the Network Connection" [MQTT-3.1.3-8].
 | 
					 | 
				
			||||||
non_clean_sess_empty_client_id(Config) ->
 | 
					 | 
				
			||||||
    {ok, C} = emqtt:start_link(
 | 
					 | 
				
			||||||
                [{clientid, <<>>},
 | 
					 | 
				
			||||||
                 {clean_start, false},
 | 
					 | 
				
			||||||
                 {proto_ver, v4},
 | 
					 | 
				
			||||||
                 {host, "localhost"},
 | 
					 | 
				
			||||||
                 {port, rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_mqtt)}
 | 
					 | 
				
			||||||
                ]),
 | 
					 | 
				
			||||||
    process_flag(trap_exit, true),
 | 
					 | 
				
			||||||
    ?assertMatch({error, {client_identifier_not_valid, _}},
 | 
					 | 
				
			||||||
                 emqtt:connect(C)),
 | 
					 | 
				
			||||||
    ok = await_exit(C).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
event_authentication_failure(Config) ->
 | 
					event_authentication_failure(Config) ->
 | 
				
			||||||
    {ok, C} = emqtt:start_link(
 | 
					    {ok, C} = emqtt:start_link(
 | 
				
			||||||
                [{username, <<"Trudy">>},
 | 
					                [{username, <<"Trudy">>},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,6 +79,7 @@ subgroups() ->
 | 
				
			||||||
         ,non_clean_sess_reconnect_qos1
 | 
					         ,non_clean_sess_reconnect_qos1
 | 
				
			||||||
         ,non_clean_sess_reconnect_qos0
 | 
					         ,non_clean_sess_reconnect_qos0
 | 
				
			||||||
         ,non_clean_sess_reconnect_qos0_and_qos1
 | 
					         ,non_clean_sess_reconnect_qos0_and_qos1
 | 
				
			||||||
 | 
					         ,non_clean_sess_empty_client_id
 | 
				
			||||||
         ,subscribe_same_topic_same_qos
 | 
					         ,subscribe_same_topic_same_qos
 | 
				
			||||||
         ,subscribe_same_topic_different_qos
 | 
					         ,subscribe_same_topic_different_qos
 | 
				
			||||||
         ,subscribe_multiple
 | 
					         ,subscribe_multiple
 | 
				
			||||||
| 
						 | 
					@ -852,6 +853,16 @@ non_clean_sess_reconnect_qos0_and_qos1(Config) ->
 | 
				
			||||||
    C3 = connect(ClientId, Config, [{clean_start, true}]),
 | 
					    C3 = connect(ClientId, Config, [{clean_start, true}]),
 | 
				
			||||||
    ok = emqtt:disconnect(C3).
 | 
					    ok = emqtt:disconnect(C3).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% "If the Client supplies a zero-byte ClientId with CleanSession set to 0,
 | 
				
			||||||
 | 
					%% the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02
 | 
				
			||||||
 | 
					%% (Identifier rejected) and then close the Network Connection" [MQTT-3.1.3-8].
 | 
				
			||||||
 | 
					non_clean_sess_empty_client_id(Config) ->
 | 
				
			||||||
 | 
					    {C, Connect} = util:start_client(<<>>, Config, 0, [{clean_start, false}]),
 | 
				
			||||||
 | 
					    process_flag(trap_exit, true),
 | 
				
			||||||
 | 
					    ?assertMatch({error, {client_identifier_not_valid, _}},
 | 
				
			||||||
 | 
					                 Connect(C)),
 | 
				
			||||||
 | 
					    ok = await_exit(C).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
subscribe_same_topic_same_qos(Config) ->
 | 
					subscribe_same_topic_same_qos(Config) ->
 | 
				
			||||||
    C = connect(?FUNCTION_NAME, Config),
 | 
					    C = connect(?FUNCTION_NAME, Config),
 | 
				
			||||||
    Topic = <<"a/b">>,
 | 
					    Topic = <<"a/b">>,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,6 +139,8 @@ websocket_info({bump_credit, Msg}, State) ->
 | 
				
			||||||
    handle_credits(State);
 | 
					    handle_credits(State);
 | 
				
			||||||
websocket_info({reply, Data}, State) ->
 | 
					websocket_info({reply, Data}, State) ->
 | 
				
			||||||
    {[{binary, Data}], State, hibernate};
 | 
					    {[{binary, Data}], State, hibernate};
 | 
				
			||||||
 | 
					websocket_info({stop, CloseCode, Error}, State) ->
 | 
				
			||||||
 | 
					    stop(State, CloseCode, Error);
 | 
				
			||||||
websocket_info({'EXIT', _, _}, State) ->
 | 
					websocket_info({'EXIT', _, _}, State) ->
 | 
				
			||||||
    stop(State);
 | 
					    stop(State);
 | 
				
			||||||
websocket_info({'$gen_cast', QueueEvent = {queue_event, _, _}},
 | 
					websocket_info({'$gen_cast', QueueEvent = {queue_event, _, _}},
 | 
				
			||||||
| 
						 | 
					@ -271,9 +273,8 @@ handle_data1(Data, State = #state{socket = Socket,
 | 
				
			||||||
                                                proc_state = ProcState1});
 | 
					                                                proc_state = ProcState1});
 | 
				
			||||||
                        {error, Reason} ->
 | 
					                        {error, Reason} ->
 | 
				
			||||||
                            ?LOG_ERROR("Rejected Web MQTT connection ~ts: ~p", [ConnName, Reason]),
 | 
					                            ?LOG_ERROR("Rejected Web MQTT connection ~ts: ~p", [ConnName, Reason]),
 | 
				
			||||||
                            stop_mqtt_protocol_error({_SendWill = false, State},
 | 
					                            self() ! {stop, ?CLOSE_PROTOCOL_ERROR, connect_packet_rejected},
 | 
				
			||||||
                                                     connect_packet_rejected,
 | 
					                            {[], {_SendWill = false, State}}
 | 
				
			||||||
                                                     ConnName)
 | 
					 | 
				
			||||||
                    end;
 | 
					                    end;
 | 
				
			||||||
                _ ->
 | 
					                _ ->
 | 
				
			||||||
                    case rabbit_mqtt_processor:process_packet(Packet, ProcState) of
 | 
					                    case rabbit_mqtt_processor:process_packet(Packet, ProcState) of
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue