26
26
import java .util .List ;
27
27
import java .util .Random ;
28
28
import java .util .concurrent .TimeUnit ;
29
-
30
29
import javax .servlet .http .HttpServletRequest ;
31
30
32
31
import org .apache .commons .logging .Log ;
@@ -279,16 +278,13 @@ public boolean isWebSocketEnabled() {
279
278
* Configure allowed {@code Origin} header values. This check is mostly
280
279
* designed for browsers. There is nothing preventing other types of client
281
280
* to modify the {@code Origin} header value.
282
- *
283
281
* <p>When SockJS is enabled and origins are restricted, transport types
284
282
* that do not allow to check request origin (JSONP and Iframe based
285
283
* transports) are disabled. As a consequence, IE 6 to 9 are not supported
286
284
* when origins are restricted.
287
- *
288
285
* <p>Each provided allowed origin must have a scheme, and optionally a port
289
286
* (e.g. "http://example.org", "http://example.org:9090"). An allowed origin
290
287
* string may also be "*" in which case all origins are allowed.
291
- *
292
288
* @since 4.1.2
293
289
* @see <a href="https://tools.ietf.org/html/rfc6454">RFC 6454: The Web Origin Concept</a>
294
290
* @see <a href="https://github.com/sockjs/sockjs-client#supported-transports-by-browser-html-served-from-http-or-https">SockJS supported transports by browser</a>
@@ -325,6 +321,7 @@ public boolean shouldSuppressCors() {
325
321
return this .suppressCors ;
326
322
}
327
323
324
+
328
325
/**
329
326
* This method determines the SockJS path and handles SockJS static URLs.
330
327
* Session URLs and raw WebSocket requests are delegated to abstract methods.
@@ -348,68 +345,84 @@ public final void handleRequest(ServerHttpRequest request, ServerHttpResponse re
348
345
// As per SockJS protocol content-type can be ignored (it's always json)
349
346
}
350
347
351
- String requestInfo = logger .isDebugEnabled () ? request .getMethod () + " " + request .getURI () : "" ;
348
+ String requestInfo = ( logger .isDebugEnabled () ? request .getMethod () + " " + request .getURI () : null ) ;
352
349
try {
353
350
if (sockJsPath .equals ("" ) || sockJsPath .equals ("/" )) {
354
- logger .debug (requestInfo );
351
+ if (requestInfo != null ) {
352
+ logger .debug ("Processing transport request: " + requestInfo );
353
+ }
355
354
response .getHeaders ().setContentType (new MediaType ("text" , "plain" , UTF8_CHARSET ));
356
355
response .getBody ().write ("Welcome to SockJS!\n " .getBytes (UTF8_CHARSET ));
357
356
}
358
357
else if (sockJsPath .equals ("/info" )) {
359
- logger .debug (requestInfo );
358
+ if (requestInfo != null ) {
359
+ logger .debug ("Processing transport request: " + requestInfo );
360
+ }
360
361
this .infoHandler .handle (request , response );
361
362
}
362
363
else if (sockJsPath .matches ("/iframe[0-9-.a-z_]*.html" )) {
363
364
if (!this .allowedOrigins .isEmpty () && !this .allowedOrigins .contains ("*" )) {
364
- if (logger . isDebugEnabled () ) {
365
- logger .debug ("Iframe support is disabled when an origin check is required, ignoring " +
366
- requestInfo );
365
+ if (requestInfo != null ) {
366
+ logger .debug ("Iframe support is disabled when an origin check is required. " +
367
+ "Ignoring transport request: " + requestInfo );
367
368
}
368
369
response .setStatusCode (HttpStatus .NOT_FOUND );
369
370
return ;
370
371
}
371
372
if (this .allowedOrigins .isEmpty ()) {
372
373
response .getHeaders ().add (XFRAME_OPTIONS_HEADER , "SAMEORIGIN" );
373
374
}
374
- logger .debug (requestInfo );
375
+ if (requestInfo != null ) {
376
+ logger .debug ("Processing transport request: " + requestInfo );
377
+ }
375
378
this .iframeHandler .handle (request , response );
376
379
}
377
380
else if (sockJsPath .equals ("/websocket" )) {
378
381
if (isWebSocketEnabled ()) {
379
- logger .debug (requestInfo );
382
+ if (requestInfo != null ) {
383
+ logger .debug ("Processing transport request: " + requestInfo );
384
+ }
380
385
handleRawWebSocketRequest (request , response , wsHandler );
381
386
}
382
- else if (logger . isDebugEnabled () ) {
383
- logger .debug ("WebSocket disabled, ignoring " + requestInfo );
387
+ else if (requestInfo != null ) {
388
+ logger .debug ("WebSocket disabled. Ignoring transport request: " + requestInfo );
384
389
}
385
390
}
386
391
else {
387
392
String [] pathSegments = StringUtils .tokenizeToStringArray (sockJsPath .substring (1 ), "/" );
388
393
if (pathSegments .length != 3 ) {
389
394
if (logger .isWarnEnabled ()) {
390
- logger .warn ("Ignoring invalid transport request " + requestInfo );
395
+ logger .warn ("Invalid SockJS path '" + sockJsPath + "' - required to have 3 path segments" );
396
+ }
397
+ if (requestInfo != null ) {
398
+ logger .debug ("Ignoring transport request: " + requestInfo );
391
399
}
392
400
response .setStatusCode (HttpStatus .NOT_FOUND );
393
401
return ;
394
402
}
403
+
395
404
String serverId = pathSegments [0 ];
396
405
String sessionId = pathSegments [1 ];
397
406
String transport = pathSegments [2 ];
398
407
399
408
if (!isWebSocketEnabled () && transport .equals ("websocket" )) {
400
- if (logger . isDebugEnabled () ) {
401
- logger .debug ("WebSocket transport is disabled, ignoring " + requestInfo );
409
+ if (requestInfo != null ) {
410
+ logger .debug ("WebSocket disabled. Ignoring transport request: " + requestInfo );
402
411
}
403
412
response .setStatusCode (HttpStatus .NOT_FOUND );
404
413
return ;
405
414
}
406
415
else if (!validateRequest (serverId , sessionId , transport )) {
407
- if (logger . isWarnEnabled () ) {
408
- logger .warn ("Ignoring transport request " + requestInfo );
416
+ if (requestInfo != null ) {
417
+ logger .debug ("Ignoring transport request: " + requestInfo );
409
418
}
410
419
response .setStatusCode (HttpStatus .NOT_FOUND );
411
420
return ;
412
421
}
422
+
423
+ if (requestInfo != null ) {
424
+ logger .debug ("Processing transport request: " + requestInfo );
425
+ }
413
426
handleTransportRequest (request , response , wsHandler , sessionId , transport );
414
427
}
415
428
response .close ();
@@ -421,14 +434,16 @@ else if (!validateRequest(serverId, sessionId, transport)) {
421
434
422
435
protected boolean validateRequest (String serverId , String sessionId , String transport ) {
423
436
if (!StringUtils .hasText (serverId ) || !StringUtils .hasText (sessionId ) || !StringUtils .hasText (transport )) {
424
- logger .warn ("No server, session, or transport path segment" );
437
+ logger .warn ("No server, session, or transport path segment in SockJS request. " );
425
438
return false ;
426
439
}
440
+
427
441
// Server and session id's must not contain "."
428
442
if (serverId .contains ("." ) || sessionId .contains ("." )) {
429
443
logger .warn ("Either server or session contains a \" .\" which is not allowed by SockJS protocol." );
430
444
return false ;
431
445
}
446
+
432
447
return true ;
433
448
}
434
449
@@ -445,6 +460,7 @@ protected abstract void handleRawWebSocketRequest(ServerHttpRequest request,
445
460
protected abstract void handleTransportRequest (ServerHttpRequest request , ServerHttpResponse response ,
446
461
WebSocketHandler webSocketHandler , String sessionId , String transport ) throws SockJsException ;
447
462
463
+
448
464
protected boolean checkOrigin (ServerHttpRequest request , ServerHttpResponse response ,
449
465
HttpMethod ... httpMethods ) throws IOException {
450
466
@@ -454,7 +470,9 @@ protected boolean checkOrigin(ServerHttpRequest request, ServerHttpResponse resp
454
470
455
471
if (!WebUtils .isValidOrigin (request , this .allowedOrigins )) {
456
472
String origin = request .getHeaders ().getOrigin ();
457
- logger .debug ("Request rejected, Origin header value " + origin + " not allowed" );
473
+ if (logger .isWarnEnabled ()) {
474
+ logger .warn ("Origin header value '" + origin + "' not allowed." );
475
+ }
458
476
response .setStatusCode (HttpStatus .FORBIDDEN );
459
477
return false ;
460
478
}
0 commit comments