Skip to content

Commit b3c7c18

Browse files
committed
Add MessageHandler destination prefix checks
1 parent 2cdac26 commit b3c7c18

File tree

5 files changed

+94
-42
lines changed

5 files changed

+94
-42
lines changed

spring-messaging/src/main/java/org/springframework/messaging/simp/handler/AnnotationMethodMessageHandler.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.messaging.handler.annotation.ReplyTo;
4343
import org.springframework.messaging.handler.annotation.support.ExceptionHandlerMethodResolver;
4444
import org.springframework.messaging.handler.annotation.support.MessageBodyMethodArgumentResolver;
45+
import org.springframework.messaging.handler.annotation.support.MessageMethodArgumentResolver;
4546
import org.springframework.messaging.handler.method.HandlerMethod;
4647
import org.springframework.messaging.handler.method.HandlerMethodArgumentResolverComposite;
4748
import org.springframework.messaging.handler.method.HandlerMethodReturnValueHandlerComposite;
@@ -75,6 +76,8 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
7576

7677
private final SimpMessageSendingOperations webSocketSessionMessagingTemplate;
7778

79+
private List<String> destinationPrefixes;
80+
7881
private MessageConverter<?> messageConverter;
7982

8083
private ApplicationContext applicationContext;
@@ -110,16 +113,26 @@ public AnnotationMethodMessageHandler(SimpMessageSendingOperations dispatchMessa
110113
this.webSocketSessionMessagingTemplate = new SimpMessagingTemplate(webSocketSessionChannel);
111114
}
112115

113-
/**
114-
* TODO: multiple converters with 'content-type' header
115-
*/
116+
117+
public void setDestinationPrefixes(List<String> destinationPrefixes) {
118+
this.destinationPrefixes = destinationPrefixes;
119+
}
120+
121+
public List<String> getDestinationPrefixes() {
122+
return this.destinationPrefixes;
123+
}
124+
116125
public void setMessageConverter(MessageConverter<?> converter) {
117126
this.messageConverter = converter;
118127
if (converter != null) {
119128
((AbstractMessageSendingTemplate<?>) this.webSocketSessionMessagingTemplate).setMessageConverter(converter);
120129
}
121130
}
122131

132+
public MessageConverter<?> getMessageConverter() {
133+
return this.messageConverter;
134+
}
135+
123136
@Override
124137
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
125138
this.applicationContext = applicationContext;
@@ -131,6 +144,7 @@ public void afterPropertiesSet() {
131144
initHandlerMethods();
132145

133146
this.argumentResolvers.addResolver(new PrincipalMethodArgumentResolver());
147+
this.argumentResolvers.addResolver(new MessageMethodArgumentResolver());
134148
this.argumentResolvers.addResolver(new MessageBodyMethodArgumentResolver(this.messageConverter));
135149

136150
this.returnValueHandlers.addHandler(new ReplyToMethodReturnValueHandler(this.dispatchMessagingTemplate));
@@ -147,8 +161,7 @@ protected void initHandlerMethods() {
147161
}
148162

149163
protected boolean isHandler(Class<?> beanType) {
150-
return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) ||
151-
(AnnotationUtils.findAnnotation(beanType, MessageMapping.class) != null));
164+
return (AnnotationUtils.findAnnotation(beanType, Controller.class) != null);
152165
}
153166

154167
protected void detectHandlerMethods(Object handler) {
@@ -220,11 +233,19 @@ private void handleMessageInternal(final Message<?> message, Map<MappingInfo, Ha
220233
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
221234
String destination = headers.getDestination();
222235

236+
if (!checkDestinationPrefix(destination)) {
237+
return;
238+
}
239+
223240
HandlerMethod match = getHandlerMethod(destination, handlerMethods);
224241
if (match == null) {
225242
return;
226243
}
227244

245+
if (logger.isTraceEnabled()) {
246+
logger.trace("Processing message: " + message);
247+
}
248+
228249
HandlerMethod handlerMethod = match.createWithResolvedBean();
229250

230251
InvocableHandlerMethod invocableHandlerMethod = new InvocableHandlerMethod(handlerMethod);
@@ -248,6 +269,17 @@ private void handleMessageInternal(final Message<?> message, Map<MappingInfo, Ha
248269
}
249270
}
250271

272+
private boolean checkDestinationPrefix(String destination) {
273+
if ((destination != null) && (this.destinationPrefixes != null)) {
274+
for (String prefix : this.destinationPrefixes) {
275+
if (destination.startsWith(prefix)) {
276+
return true;
277+
}
278+
}
279+
}
280+
return false;
281+
}
282+
251283
private void invokeExceptionHandler(Message<?> message, HandlerMethod handlerMethod, Exception ex) {
252284

253285
InvocableHandlerMethod exceptionHandlerMethod;

spring-messaging/src/main/java/org/springframework/messaging/simp/handler/SimpleBrokerMessageHandler.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.messaging.simp.handler;
1818

19+
import java.util.List;
20+
1921
import org.apache.commons.logging.Log;
2022
import org.apache.commons.logging.LogFactory;
2123
import org.springframework.messaging.Message;
@@ -39,6 +41,8 @@ public class SimpleBrokerMessageHandler implements MessageHandler {
3941

4042
private final MessageChannel messageChannel;
4143

44+
private List<String> destinationPrefixes;
45+
4246
private SubscriptionRegistry subscriptionRegistry = new DefaultSubscriptionRegistry();
4347

4448

@@ -51,6 +55,14 @@ public SimpleBrokerMessageHandler(MessageChannel messageChannel) {
5155
}
5256

5357

58+
public void setDestinationPrefixes(List<String> destinationPrefixes) {
59+
this.destinationPrefixes = destinationPrefixes;
60+
}
61+
62+
public List<String> getDestinationPrefixes() {
63+
return this.destinationPrefixes;
64+
}
65+
5466
public void setSubscriptionRegistry(SubscriptionRegistry subscriptionRegistry) {
5567
Assert.notNull(subscriptionRegistry, "subscriptionRegistry is required");
5668
this.subscriptionRegistry = subscriptionRegistry;
@@ -65,6 +77,11 @@ public void handleMessage(Message<?> message) throws MessagingException {
6577

6678
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
6779
SimpMessageType messageType = headers.getMessageType();
80+
String destination = headers.getDestination();
81+
82+
if (!checkDestinationPrefix(destination)) {
83+
return;
84+
}
6885

6986
if (SimpMessageType.SUBSCRIBE.equals(messageType)) {
7087
preProcessMessage(message);
@@ -85,6 +102,17 @@ else if (SimpMessageType.DISCONNECT.equals(messageType)) {
85102
}
86103
}
87104

105+
private boolean checkDestinationPrefix(String destination) {
106+
if ((destination != null) && (this.destinationPrefixes != null)) {
107+
for (String prefix : this.destinationPrefixes) {
108+
if (destination.startsWith(prefix)) {
109+
return true;
110+
}
111+
}
112+
}
113+
return false;
114+
}
115+
88116
private void preProcessMessage(Message<?> message) {
89117
if (logger.isTraceEnabled()) {
90118
logger.trace("Processing " + message);

spring-messaging/src/main/java/org/springframework/messaging/simp/handler/UserDestinationMessageHandler.java

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.springframework.messaging.simp.SimpMessageType;
2727
import org.springframework.messaging.support.MessageBuilder;
2828
import org.springframework.util.Assert;
29-
import org.springframework.util.StringUtils;
3029

3130

3231
/**
@@ -48,7 +47,7 @@ public class UserDestinationMessageHandler implements MessageHandler {
4847

4948
private final MessageSendingOperations<String> messagingTemplate;
5049

51-
private String prefix = "/user/";
50+
private String destinationPrefix = "/user/";
5251

5352
private UserQueueSuffixResolver userQueueSuffixResolver = new SimpleUserQueueSuffixResolver();
5453

@@ -72,16 +71,16 @@ public UserDestinationMessageHandler(MessageSendingOperations<String> messagingT
7271
* <p>The default prefix is "/user".
7372
* @param prefix the prefix to set
7473
*/
75-
public void setPrefix(String prefix) {
74+
public void setDestinationPrefix(String prefix) {
7675
Assert.hasText(prefix, "prefix is required");
77-
this.prefix = prefix.endsWith("/") ? prefix : prefix + "/";
76+
this.destinationPrefix = prefix.endsWith("/") ? prefix : prefix + "/";
7877
}
7978

8079
/**
8180
* @return the prefix
8281
*/
83-
public String getPrefix() {
84-
return this.prefix;
82+
public String getDestinationPrefix() {
83+
return this.destinationPrefix;
8584
}
8685

8786
/**
@@ -101,12 +100,17 @@ public MessageSendingOperations<String> getMessagingTemplate() {
101100
@Override
102101
public void handleMessage(Message<?> message) throws MessagingException {
103102

104-
if (!shouldHandle(message)) {
103+
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
104+
SimpMessageType messageType = headers.getMessageType();
105+
String destination = headers.getDestination();
106+
107+
if (!SimpMessageType.MESSAGE.equals(messageType)) {
105108
return;
106109
}
107110

108-
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
109-
String destination = headers.getDestination();
111+
if (!checkDestination(destination)) {
112+
return;
113+
}
110114

111115
if (logger.isTraceEnabled()) {
112116
logger.trace("Processing message to destination " + destination);
@@ -117,7 +121,7 @@ public void handleMessage(Message<?> message) throws MessagingException {
117121

118122
if (user == null) {
119123
if (logger.isErrorEnabled()) {
120-
logger.error("Ignoring message, expected destination \"" + this.prefix
124+
logger.error("Ignoring message, expected destination pattern \"" + this.destinationPrefix
121125
+ "{userId}/**\": " + destination);
122126
}
123127
return;
@@ -136,27 +140,13 @@ public void handleMessage(Message<?> message) throws MessagingException {
136140
}
137141
}
138142

139-
protected boolean shouldHandle(Message<?> message) {
140-
141-
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
142-
SimpMessageType messageType = headers.getMessageType();
143-
String destination = headers.getDestination();
144-
145-
if (!SimpMessageType.MESSAGE.equals(messageType)) {
146-
return false;
147-
}
148-
149-
if (!StringUtils.hasText(destination)) {
150-
if (logger.isErrorEnabled()) {
151-
logger.error("Ignoring message, no destination: " + headers);
143+
private boolean checkDestination(String destination) {
144+
if (destination != null) {
145+
if (destination.startsWith(this.destinationPrefix)) {
146+
return true;
152147
}
153-
return false;
154148
}
155-
else if (!destination.startsWith(this.prefix)) {
156-
return false;
157-
}
158-
159-
return true;
149+
return false;
160150
}
161151

162152

@@ -169,7 +159,7 @@ private class UserDestinationParser {
169159

170160
public UserDestinationParser(String destination) {
171161

172-
int userStartIndex = prefix.length();
162+
int userStartIndex = destinationPrefix.length();
173163
int userEndIndex = destination.indexOf('/', userStartIndex);
174164

175165
if (userEndIndex > 0) {

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,9 @@ public void handleMessage(Message<?> message) {
285285
logger.error("Ignoring message, no sessionId: " + message);
286286
return;
287287
}
288-
if (command.requiresDestination() && (destination == null)) {
289-
logger.error("Ignoring " + command + " message, no destination: " + message);
290-
return;
291-
}
292288

293289
try {
294-
if ((destination == null) || supportsDestination(destination)) {
290+
if (checkDestinationPrefix(command, destination)) {
295291

296292
if (logger.isTraceEnabled()) {
297293
logger.trace("Processing message: " + message);
@@ -329,7 +325,13 @@ else if (SimpMessageType.DISCONNECT.equals(messageType)) {
329325
}
330326
}
331327

332-
protected boolean supportsDestination(String destination) {
328+
protected boolean checkDestinationPrefix(StompCommand command, String destination) {
329+
if (!command.requiresDestination()) {
330+
return true;
331+
}
332+
else if (destination == null) {
333+
return false;
334+
}
333335
for (String prefix : this.destinationPrefixes) {
334336
if (destination.startsWith(prefix)) {
335337
return true;

spring-messaging/src/main/java/org/springframework/messaging/support/converter/MappingJackson2MessageConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ else if (payload instanceof String) {
8383
}
8484
}
8585
catch (IOException ex) {
86-
throw new MessageConversionException("Could not read JSON: " + ex.getMessage(), ex);
86+
throw new MessageConversionException(message, "Could not read JSON: " + ex.getMessage(), ex);
8787
}
8888
}
8989

0 commit comments

Comments
 (0)