1818
1919import  java .io .IOException ;
2020import  java .nio .charset .Charset ;
21- import  java .util .ArrayList ;
2221import  java .util .Arrays ;
23- import  java .util .Collections ;
24- import  java .util .Comparator ;
2522import  java .util .Date ;
2623import  java .util .HashSet ;
2724import  java .util .List ;
2825import  java .util .Random ;
29- import  java .util .concurrent .CopyOnWriteArrayList ;
3026import  java .util .concurrent .TimeUnit ;
3127
3228import  org .apache .commons .logging .Log ;
5147 * An abstract base class for {@link SockJsService} implementations that provides SockJS 
5248 * path resolution and handling of static SockJS requests (e.g. "/info", "/iframe.html", 
5349 * etc). Sub-classes must handle session URLs (i.e. transport-specific requests). 
54-  * <p> 
55-  * This service is unaware of the underlying HTTP request processing mechanism and URL 
56-  * mappings but nevertheless needs to know the "SockJS path" for a given request, i.e. the 
57-  * portion of the URL path that follows the SockJS prefix. In most cases, this can be 
58-  * auto-detected since the <a href="https://github.com/sockjs/sockjs-client">SockJS 
59-  * client</a> sends a "greeting URL" first. However it is recommended to configure 
60-  * explicitly the expected SockJS prefixes via {@link #setValidSockJsPrefixes(String...)} 
61-  * to eliminate any potential issues. 
6250 * 
6351 * @author Rossen Stoyanchev 
6452 * @since 4.0 
@@ -90,10 +78,6 @@ public abstract class AbstractSockJsService implements SockJsService {
9078
9179	private  final  TaskScheduler  taskScheduler ;
9280
93- 	private  final  List <String > validSockJsPrefixes  = new  ArrayList <String >();
94- 
95- 	private  final  List <String > knownSockJsPrefixes  = new  CopyOnWriteArrayList <String >();
96- 
9781
9882	public  AbstractSockJsService (TaskScheduler  scheduler ) {
9983		Assert .notNull (scheduler , "scheduler must not be null" );
@@ -112,39 +96,6 @@ public String getName() {
11296		return  this .name ;
11397	}
11498
115- 	/** 
116- 	 * Use this property to configure one or more prefixes that this SockJS service is 
117- 	 * allowed to serve. The prefix (e.g. "/echo") is needed to extract the SockJS 
118- 	 * specific portion of the URL (e.g. "${prefix}/info", "${prefix}/iframe.html", etc). 
119- 	 * 
120- 	 * <p>This property is not strictly required. In most cases, the SockJS path can be 
121- 	 * auto-detected since the initial request from the SockJS client is of the form 
122- 	 * "{prefix}/info". Assuming the SockJS service is mapped correctly (e.g. using 
123- 	 * Ant-style pattern "/echo/**") this should work fine. This property can be used 
124- 	 * to configure explicitly the prefixes this service is allowed to service. 
125- 	 * 
126- 	 * @param prefixes the prefixes to use; prefixes do not need to include the portions 
127- 	 *        of the path that represent Servlet container context or Servlet path. 
128- 	 */ 
129- 	public  void  setValidSockJsPrefixes (String ... prefixes ) {
130- 
131- 		this .validSockJsPrefixes .clear ();
132- 		for  (String  prefix  : prefixes ) {
133- 			if  (prefix .endsWith ("/" ) && (prefix .length () > 1 )) {
134- 				prefix  = prefix .substring (0 , prefix .length () - 1 );
135- 			}
136- 			this .validSockJsPrefixes .add (prefix );
137- 		}
138- 
139- 		// sort with longest prefix at the top 
140- 		Collections .sort (this .validSockJsPrefixes , Collections .reverseOrder (new  Comparator <String >() {
141- 			@ Override 
142- 			public  int  compare (String  o1 , String  o2 ) {
143- 				return  new  Integer (o1 .length ()).compareTo (new  Integer (o2 .length ()));
144- 			}
145- 		}));
146- 	}
147- 
14899	/** 
149100	 * Transports which don't support cross-domain communication natively (e.g. 
150101	 * "eventsource", "htmlfile") rely on serving a simple page (using the 
@@ -308,12 +259,10 @@ public boolean isWebSocketEnabled() {
308259	 */ 
309260	@ Override 
310261	public  final  void  handleRequest (ServerHttpRequest  request , ServerHttpResponse  response ,
311- 			WebSocketHandler  wsHandler ) throws  SockJsException  {
262+ 			String   sockJsPath ,  WebSocketHandler  wsHandler ) throws  SockJsException  {
312263
313- 		String  sockJsPath  = getSockJsPath (request );
314264		if  (sockJsPath  == null ) {
315- 			logger .warn ("Could not determine SockJS path for URL \" "  + request .getURI ().getPath () +
316- 					". Consider setting validSockJsPrefixes." );
265+ 			logger .warn ("No SockJS path provided, URI=\" "  + request .getURI ());
317266			response .setStatusCode (HttpStatus .NOT_FOUND );
318267			return ;
319268		}
@@ -365,70 +314,6 @@ else if (sockJsPath.equals("/websocket")) {
365314		}
366315	}
367316
368- 	/** 
369- 	 * Return the SockJS path or null if the path could not be determined. 
370- 	 */ 
371- 	private  String  getSockJsPath (ServerHttpRequest  request ) {
372- 
373- 		String  path  = request .getURI ().getPath ();
374- 
375- 		// Try SockJS prefix hints 
376- 		if  (!this .validSockJsPrefixes .isEmpty ()) {
377- 			for  (String  prefix  : this .validSockJsPrefixes ) {
378- 				int  index  = path .lastIndexOf (prefix );
379- 				if  (index  != -1 ) {
380- 					return  path .substring (index  + prefix .length ());
381- 				}
382- 			}
383- 			return  null ;
384- 		}
385- 
386- 		// Try SockJS info request 
387- 		if  (path .endsWith ("/info" )) {
388- 			addKnownSockJsPrefix (path .substring (0 , path .length () - "/info" .length ()));
389- 			return  "/info" ;
390- 		}
391- 
392- 		// Have we seen this prefix before (following the initial /info request)? 
393- 		String  match  = null ;
394- 		for  (String  sockJsPath  : this .knownSockJsPrefixes ) {
395- 			if  (path .startsWith (sockJsPath )) {
396- 				if  ((match  == null ) || (match .length () < sockJsPath .length ())) {
397- 					match  = sockJsPath ;
398- 				}
399- 			}
400- 		}
401- 		if  (match  != null ) {
402- 			String  result  = path .substring (match .length ());
403- 			Assert .isTrue (result .charAt (0 )  == '/' , "Invalid SockJS path extracted from incoming path \" "  +
404- 					path  + "\" . The extracted SockJS path is \" "  + result  +
405- 					"\" . It was extracted from these known SockJS prefixes "  + this .knownSockJsPrefixes  +
406- 					". Consider setting 'validSockJsPrefixes' on DefaultSockJsService." );
407- 			return  result ;
408- 		}
409- 
410- 		// Try SockJS greeting 
411- 		String  pathNoSlash  = path .endsWith ("/" )  ? path .substring (0 , path .length () - 1 ) : path ;
412- 		String  lastSegment  = pathNoSlash .substring (pathNoSlash .lastIndexOf ('/' ) + 1 );
413- 
414- 		if  (!isValidTransportType (lastSegment ) && !lastSegment .startsWith ("iframe" )) {
415- 			addKnownSockJsPrefix (path );
416- 			return  "" ;
417- 		}
418- 
419- 		return  null ;
420- 	}
421- 
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- 
432317	/** 
433318	 * Validate whether the given transport String extracted from the URL is a valid 
434319	 * SockJS transport type (regardless of whether a transport handler is configured). 
0 commit comments