From 02cb86659d13d41c1f7d9b7e8866284f26616a02 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 30 Sep 2013 21:46:19 -0400 Subject: [PATCH] Prevent cache of sockjs known prefixes from growing Issue: SPR-10893 --- .../sockjs/support/AbstractSockJsService.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java index 47e3ba97d5..038c5e9655 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java @@ -26,8 +26,7 @@ import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Random; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; @@ -66,6 +65,8 @@ import org.springframework.web.socket.sockjs.SockJsService; */ public abstract class AbstractSockJsService implements SockJsService { + private static final int MAX_KNOWN_SOCKJS_PREFIX_COUNT = 100; + protected final Log logger = LogFactory.getLog(getClass()); private static final long ONE_YEAR = TimeUnit.DAYS.toSeconds(365); @@ -91,7 +92,7 @@ public abstract class AbstractSockJsService implements SockJsService { private final List validSockJsPrefixes = new ArrayList(); - private final Set knownSockJsPrefixes = new CopyOnWriteArraySet(); + private final List knownSockJsPrefixes = new CopyOnWriteArrayList(); public AbstractSockJsService(TaskScheduler scheduler) { @@ -376,7 +377,6 @@ public abstract class AbstractSockJsService implements SockJsService { for (String prefix : this.validSockJsPrefixes) { int index = path.lastIndexOf(prefix); if (index != -1) { - this.knownSockJsPrefixes.add(path.substring(0, index + prefix.length())); return path.substring(index + prefix.length()); } } @@ -385,7 +385,7 @@ public abstract class AbstractSockJsService implements SockJsService { // Try SockJS info request if (path.endsWith("/info")) { - this.knownSockJsPrefixes.add(path.substring(0, path.length() - "/info".length())); + addKnownSockJsPrefix(path.substring(0, path.length() - "/info".length())); return "/info"; } @@ -412,13 +412,23 @@ public abstract class AbstractSockJsService implements SockJsService { String lastSegment = pathNoSlash.substring(pathNoSlash.lastIndexOf('/') + 1); if (!isValidTransportType(lastSegment) && !lastSegment.startsWith("iframe")) { - this.knownSockJsPrefixes.add(path); + addKnownSockJsPrefix(path); return ""; } return null; } + private void addKnownSockJsPrefix(String path) { + if (this.knownSockJsPrefixes.size() > MAX_KNOWN_SOCKJS_PREFIX_COUNT) { + String removed = this.knownSockJsPrefixes.remove(0); + if (logger.isWarnEnabled()) { + logger.warn("MAX_KNOWN_SOCKJS_PREFIX_COUNT reached, removed prefix " + removed); + } + } + this.knownSockJsPrefixes.add(path); + } + /** * Validate whether the given transport String extracted from the URL is a valid * SockJS transport type (regardless of whether a transport handler is configured).