Optimize DefaultUserDestinationResolver.resolveDestination()
Issue: SPR-15602
This commit is contained in:
committed by
Rossen Stoyanchev
parent
04a96ffa27
commit
6aeb8ef56d
@@ -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);
|
||||||
Principal principal = SimpMessageHeaderAccessor.getUser(headers);
|
switch (messageType) {
|
||||||
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
|
case SUBSCRIBE:
|
||||||
if (SimpMessageType.SUBSCRIBE.equals(messageType) || SimpMessageType.UNSUBSCRIBE.equals(messageType)) {
|
case UNSUBSCRIBE:
|
||||||
if (sessionId == null) {
|
return parseSubscriptionMessage(message, sourceDestination);
|
||||||
logger.error("No session id. Ignoring " + message);
|
case MESSAGE:
|
||||||
|
return parseMessage(headers, sourceDestination);
|
||||||
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
int prefixEnd = this.prefix.length() - 1;
|
|
||||||
String actualDestination = destination.substring(prefixEnd);
|
|
||||||
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)) {
|
}
|
||||||
int prefixEnd = this.prefix.length();
|
|
||||||
int userEnd = destination.indexOf('/', prefixEnd);
|
private ParseResult parseSubscriptionMessage(Message<?> message, String sourceDestination) {
|
||||||
Assert.isTrue(userEnd > 0, "Expected destination pattern \"/user/{userId}/**\"");
|
MessageHeaders headers = message.getHeaders();
|
||||||
String actualDestination = destination.substring(userEnd);
|
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
|
||||||
String subscribeDestination = this.prefix.substring(0, prefixEnd - 1) + actualDestination;
|
if (sessionId == null) {
|
||||||
String userName = destination.substring(prefixEnd, userEnd);
|
logger.error("No session id. Ignoring " + message);
|
||||||
userName = StringUtils.replace(userName, "%2F", "/");
|
return null;
|
||||||
Set<String> sessionIds;
|
}
|
||||||
if (userName.equals(sessionId)) {
|
int prefixEnd = this.prefix.length() - 1;
|
||||||
userName = null;
|
String actualDestination = sourceDestination.substring(prefixEnd);
|
||||||
|
if (!this.keepLeadingSlash) {
|
||||||
|
actualDestination = actualDestination.substring(1);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
Set<String> sessionIds;
|
||||||
|
if (userName.equals(sessionId)) {
|
||||||
|
userName = null;
|
||||||
|
sessionIds = Collections.singleton(sessionId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sessionIds = getSessionIdsByUser(userName, sessionId);
|
||||||
|
}
|
||||||
|
if (!this.keepLeadingSlash) {
|
||||||
|
actualDestination = actualDestination.substring(1);
|
||||||
|
}
|
||||||
|
return new ParseResult(sourceDestination, actualDestination, subscribeDestination,
|
||||||
|
sessionIds, userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getSessionIdsByUser(String userName, String sessionId) {
|
||||||
|
Set<String> sessionIds;
|
||||||
|
SimpUser user = this.userRegistry.getUser(userName);
|
||||||
|
if (user != null) {
|
||||||
|
if (user.getSession(sessionId) != 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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user