/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.socket.config.annotation;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.MultiValueMap;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import org.springframework.web.socket.server.support.OriginHandshakeInterceptor;
import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;
import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;
import org.springframework.web.socket.sockjs.transport.TransportHandler;
import org.springframework.web.socket.sockjs.transport.TransportType;
import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService;
import org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* Test fixture for
* {@link org.springframework.web.socket.config.annotation.WebMvcStompWebSocketEndpointRegistration}.
*
* @author Rossen Stoyanchev
*/
public class WebMvcStompWebSocketEndpointRegistrationTests {
private SubProtocolWebSocketHandler handler;
private TaskScheduler scheduler;
@Before
public void setup() {
this.handler = new SubProtocolWebSocketHandler(mock(MessageChannel.class), mock(SubscribableChannel.class));
this.scheduler = mock(TaskScheduler.class);
}
@Test
public void minimalRegistration() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
assertNotNull(((WebSocketHttpRequestHandler) entry.getKey()).getWebSocketHandler());
assertEquals(1, ((WebSocketHttpRequestHandler) entry.getKey()).getHandshakeInterceptors().size());
assertEquals(Arrays.asList("/foo"), entry.getValue());
}
@Test
public void allowedOrigins() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
registration.setAllowedOrigins();
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
assertNotNull(requestHandler.getWebSocketHandler());
assertEquals(1, requestHandler.getHandshakeInterceptors().size());
assertEquals(OriginHandshakeInterceptor.class, requestHandler.getHandshakeInterceptors().get(0).getClass());
}
@Test
public void sameOrigin() {
WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
registration.setAllowedOrigins();
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
assertNotNull(requestHandler.getWebSocketHandler());
assertEquals(1, requestHandler.getHandshakeInterceptors().size());
assertEquals(OriginHandshakeInterceptor.class, requestHandler.getHandshakeInterceptors().get(0).getClass());
}
@Test
public void allowedOriginsWithSockJsService() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
String origin = "http://mydomain.com";
registration.setAllowedOrigins(origin).withSockJS();
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
assertNotNull(requestHandler.getSockJsService());
DefaultSockJsService sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
assertTrue(sockJsService.getAllowedOrigins().contains(origin));
assertFalse(sockJsService.shouldSuppressCors());
registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
registration.withSockJS().setAllowedOrigins(origin);
mappings = registration.getMappings();
assertEquals(1, mappings.size());
requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
assertNotNull(requestHandler.getSockJsService());
sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
assertTrue(sockJsService.getAllowedOrigins().contains(origin));
assertFalse(sockJsService.shouldSuppressCors());
}
@Test // SPR-12283
public void disableCorsWithSockJsService() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
registration.withSockJS().setSupressCors(true);
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
assertNotNull(requestHandler.getSockJsService());
DefaultSockJsService sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
assertTrue(sockJsService.shouldSuppressCors());
}
@Test
public void handshakeHandlerAndInterceptor() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler();
HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor();
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor);
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
assertEquals(Arrays.asList("/foo"), entry.getValue());
WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler) entry.getKey();
assertNotNull(requestHandler.getWebSocketHandler());
assertSame(handshakeHandler, requestHandler.getHandshakeHandler());
assertEquals(2, requestHandler.getHandshakeInterceptors().size());
assertEquals(interceptor, requestHandler.getHandshakeInterceptors().get(0));
assertEquals(OriginHandshakeInterceptor.class, requestHandler.getHandshakeInterceptors().get(1).getClass());
}
@Test
public void handshakeHandlerAndInterceptorWithAllowedOrigins() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler();
HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor();
String origin = "http://mydomain.com";
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor).setAllowedOrigins(origin);
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
assertEquals(Arrays.asList("/foo"), entry.getValue());
WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler) entry.getKey();
assertNotNull(requestHandler.getWebSocketHandler());
assertSame(handshakeHandler, requestHandler.getHandshakeHandler());
assertEquals(2, requestHandler.getHandshakeInterceptors().size());
assertEquals(interceptor, requestHandler.getHandshakeInterceptors().get(0));
assertEquals(OriginHandshakeInterceptor.class, requestHandler.getHandshakeInterceptors().get(1).getClass());
}
@Test
public void handshakeHandlerInterceptorWithSockJsService() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler();
HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor();
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor).withSockJS();
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
assertEquals(Arrays.asList("/foo/**"), entry.getValue());
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler) entry.getKey();
assertNotNull(requestHandler.getWebSocketHandler());
DefaultSockJsService sockJsService = (DefaultSockJsService) requestHandler.getSockJsService();
assertNotNull(sockJsService);
Map<TransportType, TransportHandler> handlers = sockJsService.getTransportHandlers();
WebSocketTransportHandler transportHandler = (WebSocketTransportHandler) handlers.get(TransportType.WEBSOCKET);
assertSame(handshakeHandler, transportHandler.getHandshakeHandler());
assertEquals(2, sockJsService.getHandshakeInterceptors().size());
assertEquals(interceptor, sockJsService.getHandshakeInterceptors().get(0));
assertEquals(OriginHandshakeInterceptor.class, sockJsService.getHandshakeInterceptors().get(1).getClass());
}
@Test
public void handshakeHandlerInterceptorWithSockJsServiceAndAllowedOrigins() {
WebMvcStompWebSocketEndpointRegistration registration =
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler();
HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor();
String origin = "http://mydomain.com";
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor).setAllowedOrigins(origin).withSockJS();
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
assertEquals(1, mappings.size());
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
assertEquals(Arrays.asList("/foo/**"), entry.getValue());
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler) entry.getKey();
assertNotNull(requestHandler.getWebSocketHandler());
DefaultSockJsService sockJsService = (DefaultSockJsService) requestHandler.getSockJsService();
assertNotNull(sockJsService);
Map<TransportType, TransportHandler> handlers = sockJsService.getTransportHandlers();
WebSocketTransportHandler transportHandler = (WebSocketTransportHandler) handlers.get(TransportType.WEBSOCKET);
assertSame(handshakeHandler, transportHandler.getHandshakeHandler());
assertEquals(2, sockJsService.getHandshakeInterceptors().size());
assertEquals(interceptor, sockJsService.getHandshakeInterceptors().get(0));
assertEquals(OriginHandshakeInterceptor.class,
sockJsService.getHandshakeInterceptors().get(1).getClass());
assertTrue(sockJsService.getAllowedOrigins().contains(origin));
}
}