Validate if STOMP frame is allowed to have a body
Issue: SPR-10890
This commit is contained in:
parent
7c3749769a
commit
57d127b55a
|
@ -17,10 +17,9 @@
|
||||||
package org.springframework.messaging.simp.stomp;
|
package org.springframework.messaging.simp.stomp;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.messaging.simp.SimpMessageType;
|
import org.springframework.messaging.simp.SimpMessageType;
|
||||||
|
|
||||||
|
@ -51,36 +50,38 @@ public enum StompCommand {
|
||||||
RECEIPT,
|
RECEIPT,
|
||||||
ERROR;
|
ERROR;
|
||||||
|
|
||||||
|
private static Map<StompCommand, SimpMessageType> messageTypes = new HashMap<StompCommand, SimpMessageType>();
|
||||||
|
|
||||||
private static Map<StompCommand, SimpMessageType> messageTypeLookup = new HashMap<StompCommand, SimpMessageType>();
|
private static Collection<StompCommand> destinationRequired = Arrays.asList(SEND, SUBSCRIBE, MESSAGE);
|
||||||
|
private static Collection<StompCommand> subscriptionIdRequired = Arrays.asList(SUBSCRIBE, UNSUBSCRIBE, MESSAGE);
|
||||||
private static Set<StompCommand> destinationRequiredLookup =
|
private static Collection<StompCommand> bodyAllowed = Arrays.asList(SEND, MESSAGE, ERROR);
|
||||||
new HashSet<StompCommand>(Arrays.asList(SEND, SUBSCRIBE, MESSAGE));
|
|
||||||
|
|
||||||
private static Set<StompCommand> subscriptionIdRequiredLookup =
|
|
||||||
new HashSet<StompCommand>(Arrays.asList(SUBSCRIBE, UNSUBSCRIBE, MESSAGE));
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
messageTypeLookup.put(StompCommand.CONNECT, SimpMessageType.CONNECT);
|
messageTypes.put(StompCommand.CONNECT, SimpMessageType.CONNECT);
|
||||||
messageTypeLookup.put(StompCommand.STOMP, SimpMessageType.CONNECT);
|
messageTypes.put(StompCommand.STOMP, SimpMessageType.CONNECT);
|
||||||
messageTypeLookup.put(StompCommand.SEND, SimpMessageType.MESSAGE);
|
messageTypes.put(StompCommand.SEND, SimpMessageType.MESSAGE);
|
||||||
messageTypeLookup.put(StompCommand.MESSAGE, SimpMessageType.MESSAGE);
|
messageTypes.put(StompCommand.MESSAGE, SimpMessageType.MESSAGE);
|
||||||
messageTypeLookup.put(StompCommand.SUBSCRIBE, SimpMessageType.SUBSCRIBE);
|
messageTypes.put(StompCommand.SUBSCRIBE, SimpMessageType.SUBSCRIBE);
|
||||||
messageTypeLookup.put(StompCommand.UNSUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
|
messageTypes.put(StompCommand.UNSUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
|
||||||
messageTypeLookup.put(StompCommand.DISCONNECT, SimpMessageType.DISCONNECT);
|
messageTypes.put(StompCommand.DISCONNECT, SimpMessageType.DISCONNECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpMessageType getMessageType() {
|
public SimpMessageType getMessageType() {
|
||||||
SimpMessageType type = messageTypeLookup.get(this);
|
SimpMessageType type = messageTypes.get(this);
|
||||||
return (type != null) ? type : SimpMessageType.OTHER;
|
return (type != null) ? type : SimpMessageType.OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requiresDestination() {
|
public boolean requiresDestination() {
|
||||||
return destinationRequiredLookup.contains(this);
|
return destinationRequired.contains(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requiresSubscriptionId() {
|
public boolean requiresSubscriptionId() {
|
||||||
return subscriptionIdRequiredLookup.contains(this);
|
return subscriptionIdRequired.contains(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBodyAllowed() {
|
||||||
|
return bodyAllowed.contains(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,9 @@ import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decoder for STOMP frames
|
* A decoder for STOMP frames.
|
||||||
*
|
*
|
||||||
* @author awilkinson
|
* @author Andy Wilkinson
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class StompDecoder {
|
public class StompDecoder {
|
||||||
|
@ -60,8 +60,15 @@ public class StompDecoder {
|
||||||
MultiValueMap<String, String> headers = readHeaders(buffer);
|
MultiValueMap<String, String> headers = readHeaders(buffer);
|
||||||
byte[] payload = readPayload(buffer, headers);
|
byte[] payload = readPayload(buffer, headers);
|
||||||
|
|
||||||
decodedMessage = MessageBuilder.withPayload(payload).setHeaders(
|
StompCommand stompCommand = StompCommand.valueOf(command);
|
||||||
StompHeaderAccessor.create(StompCommand.valueOf(command), headers)).build();
|
if ((payload.length > 0) && (!stompCommand.isBodyAllowed())) {
|
||||||
|
throw new StompConversionException(stompCommand +
|
||||||
|
" isn't allowed to have a body but has payload length=" + payload.length +
|
||||||
|
", headers=" + headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedMessage = MessageBuilder.withPayload(payload)
|
||||||
|
.setHeaders(StompHeaderAccessor.create(stompCommand, headers)).build();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decodedMessage = MessageBuilder.withPayload(HEARTBEAT_PAYLOAD).setHeaders(
|
decodedMessage = MessageBuilder.withPayload(HEARTBEAT_PAYLOAD).setHeaders(
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.springframework.messaging.Message;
|
||||||
import org.springframework.messaging.simp.SimpMessageType;
|
import org.springframework.messaging.simp.SimpMessageType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An encoder for STOMP frames
|
* An encoder for STOMP frames.
|
||||||
*
|
*
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
|
|
|
@ -20,12 +20,15 @@ import org.springframework.messaging.Message;
|
||||||
import org.springframework.messaging.MessagingException;
|
import org.springframework.messaging.MessagingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* An exception raised by {@link MessageConverter} implementations.
|
||||||
|
*
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class MessageConversionException extends MessagingException {
|
public class MessageConversionException extends MessagingException {
|
||||||
|
|
||||||
|
|
||||||
public MessageConversionException(String description, Throwable cause) {
|
public MessageConversionException(String description, Throwable cause) {
|
||||||
super(description, cause);
|
super(description, cause);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,11 @@ public class StompCodecTests {
|
||||||
assertEquals("alpha:bravo\r\n\\", headers.getFirstNativeHeader("a:\r\n\\b"));
|
assertEquals("alpha:bravo\r\n\\", headers.getFirstNativeHeader("a:\r\n\\b"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected=StompConversionException.class)
|
||||||
|
public void decodeFrameBodyNotAllowed() {
|
||||||
|
decode("CONNECT\naccept-version:1.2\n\nThe body of the message\0");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void decodeMultipleFramesFromSameBuffer() {
|
public void decodeMultipleFramesFromSameBuffer() {
|
||||||
String frame1 = "SEND\ndestination:test\n\nThe body of the message\0";
|
String frame1 = "SEND\ndestination:test\n\nThe body of the message\0";
|
||||||
|
|
Loading…
Reference in New Issue