codec.mqtt: password and willMessage field types should be byte[]
Motivation: Update the mqtt-codec based on mqtt spec (3.1.3.5). Modification: Changes made to the file MqttConnectPayload.java. Subsequent changes have been made to files MqttDecoder.java, MqttEncoder.java, MqttMessageBuilders.java. Test cases have been updated. Result: Fixes #6750 .
This commit is contained in:
parent
ea2af3593c
commit
66c83f7b74
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.mqtt;
|
package io.netty.handler.codec.mqtt;
|
||||||
|
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,16 +26,34 @@ public final class MqttConnectPayload {
|
|||||||
|
|
||||||
private final String clientIdentifier;
|
private final String clientIdentifier;
|
||||||
private final String willTopic;
|
private final String willTopic;
|
||||||
private final String willMessage;
|
private final byte[] willMessage;
|
||||||
private final String userName;
|
private final String userName;
|
||||||
private final String password;
|
private final byte[] password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link MqttConnectPayload#MqttConnectPayload(String, String, byte[], String, byte[])} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public MqttConnectPayload(
|
public MqttConnectPayload(
|
||||||
String clientIdentifier,
|
String clientIdentifier,
|
||||||
String willTopic,
|
String willTopic,
|
||||||
String willMessage,
|
String willMessage,
|
||||||
String userName,
|
String userName,
|
||||||
String password) {
|
String password) {
|
||||||
|
this(
|
||||||
|
clientIdentifier,
|
||||||
|
willTopic,
|
||||||
|
willMessage.getBytes(CharsetUtil.UTF_8),
|
||||||
|
userName,
|
||||||
|
password.getBytes(CharsetUtil.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MqttConnectPayload(
|
||||||
|
String clientIdentifier,
|
||||||
|
String willTopic,
|
||||||
|
byte[] willMessage,
|
||||||
|
String userName,
|
||||||
|
byte[] password) {
|
||||||
this.clientIdentifier = clientIdentifier;
|
this.clientIdentifier = clientIdentifier;
|
||||||
this.willTopic = willTopic;
|
this.willTopic = willTopic;
|
||||||
this.willMessage = willMessage;
|
this.willMessage = willMessage;
|
||||||
@ -50,7 +69,15 @@ public final class MqttConnectPayload {
|
|||||||
return willTopic;
|
return willTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link MqttConnectPayload#willMessageInBytes()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public String willMessage() {
|
public String willMessage() {
|
||||||
|
return new String(willMessage, CharsetUtil.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] willMessageInBytes() {
|
||||||
return willMessage;
|
return willMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +85,15 @@ public final class MqttConnectPayload {
|
|||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link MqttConnectPayload#passwordInBytes()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public String password() {
|
public String password() {
|
||||||
|
return new String(password, CharsetUtil.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] passwordInBytes() {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,21 +339,21 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
|||||||
int numberOfBytesConsumed = decodedClientId.numberOfBytesConsumed;
|
int numberOfBytesConsumed = decodedClientId.numberOfBytesConsumed;
|
||||||
|
|
||||||
Result<String> decodedWillTopic = null;
|
Result<String> decodedWillTopic = null;
|
||||||
Result<String> decodedWillMessage = null;
|
Result<byte[]> decodedWillMessage = null;
|
||||||
if (mqttConnectVariableHeader.isWillFlag()) {
|
if (mqttConnectVariableHeader.isWillFlag()) {
|
||||||
decodedWillTopic = decodeString(buffer, 0, 32767);
|
decodedWillTopic = decodeString(buffer, 0, 32767);
|
||||||
numberOfBytesConsumed += decodedWillTopic.numberOfBytesConsumed;
|
numberOfBytesConsumed += decodedWillTopic.numberOfBytesConsumed;
|
||||||
decodedWillMessage = decodeAsciiString(buffer);
|
decodedWillMessage = decodeByteArray(buffer);
|
||||||
numberOfBytesConsumed += decodedWillMessage.numberOfBytesConsumed;
|
numberOfBytesConsumed += decodedWillMessage.numberOfBytesConsumed;
|
||||||
}
|
}
|
||||||
Result<String> decodedUserName = null;
|
Result<String> decodedUserName = null;
|
||||||
Result<String> decodedPassword = null;
|
Result<byte[]> decodedPassword = null;
|
||||||
if (mqttConnectVariableHeader.hasUserName()) {
|
if (mqttConnectVariableHeader.hasUserName()) {
|
||||||
decodedUserName = decodeString(buffer);
|
decodedUserName = decodeString(buffer);
|
||||||
numberOfBytesConsumed += decodedUserName.numberOfBytesConsumed;
|
numberOfBytesConsumed += decodedUserName.numberOfBytesConsumed;
|
||||||
}
|
}
|
||||||
if (mqttConnectVariableHeader.hasPassword()) {
|
if (mqttConnectVariableHeader.hasPassword()) {
|
||||||
decodedPassword = decodeString(buffer);
|
decodedPassword = decodeByteArray(buffer);
|
||||||
numberOfBytesConsumed += decodedPassword.numberOfBytesConsumed;
|
numberOfBytesConsumed += decodedPassword.numberOfBytesConsumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,17 +419,6 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
|||||||
return decodeString(buffer, 0, Integer.MAX_VALUE);
|
return decodeString(buffer, 0, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result<String> decodeAsciiString(ByteBuf buffer) {
|
|
||||||
Result<String> result = decodeString(buffer, 0, Integer.MAX_VALUE);
|
|
||||||
final String s = result.value;
|
|
||||||
for (int i = 0; i < s.length(); i++) {
|
|
||||||
if (s.charAt(i) > 127) {
|
|
||||||
return new Result<String>(null, result.numberOfBytesConsumed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Result<String>(s, result.numberOfBytesConsumed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Result<String> decodeString(ByteBuf buffer, int minBytes, int maxBytes) {
|
private static Result<String> decodeString(ByteBuf buffer, int minBytes, int maxBytes) {
|
||||||
final Result<Integer> decodedSize = decodeMsbLsb(buffer);
|
final Result<Integer> decodedSize = decodeMsbLsb(buffer);
|
||||||
int size = decodedSize.value;
|
int size = decodedSize.value;
|
||||||
@ -445,6 +434,14 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
|||||||
return new Result<String>(s, numberOfBytesConsumed);
|
return new Result<String>(s, numberOfBytesConsumed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Result<byte[]> decodeByteArray(ByteBuf buffer) {
|
||||||
|
final Result<Integer> decodedSize = decodeMsbLsb(buffer);
|
||||||
|
int size = decodedSize.value;
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
buffer.readBytes(bytes);
|
||||||
|
return new Result<byte[]>(bytes, decodedSize.numberOfBytesConsumed + size);
|
||||||
|
}
|
||||||
|
|
||||||
private static Result<Integer> decodeMsbLsb(ByteBuf buffer) {
|
private static Result<Integer> decodeMsbLsb(ByteBuf buffer) {
|
||||||
return decodeMsbLsb(buffer, 0, 65535);
|
return decodeMsbLsb(buffer, 0, 65535);
|
||||||
}
|
}
|
||||||
|
@ -113,8 +113,8 @@ public final class MqttEncoder extends MessageToMessageEncoder<MqttMessage> {
|
|||||||
// Will topic and message
|
// Will topic and message
|
||||||
String willTopic = payload.willTopic();
|
String willTopic = payload.willTopic();
|
||||||
byte[] willTopicBytes = willTopic != null ? encodeStringUtf8(willTopic) : EmptyArrays.EMPTY_BYTES;
|
byte[] willTopicBytes = willTopic != null ? encodeStringUtf8(willTopic) : EmptyArrays.EMPTY_BYTES;
|
||||||
String willMessage = payload.willMessage();
|
byte[] willMessage = payload.willMessageInBytes();
|
||||||
byte[] willMessageBytes = willMessage != null ? encodeStringUtf8(willMessage) : EmptyArrays.EMPTY_BYTES;
|
byte[] willMessageBytes = willMessage != null ? willMessage : EmptyArrays.EMPTY_BYTES;
|
||||||
if (variableHeader.isWillFlag()) {
|
if (variableHeader.isWillFlag()) {
|
||||||
payloadBufferSize += 2 + willTopicBytes.length;
|
payloadBufferSize += 2 + willTopicBytes.length;
|
||||||
payloadBufferSize += 2 + willMessageBytes.length;
|
payloadBufferSize += 2 + willMessageBytes.length;
|
||||||
@ -126,8 +126,8 @@ public final class MqttEncoder extends MessageToMessageEncoder<MqttMessage> {
|
|||||||
payloadBufferSize += 2 + userNameBytes.length;
|
payloadBufferSize += 2 + userNameBytes.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
String password = payload.password();
|
byte[] password = payload.passwordInBytes();
|
||||||
byte[] passwordBytes = password != null ? encodeStringUtf8(password) : EmptyArrays.EMPTY_BYTES;
|
byte[] passwordBytes = password != null ? password : EmptyArrays.EMPTY_BYTES;
|
||||||
if (variableHeader.hasPassword()) {
|
if (variableHeader.hasPassword()) {
|
||||||
payloadBufferSize += 2 + passwordBytes.length;
|
payloadBufferSize += 2 + passwordBytes.length;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package io.netty.handler.codec.mqtt;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -77,9 +78,9 @@ public final class MqttMessageBuilders {
|
|||||||
private boolean willRetain;
|
private boolean willRetain;
|
||||||
private MqttQoS willQos = MqttQoS.AT_MOST_ONCE;
|
private MqttQoS willQos = MqttQoS.AT_MOST_ONCE;
|
||||||
private String willTopic;
|
private String willTopic;
|
||||||
private String willMessage;
|
private byte[] willMessage;
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private byte[] password;
|
||||||
|
|
||||||
ConnectBuilder() {
|
ConnectBuilder() {
|
||||||
}
|
}
|
||||||
@ -119,7 +120,16 @@ public final class MqttMessageBuilders {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link ConnectBuilder#willMessage(byte[])} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public ConnectBuilder willMessage(String willMessage) {
|
public ConnectBuilder willMessage(String willMessage) {
|
||||||
|
willMessage(willMessage.getBytes(CharsetUtil.UTF_8));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectBuilder willMessage(byte[] willMessage) {
|
||||||
this.willMessage = willMessage;
|
this.willMessage = willMessage;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -145,7 +155,16 @@ public final class MqttMessageBuilders {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link ConnectBuilder#password(byte[])} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public ConnectBuilder password(String password) {
|
public ConnectBuilder password(String password) {
|
||||||
|
password(password.getBytes(CharsetUtil.UTF_8));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectBuilder password(byte[] password) {
|
||||||
this.hasPassword = true;
|
this.hasPassword = true;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
return this;
|
return this;
|
||||||
|
@ -28,6 +28,7 @@ import org.junit.Test;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -395,7 +396,13 @@ public class MqttCodecTest {
|
|||||||
actual.clientIdentifier());
|
actual.clientIdentifier());
|
||||||
assertEquals("MqttConnectPayload UserName mismatch ", expected.userName(), actual.userName());
|
assertEquals("MqttConnectPayload UserName mismatch ", expected.userName(), actual.userName());
|
||||||
assertEquals("MqttConnectPayload Password mismatch ", expected.password(), actual.password());
|
assertEquals("MqttConnectPayload Password mismatch ", expected.password(), actual.password());
|
||||||
|
assertTrue(
|
||||||
|
"MqttConnectPayload Password bytes mismatch ",
|
||||||
|
Arrays.equals(expected.passwordInBytes(), actual.passwordInBytes()));
|
||||||
assertEquals("MqttConnectPayload WillMessage mismatch ", expected.willMessage(), actual.willMessage());
|
assertEquals("MqttConnectPayload WillMessage mismatch ", expected.willMessage(), actual.willMessage());
|
||||||
|
assertTrue(
|
||||||
|
"MqttConnectPayload WillMessage bytes mismatch ",
|
||||||
|
Arrays.equals(expected.willMessageInBytes(), actual.willMessageInBytes()));
|
||||||
assertEquals("MqttConnectPayload WillTopic mismatch ", expected.willTopic(), actual.willTopic());
|
assertEquals("MqttConnectPayload WillTopic mismatch ", expected.willTopic(), actual.willTopic());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user