|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2016 the original author or authors. |
|
|
|
* Copyright 2002-2017 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -120,16 +120,17 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public UserDestinationResult resolveDestination(Message<?> message) { |
|
|
|
public UserDestinationResult resolveDestination(Message<?> message) { |
|
|
|
String sourceDestination = SimpMessageHeaderAccessor.getDestination(message.getHeaders()); |
|
|
|
|
|
|
|
ParseResult parseResult = parse(message); |
|
|
|
ParseResult parseResult = parse(message); |
|
|
|
if (parseResult == null) { |
|
|
|
if (parseResult == null) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
String user = parseResult.getUser(); |
|
|
|
String user = parseResult.getUser(); |
|
|
|
|
|
|
|
String sourceDestination = parseResult.getSourceDestination(); |
|
|
|
Set<String> targetSet = new HashSet<String>(); |
|
|
|
Set<String> targetSet = new HashSet<String>(); |
|
|
|
for (String sessionId : parseResult.getSessionIds()) { |
|
|
|
for (String sessionId : parseResult.getSessionIds()) { |
|
|
|
String actualDestination = parseResult.getActualDestination(); |
|
|
|
String actualDestination = parseResult.getActualDestination(); |
|
|
|
String targetDestination = getTargetDestination(sourceDestination, actualDestination, sessionId, user); |
|
|
|
String targetDestination = getTargetDestination( |
|
|
|
|
|
|
|
sourceDestination, actualDestination, sessionId, user); |
|
|
|
if (targetDestination != null) { |
|
|
|
if (targetDestination != null) { |
|
|
|
targetSet.add(targetDestination); |
|
|
|
targetSet.add(targetDestination); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -140,65 +141,84 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { |
|
|
|
|
|
|
|
|
|
|
|
private ParseResult parse(Message<?> message) { |
|
|
|
private ParseResult parse(Message<?> message) { |
|
|
|
MessageHeaders headers = message.getHeaders(); |
|
|
|
MessageHeaders headers = message.getHeaders(); |
|
|
|
String destination = SimpMessageHeaderAccessor.getDestination(headers); |
|
|
|
String sourceDestination = SimpMessageHeaderAccessor.getDestination(headers); |
|
|
|
if (destination == null || !checkDestination(destination, this.prefix)) { |
|
|
|
if (sourceDestination == null || !checkDestination(sourceDestination, this.prefix)) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); |
|
|
|
SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); |
|
|
|
|
|
|
|
switch (messageType) { |
|
|
|
|
|
|
|
case SUBSCRIBE: |
|
|
|
|
|
|
|
case UNSUBSCRIBE: |
|
|
|
|
|
|
|
return parseSubscriptionMessage(message, sourceDestination); |
|
|
|
|
|
|
|
case MESSAGE: |
|
|
|
|
|
|
|
return parseMessage(headers, sourceDestination); |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ParseResult parseSubscriptionMessage(Message<?> message, String sourceDestination) { |
|
|
|
|
|
|
|
MessageHeaders headers = message.getHeaders(); |
|
|
|
|
|
|
|
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); |
|
|
|
|
|
|
|
if (sessionId == null) { |
|
|
|
|
|
|
|
logger.error("No session id. Ignoring " + message); |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int prefixEnd = this.prefix.length() - 1; |
|
|
|
|
|
|
|
String actualDestination = sourceDestination.substring(prefixEnd); |
|
|
|
|
|
|
|
if (!this.keepLeadingSlash) { |
|
|
|
|
|
|
|
actualDestination = actualDestination.substring(1); |
|
|
|
|
|
|
|
} |
|
|
|
Principal principal = SimpMessageHeaderAccessor.getUser(headers); |
|
|
|
Principal principal = SimpMessageHeaderAccessor.getUser(headers); |
|
|
|
|
|
|
|
String user = (principal != null ? principal.getName() : null); |
|
|
|
|
|
|
|
Set<String> sessionIds = Collections.singleton(sessionId); |
|
|
|
|
|
|
|
return new ParseResult(sourceDestination, actualDestination, sourceDestination, |
|
|
|
|
|
|
|
sessionIds, user); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ParseResult parseMessage(MessageHeaders headers, String sourceDestination) { |
|
|
|
|
|
|
|
int prefixEnd = this.prefix.length(); |
|
|
|
|
|
|
|
int userEnd = sourceDestination.indexOf('/', prefixEnd); |
|
|
|
|
|
|
|
Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\""); |
|
|
|
|
|
|
|
String actualDestination = sourceDestination.substring(userEnd); |
|
|
|
|
|
|
|
String subscribeDestination = this.prefix.substring(0, prefixEnd - 1) + actualDestination; |
|
|
|
|
|
|
|
String userName = sourceDestination.substring(prefixEnd, userEnd); |
|
|
|
|
|
|
|
userName = StringUtils.replace(userName, "%2F", "/"); |
|
|
|
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); |
|
|
|
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); |
|
|
|
if (SimpMessageType.SUBSCRIBE.equals(messageType) || SimpMessageType.UNSUBSCRIBE.equals(messageType)) { |
|
|
|
Set<String> sessionIds; |
|
|
|
if (sessionId == null) { |
|
|
|
if (userName.equals(sessionId)) { |
|
|
|
logger.error("No session id. Ignoring " + message); |
|
|
|
userName = null; |
|
|
|
return null; |
|
|
|
sessionIds = Collections.singleton(sessionId); |
|
|
|
} |
|
|
|
} |
|
|
|
int prefixEnd = this.prefix.length() - 1; |
|
|
|
else { |
|
|
|
String actualDestination = destination.substring(prefixEnd); |
|
|
|
sessionIds = getSessionIdsByUser(userName, sessionId); |
|
|
|
if (!this.keepLeadingSlash) { |
|
|
|
} |
|
|
|
actualDestination = actualDestination.substring(1); |
|
|
|
if (!this.keepLeadingSlash) { |
|
|
|
} |
|
|
|
actualDestination = actualDestination.substring(1); |
|
|
|
String user = (principal != null ? principal.getName() : null); |
|
|
|
|
|
|
|
return new ParseResult(actualDestination, destination, Collections.singleton(sessionId), user); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else if (SimpMessageType.MESSAGE.equals(messageType)) { |
|
|
|
return new ParseResult(sourceDestination, actualDestination, subscribeDestination, |
|
|
|
int prefixEnd = this.prefix.length(); |
|
|
|
sessionIds, userName); |
|
|
|
int userEnd = destination.indexOf('/', prefixEnd); |
|
|
|
} |
|
|
|
Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\""); |
|
|
|
|
|
|
|
String actualDestination = destination.substring(userEnd); |
|
|
|
private Set<String> getSessionIdsByUser(String userName, String sessionId) { |
|
|
|
String subscribeDestination = this.prefix.substring(0, prefixEnd - 1) + actualDestination; |
|
|
|
Set<String> sessionIds; |
|
|
|
String userName = destination.substring(prefixEnd, userEnd); |
|
|
|
SimpUser user = this.userRegistry.getUser(userName); |
|
|
|
userName = StringUtils.replace(userName, "%2F", "/"); |
|
|
|
if (user != null) { |
|
|
|
Set<String> sessionIds; |
|
|
|
if (user.getSession(sessionId) != null) { |
|
|
|
if (userName.equals(sessionId)) { |
|
|
|
|
|
|
|
userName = null; |
|
|
|
|
|
|
|
sessionIds = Collections.singleton(sessionId); |
|
|
|
sessionIds = Collections.singleton(sessionId); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
SimpUser user = this.userRegistry.getUser(userName); |
|
|
|
Set<SimpSession> sessions = user.getSessions(); |
|
|
|
if (user != null) { |
|
|
|
sessionIds = new HashSet<String>(sessions.size()); |
|
|
|
if (user.getSession(sessionId) != null) { |
|
|
|
for (SimpSession session : sessions) { |
|
|
|
sessionIds = Collections.singleton(sessionId); |
|
|
|
sessionIds.add(session.getId()); |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
Set<SimpSession> sessions = user.getSessions(); |
|
|
|
|
|
|
|
sessionIds = new HashSet<String>(sessions.size()); |
|
|
|
|
|
|
|
for (SimpSession session : sessions) { |
|
|
|
|
|
|
|
sessionIds.add(session.getId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
sessionIds = Collections.<String>emptySet(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!this.keepLeadingSlash) { |
|
|
|
|
|
|
|
actualDestination = actualDestination.substring(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return new ParseResult(actualDestination, subscribeDestination, sessionIds, userName); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
return null; |
|
|
|
sessionIds = Collections.emptySet(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return sessionIds; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected boolean checkDestination(String destination, String requiredPrefix) { |
|
|
|
protected boolean checkDestination(String destination, String requiredPrefix) { |
|
|
|
@ -232,6 +252,8 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private static class ParseResult { |
|
|
|
private static class ParseResult { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final String sourceDestination; |
|
|
|
|
|
|
|
|
|
|
|
private final String actualDestination; |
|
|
|
private final String actualDestination; |
|
|
|
|
|
|
|
|
|
|
|
private final String subscribeDestination; |
|
|
|
private final String subscribeDestination; |
|
|
|
@ -241,7 +263,10 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { |
|
|
|
private final String user; |
|
|
|
private final String user; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public ParseResult(String actualDest, String subscribeDest, Set<String> sessionIds, String user) { |
|
|
|
public ParseResult(String sourceDest, String actualDest, String subscribeDest, |
|
|
|
|
|
|
|
Set<String> sessionIds, String user) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.sourceDestination = sourceDest; |
|
|
|
this.actualDestination = actualDest; |
|
|
|
this.actualDestination = actualDest; |
|
|
|
this.subscribeDestination = subscribeDest; |
|
|
|
this.subscribeDestination = subscribeDest; |
|
|
|
this.sessionIds = sessionIds; |
|
|
|
this.sessionIds = sessionIds; |
|
|
|
@ -249,6 +274,10 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getSourceDestination() { |
|
|
|
|
|
|
|
return this.sourceDestination; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String getActualDestination() { |
|
|
|
public String getActualDestination() { |
|
|
|
return this.actualDestination; |
|
|
|
return this.actualDestination; |
|
|
|
} |
|
|
|
} |
|
|
|
|