Skip to content

Commit 6802f81

Browse files
committed
Polish STOMP codec
Issue: SPR-11088
1 parent e84885c commit 6802f81

File tree

2 files changed

+30
-27
lines changed

2 files changed

+30
-27
lines changed

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompCodec.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ public Message<byte[]> apply(Buffer buffer) {
5353
Message<byte[]> message = DECODER.decode(buffer.byteBuffer());
5454
if (message != null) {
5555
next.accept(message);
56-
} else {
56+
}
57+
else {
5758
break;
5859
}
5960
}

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java

+28-26
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@
2929
import org.springframework.util.MultiValueMap;
3030

3131
/**
32-
* A decoder for STOMP frames.
32+
* Decodes STOMP frames from a {@link ByteBuffer}. If the buffer does not contain
33+
* enough data to form a complete STOMP frame, the buffer is reset and the value
34+
* returned is {@code null} indicating that no message could be read.
3335
*
3436
* @author Andy Wilkinson
37+
* @author Rossen Stoyanchev
3538
* @since 4.0
3639
*/
3740
public class StompDecoder {
@@ -45,15 +48,18 @@ public class StompDecoder {
4548

4649
/**
4750
* Decodes a STOMP frame in the given {@code buffer} into a {@link Message}.
51+
* If the given ByteBuffer contains partial STOMP frame content, the method
52+
* resets the buffer and returns {@code null}.
4853
*
4954
* @param buffer The buffer to decode the frame from
50-
* @return The decoded message
55+
*
56+
* @return The decoded message or {@code null}
5157
*/
5258
public Message<byte[]> decode(ByteBuffer buffer) {
53-
skipLeadingEol(buffer);
5459

5560
Message<byte[]> decodedMessage = null;
5661

62+
skipLeadingEol(buffer);
5763
buffer.mark();
5864

5965
String command = readCommand(buffer);
@@ -65,34 +71,38 @@ public Message<byte[]> decode(ByteBuffer buffer) {
6571
if (payload != null) {
6672
StompCommand stompCommand = StompCommand.valueOf(command);
6773
if ((payload.length > 0) && (!stompCommand.isBodyAllowed())) {
68-
throw new StompConversionException(stompCommand +
69-
" isn't allowed to have a body but has payload length=" + payload.length +
70-
", headers=" + headers);
74+
throw new StompConversionException(stompCommand + " shouldn't have but " +
75+
"has a payload with length=" + payload.length + ", headers=" + headers);
7176
}
72-
7377
decodedMessage = MessageBuilder.withPayload(payload)
7478
.setHeaders(StompHeaderAccessor.create(stompCommand, headers)).build();
75-
7679
if (logger.isDebugEnabled()) {
7780
logger.debug("Decoded " + decodedMessage);
7881
}
79-
} else {
80-
if (logger.isDebugEnabled()) {
81-
logger.debug("Received incomplete frame. Resetting buffer");
82+
}
83+
else {
84+
if (logger.isTraceEnabled()) {
85+
logger.trace("Received incomplete frame. Resetting buffer");
8286
}
8387
buffer.reset();
8488
}
8589
}
8690
else {
87-
decodedMessage = MessageBuilder.withPayload(HEARTBEAT_PAYLOAD).setHeaders(
88-
StompHeaderAccessor.create(SimpMessageType.HEARTBEAT)).build();
8991
if (logger.isTraceEnabled()) {
9092
logger.trace("Decoded heartbeat");
9193
}
94+
decodedMessage = MessageBuilder.withPayload(HEARTBEAT_PAYLOAD).setHeaders(
95+
StompHeaderAccessor.create(SimpMessageType.HEARTBEAT)).build();
9296
}
93-
9497
return decodedMessage;
98+
}
9599

100+
private void skipLeadingEol(ByteBuffer buffer) {
101+
while (true) {
102+
if (!isEol(buffer)) {
103+
break;
104+
}
105+
}
96106
}
97107

98108
private String readCommand(ByteBuffer buffer) {
@@ -143,17 +153,17 @@ private byte[] readPayload(ByteBuffer buffer, MultiValueMap<String, String> head
143153
String contentLengthString = headers.getFirst("content-length");
144154
if (contentLengthString != null) {
145155
int contentLength = Integer.valueOf(contentLengthString);
146-
byte[] payload = new byte[contentLength];
147156
if (buffer.remaining() > contentLength) {
157+
byte[] payload = new byte[contentLength];
148158
buffer.get(payload);
149159
if (buffer.get() != 0) {
150160
throw new StompConversionException("Frame must be terminated with a null octet");
151161
}
152-
} else {
162+
return payload;
163+
}
164+
else {
153165
return null;
154166
}
155-
156-
return payload;
157167
}
158168
else {
159169
ByteArrayOutputStream payload = new ByteArrayOutputStream();
@@ -170,14 +180,6 @@ private byte[] readPayload(ByteBuffer buffer, MultiValueMap<String, String> head
170180
return null;
171181
}
172182

173-
private void skipLeadingEol(ByteBuffer buffer) {
174-
while (true) {
175-
if (!isEol(buffer)) {
176-
break;
177-
}
178-
}
179-
}
180-
181183
private boolean isEol(ByteBuffer buffer) {
182184
if (buffer.remaining() > 0) {
183185
byte b = buffer.get();

0 commit comments

Comments
 (0)