From f7405f2c0cb9e917d854e721437daaee1fb1f41d Mon Sep 17 00:00:00 2001 From: Jongyeol Choi Date: Thu, 9 Oct 2014 01:38:20 +0900 Subject: [PATCH] Add exceptions for CONNACK's return code for MQTT 3.1 specification Motivation: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#connack In MQTT 3.1, MQTT server must send a CONNACK with return code if CONNECT request contains an invalid client identifier or an unacceptable protocol version. The return code is one of MqttConnectReturnCode. But, MqttDecoder throws DecoderException when CONNECT request contains invalid value without distinguish situations. This makes it difficult for codec-mqtt users to send a response with return code to clients. Modifications: Added exceptions for client identifier rejected and unacceptable protocol version. MqttDecoder will throw those exceptions instead of DecoderException. Result: Users of codec-mqtt can distinguish which is invalid when CONNECT contains invalid client identifier or invalid protocol version. And, users can send CONNACK with return code to clients. --- .../netty/handler/codec/mqtt/MqttDecoder.java | 4 +- .../mqtt/MqttIdentifierRejectedException.java | 53 ++++++++++++++++++ ...tUnacceptableProtocolVersionException.java | 54 +++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttIdentifierRejectedException.java create mode 100644 codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnacceptableProtocolVersionException.java diff --git a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java index 16052b4f52..1f1a81c6c1 100644 --- a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java +++ b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttDecoder.java @@ -204,7 +204,7 @@ public class MqttDecoder extends ReplayingDecoder { private static Result decodeConnectionVariableHeader(ByteBuf buffer) { final Result protoString = decodeString(buffer); if (!PROTOCOL_NAME.equals(protoString.value)) { - throw new DecoderException("missing " + PROTOCOL_NAME + " signature"); + throw new MqttUnacceptableProtocolVersionException("missing " + PROTOCOL_NAME + " signature"); } int numberOfBytesConsumed = protoString.numberOfBytesConsumed; @@ -322,7 +322,7 @@ public class MqttDecoder extends ReplayingDecoder { final Result decodedClientId = decodeString(buffer); final String decodedClientIdValue = decodedClientId.value; if (!isValidClientId(decodedClientIdValue)) { - throw new DecoderException("invalid clientIdentifier: " + decodedClientIdValue); + throw new MqttIdentifierRejectedException("invalid clientIdentifier: " + decodedClientIdValue); } int numberOfBytesConsumed = decodedClientId.numberOfBytesConsumed; diff --git a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttIdentifierRejectedException.java b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttIdentifierRejectedException.java new file mode 100644 index 0000000000..60fbe92a65 --- /dev/null +++ b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttIdentifierRejectedException.java @@ -0,0 +1,53 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.mqtt; + +import io.netty.handler.codec.DecoderException; + +/** + * A {@link MqttIdentifierRejectedException} which is thrown when a CONNECT request contains invalid client identifier. + */ +public class MqttIdentifierRejectedException extends DecoderException { + + private static final long serialVersionUID = -1323503322689614981L; + + /** + * Creates a new instance + */ + public MqttIdentifierRejectedException() { } + + /** + * Creates a new instance + */ + public MqttIdentifierRejectedException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance + */ + public MqttIdentifierRejectedException(String message) { + super(message); + } + + /** + * Creates a new instance + */ + public MqttIdentifierRejectedException(Throwable cause) { + super(cause); + } + +} diff --git a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnacceptableProtocolVersionException.java b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnacceptableProtocolVersionException.java new file mode 100644 index 0000000000..26b3b9cbc7 --- /dev/null +++ b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnacceptableProtocolVersionException.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.mqtt; + +import io.netty.handler.codec.DecoderException; + +/** + * A {@link MqttUnacceptableProtocolVersionException} which is thrown when + * a CONNECT request contains unacceptable protocol version. + */ +public class MqttUnacceptableProtocolVersionException extends DecoderException { + + private static final long serialVersionUID = 4914652213232455749L; + + /** + * Creates a new instance + */ + public MqttUnacceptableProtocolVersionException() { } + + /** + * Creates a new instance + */ + public MqttUnacceptableProtocolVersionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new instance + */ + public MqttUnacceptableProtocolVersionException(String message) { + super(message); + } + + /** + * Creates a new instance + */ + public MqttUnacceptableProtocolVersionException(Throwable cause) { + super(cause); + } + +}