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;
|
||||
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
/**
|
||||
@ -25,16 +26,34 @@ public final class MqttConnectPayload {
|
||||
|
||||
private final String clientIdentifier;
|
||||
private final String willTopic;
|
||||
private final String willMessage;
|
||||
private final byte[] willMessage;
|
||||
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(
|
||||
String clientIdentifier,
|
||||
String willTopic,
|
||||
String willMessage,
|
||||
String userName,
|
||||
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.willTopic = willTopic;
|
||||
this.willMessage = willMessage;
|
||||
@ -50,7 +69,15 @@ public final class MqttConnectPayload {
|
||||
return willTopic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link MqttConnectPayload#willMessageInBytes()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public String willMessage() {
|
||||
return new String(willMessage, CharsetUtil.UTF_8);
|
||||
}
|
||||
|
||||
public byte[] willMessageInBytes() {
|
||||
return willMessage;
|
||||
}
|
||||
|
||||
@ -58,7 +85,15 @@ public final class MqttConnectPayload {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link MqttConnectPayload#passwordInBytes()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public String password() {
|
||||
return new String(password, CharsetUtil.UTF_8);
|
||||
}
|
||||
|
||||
public byte[] passwordInBytes() {
|
||||
return password;
|
||||
}
|
||||
|
||||
|
@ -339,21 +339,21 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
||||
int numberOfBytesConsumed = decodedClientId.numberOfBytesConsumed;
|
||||
|
||||
Result<String> decodedWillTopic = null;
|
||||
Result<String> decodedWillMessage = null;
|
||||
Result<byte[]> decodedWillMessage = null;
|
||||
if (mqttConnectVariableHeader.isWillFlag()) {
|
||||
decodedWillTopic = decodeString(buffer, 0, 32767);
|
||||
numberOfBytesConsumed += decodedWillTopic.numberOfBytesConsumed;
|
||||
decodedWillMessage = decodeAsciiString(buffer);
|
||||
decodedWillMessage = decodeByteArray(buffer);
|
||||
numberOfBytesConsumed += decodedWillMessage.numberOfBytesConsumed;
|
||||
}
|
||||
Result<String> decodedUserName = null;
|
||||
Result<String> decodedPassword = null;
|
||||
Result<byte[]> decodedPassword = null;
|
||||
if (mqttConnectVariableHeader.hasUserName()) {
|
||||
decodedUserName = decodeString(buffer);
|
||||
numberOfBytesConsumed += decodedUserName.numberOfBytesConsumed;
|
||||
}
|
||||
if (mqttConnectVariableHeader.hasPassword()) {
|
||||
decodedPassword = decodeString(buffer);
|
||||
decodedPassword = decodeByteArray(buffer);
|
||||
numberOfBytesConsumed += decodedPassword.numberOfBytesConsumed;
|
||||
}
|
||||
|
||||
@ -419,17 +419,6 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
||||
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) {
|
||||
final Result<Integer> decodedSize = decodeMsbLsb(buffer);
|
||||
int size = decodedSize.value;
|
||||
@ -445,6 +434,14 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
||||
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) {
|
||||
return decodeMsbLsb(buffer, 0, 65535);
|
||||
}
|
||||
|
@ -113,8 +113,8 @@ public final class MqttEncoder extends MessageToMessageEncoder<MqttMessage> {
|
||||
// Will topic and message
|
||||
String willTopic = payload.willTopic();
|
||||
byte[] willTopicBytes = willTopic != null ? encodeStringUtf8(willTopic) : EmptyArrays.EMPTY_BYTES;
|
||||
String willMessage = payload.willMessage();
|
||||
byte[] willMessageBytes = willMessage != null ? encodeStringUtf8(willMessage) : EmptyArrays.EMPTY_BYTES;
|
||||
byte[] willMessage = payload.willMessageInBytes();
|
||||
byte[] willMessageBytes = willMessage != null ? willMessage : EmptyArrays.EMPTY_BYTES;
|
||||
if (variableHeader.isWillFlag()) {
|
||||
payloadBufferSize += 2 + willTopicBytes.length;
|
||||
payloadBufferSize += 2 + willMessageBytes.length;
|
||||
@ -126,8 +126,8 @@ public final class MqttEncoder extends MessageToMessageEncoder<MqttMessage> {
|
||||
payloadBufferSize += 2 + userNameBytes.length;
|
||||
}
|
||||
|
||||
String password = payload.password();
|
||||
byte[] passwordBytes = password != null ? encodeStringUtf8(password) : EmptyArrays.EMPTY_BYTES;
|
||||
byte[] password = payload.passwordInBytes();
|
||||
byte[] passwordBytes = password != null ? password : EmptyArrays.EMPTY_BYTES;
|
||||
if (variableHeader.hasPassword()) {
|
||||
payloadBufferSize += 2 + passwordBytes.length;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package io.netty.handler.codec.mqtt;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -77,9 +78,9 @@ public final class MqttMessageBuilders {
|
||||
private boolean willRetain;
|
||||
private MqttQoS willQos = MqttQoS.AT_MOST_ONCE;
|
||||
private String willTopic;
|
||||
private String willMessage;
|
||||
private byte[] willMessage;
|
||||
private String username;
|
||||
private String password;
|
||||
private byte[] password;
|
||||
|
||||
ConnectBuilder() {
|
||||
}
|
||||
@ -119,7 +120,16 @@ public final class MqttMessageBuilders {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ConnectBuilder#willMessage(byte[])} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public ConnectBuilder willMessage(String willMessage) {
|
||||
willMessage(willMessage.getBytes(CharsetUtil.UTF_8));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder willMessage(byte[] willMessage) {
|
||||
this.willMessage = willMessage;
|
||||
return this;
|
||||
}
|
||||
@ -145,7 +155,16 @@ public final class MqttMessageBuilders {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ConnectBuilder#password(byte[])} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public ConnectBuilder password(String password) {
|
||||
password(password.getBytes(CharsetUtil.UTF_8));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectBuilder password(byte[] password) {
|
||||
this.hasPassword = true;
|
||||
this.password = password;
|
||||
return this;
|
||||
|
@ -28,6 +28,7 @@ import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -395,7 +396,13 @@ public class MqttCodecTest {
|
||||
actual.clientIdentifier());
|
||||
assertEquals("MqttConnectPayload UserName mismatch ", expected.userName(), actual.userName());
|
||||
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());
|
||||
assertTrue(
|
||||
"MqttConnectPayload WillMessage bytes mismatch ",
|
||||
Arrays.equals(expected.willMessageInBytes(), actual.willMessageInBytes()));
|
||||
assertEquals("MqttConnectPayload WillTopic mismatch ", expected.willTopic(), actual.willTopic());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user