2626import java .util .HashSet ;
2727import java .util .List ;
2828import java .util .Random ;
29- import java .util .Set ;
30- import java .util .concurrent .CopyOnWriteArraySet ;
29+ import java .util .concurrent .CopyOnWriteArrayList ;
3130import java .util .concurrent .TimeUnit ;
3231
3332import org .apache .commons .logging .Log ;
6665 */
6766public abstract class AbstractSockJsService implements SockJsService {
6867
68+ private static final int MAX_KNOWN_SOCKJS_PREFIX_COUNT = 100 ;
69+
6970 protected final Log logger = LogFactory .getLog (getClass ());
7071
7172 private static final long ONE_YEAR = TimeUnit .DAYS .toSeconds (365 );
@@ -91,7 +92,7 @@ public abstract class AbstractSockJsService implements SockJsService {
9192
9293 private final List <String > validSockJsPrefixes = new ArrayList <String >();
9394
94- private final Set <String > knownSockJsPrefixes = new CopyOnWriteArraySet <String >();
95+ private final List <String > knownSockJsPrefixes = new CopyOnWriteArrayList <String >();
9596
9697
9798 public AbstractSockJsService (TaskScheduler scheduler ) {
@@ -376,7 +377,6 @@ private String getSockJsPath(ServerHttpRequest request) {
376377 for (String prefix : this .validSockJsPrefixes ) {
377378 int index = path .lastIndexOf (prefix );
378379 if (index != -1 ) {
379- this .knownSockJsPrefixes .add (path .substring (0 , index + prefix .length ()));
380380 return path .substring (index + prefix .length ());
381381 }
382382 }
@@ -385,7 +385,7 @@ private String getSockJsPath(ServerHttpRequest request) {
385385
386386 // Try SockJS info request
387387 if (path .endsWith ("/info" )) {
388- this . knownSockJsPrefixes . add (path .substring (0 , path .length () - "/info" .length ()));
388+ addKnownSockJsPrefix (path .substring (0 , path .length () - "/info" .length ()));
389389 return "/info" ;
390390 }
391391
@@ -412,13 +412,23 @@ private String getSockJsPath(ServerHttpRequest request) {
412412 String lastSegment = pathNoSlash .substring (pathNoSlash .lastIndexOf ('/' ) + 1 );
413413
414414 if (!isValidTransportType (lastSegment ) && !lastSegment .startsWith ("iframe" )) {
415- this . knownSockJsPrefixes . add (path );
415+ addKnownSockJsPrefix (path );
416416 return "" ;
417417 }
418418
419419 return null ;
420420 }
421421
422+ private void addKnownSockJsPrefix (String path ) {
423+ if (this .knownSockJsPrefixes .size () > MAX_KNOWN_SOCKJS_PREFIX_COUNT ) {
424+ String removed = this .knownSockJsPrefixes .remove (0 );
425+ if (logger .isWarnEnabled ()) {
426+ logger .warn ("MAX_KNOWN_SOCKJS_PREFIX_COUNT reached, removed prefix " + removed );
427+ }
428+ }
429+ this .knownSockJsPrefixes .add (path );
430+ }
431+
422432 /**
423433 * Validate whether the given transport String extracted from the URL is a valid
424434 * SockJS transport type (regardless of whether a transport handler is configured).
0 commit comments