diff --git a/apisix/stream/plugins/mqtt-proxy.lua b/apisix/stream/plugins/mqtt-proxy.lua index 13318e4114e1..fae0eb08f5f4 100644 --- a/apisix/stream/plugins/mqtt-proxy.lua +++ b/apisix/stream/plugins/mqtt-proxy.lua @@ -111,7 +111,13 @@ local function parse_mqtt(data) return res end - res.client_id = str_sub(data, parsed_pos + 1, parsed_pos + client_id_len) + if client_id_len == 0 then + -- A Server MAY allow a Client to supply a ClientID that has a length of zero bytes + res.client_id = "" + else + res.client_id = str_sub(data, parsed_pos + 1, parsed_pos + client_id_len) + end + parsed_pos = parsed_pos + client_id_len res.expect_len = parsed_pos @@ -120,10 +126,10 @@ end function _M.preread(conf, ctx) - core.log.warn("plugin rewrite phase, conf: ", core.json.encode(conf)) - -- core.log.warn(" ctx: ", core.json.encode(ctx, true)) local sock = ngx.req.socket() - local data, err = sock:peek(16) + -- the header format of MQTT CONNECT can be found in + -- https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901033 + local data, err = sock:peek(14) if not data then core.log.error("failed to read first 16 bytes: ", err) return 503 diff --git a/t/stream-plugin/mqtt-proxy.t b/t/stream-plugin/mqtt-proxy.t index 4f3796ba9379..ae46fa8cdcc9 100644 --- a/t/stream-plugin/mqtt-proxy.t +++ b/t/stream-plugin/mqtt-proxy.t @@ -316,5 +316,23 @@ passed "\x10\x0f\x00\x04\x4d\x51\x54\x54\x04\x02\x00\x3c\x00\x03\x66\x6f\x6f" --- stream_response hello world +--- grep_error_log eval +qr/mqtt client id: \w+/ +--- grep_error_log_out +mqtt client id: foo +--- no_error_log +[error] + + + +=== TEST 13: hit route with empty client id +--- stream_enable +--- stream_request eval +"\x10\x0f\x00\x04\x4d\x51\x54\x54\x04\x02\x00\x3c\x00\x00" +--- stream_response +hello world +--- grep_error_log eval +qr/mqtt client id: \w+/ +--- grep_error_log_out --- no_error_log [error]