parent
5245327962
commit
723e09c164
|
@ -98,18 +98,19 @@ public class SockJsServiceRegistration {
|
|||
/**
|
||||
* Transports with no native cross-domain communication (e.g. "eventsource",
|
||||
* "htmlfile") must get a simple page from the "foreign" domain in an invisible
|
||||
* iframe so that code in the iframe can run from a domain local to the SockJS
|
||||
* server. Since the iframe needs to load the SockJS javascript client library,
|
||||
* this property allows specifying where to load it from.
|
||||
* {@code iframe} so that code in the {@code iframe} can run from a domain
|
||||
* local to the SockJS server. Since the {@code iframe} needs to load the
|
||||
* SockJS JavaScript client library, this property allows specifying where to
|
||||
* load it from.
|
||||
* <p>By default this is set to point to
|
||||
* "<a href="https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js">sockjs.min.js</a>". However, it can
|
||||
* also be set to point to a URL served by the application.
|
||||
* <a href="https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js">"https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js"</a>.
|
||||
* However, it can also be set to point to a URL served by the application.
|
||||
* <p>Note that it's possible to specify a relative URL in which case the URL
|
||||
* must be relative to the iframe URL. For example assuming a SockJS endpoint
|
||||
* mapped to "/sockjs", and resulting iframe URL "/sockjs/iframe.html", then
|
||||
* must be relative to the {@code iframe} URL. For example assuming a SockJS endpoint
|
||||
* mapped to "/sockjs", and resulting {@code iframe} URL "/sockjs/iframe.html", then
|
||||
* the relative URL must start with "../../" to traverse up to the location
|
||||
* above the SockJS mapping. In case of a prefix-based Servlet mapping one more
|
||||
* traversal may be needed.
|
||||
* traversals may be needed.
|
||||
*/
|
||||
public SockJsServiceRegistration setClientLibraryUrl(String clientLibraryUrl) {
|
||||
this.clientLibraryUrl = clientLibraryUrl;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -145,18 +145,19 @@ public abstract class AbstractSockJsService implements SockJsService, CorsConfig
|
|||
/**
|
||||
* Transports with no native cross-domain communication (e.g. "eventsource",
|
||||
* "htmlfile") must get a simple page from the "foreign" domain in an invisible
|
||||
* iframe so that code in the iframe can run from a domain local to the SockJS
|
||||
* server. Since the iframe needs to load the SockJS javascript client library,
|
||||
* this property allows specifying where to load it from.
|
||||
* {@code iframe} so that code in the {@code iframe} can run from a domain
|
||||
* local to the SockJS server. Since the {@code iframe} needs to load the
|
||||
* SockJS JavaScript client library, this property allows specifying where to
|
||||
* load it from.
|
||||
* <p>By default this is set to point to
|
||||
* "<a href="https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js">sockjs.min.js</a>".
|
||||
* <a href="https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js">"https://cdn.jsdelivr.net/sockjs/1.0.0/sockjs.min.js"</a>.
|
||||
* However, it can also be set to point to a URL served by the application.
|
||||
* <p>Note that it's possible to specify a relative URL in which case the URL
|
||||
* must be relative to the iframe URL. For example assuming a SockJS endpoint
|
||||
* mapped to "/sockjs", and resulting iframe URL "/sockjs/iframe.html", then
|
||||
* must be relative to the {@code iframe} URL. For example assuming a SockJS endpoint
|
||||
* mapped to "/sockjs", and resulting {@code iframe} URL "/sockjs/iframe.html", then
|
||||
* the relative URL must start with "../../" to traverse up to the location
|
||||
* above the SockJS mapping. In case of a prefix-based Servlet mapping one more
|
||||
* traversal may be needed.
|
||||
* traversals may be needed.
|
||||
*/
|
||||
public void setSockJsClientLibraryUrl(String clientLibraryUrl) {
|
||||
this.clientLibraryUrl = clientLibraryUrl;
|
||||
|
@ -613,24 +614,23 @@ public abstract class AbstractSockJsService implements SockJsService, CorsConfig
|
|||
|
||||
private class IframeHandler implements SockJsRequestHandler {
|
||||
|
||||
private static final String IFRAME_CONTENT =
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<script>
|
||||
document.domain = document.domain;
|
||||
_sockjs_onload = function(){SockJS.bootstrap_iframe();};
|
||||
</script>
|
||||
<script src="%s"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Don't panic!</h2>
|
||||
<p>This is a SockJS hidden iframe. It's used for cross domain magic.</p>
|
||||
</body>
|
||||
</html>""";
|
||||
private static final String IFRAME_CONTENT = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<script>
|
||||
document.domain = document.domain;
|
||||
_sockjs_onload = function(){SockJS.bootstrap_iframe();};
|
||||
</script>
|
||||
<script src="%s"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Don't panic!</h2>
|
||||
<p>This is a SockJS hidden iframe. It's used for cross domain magic.</p>
|
||||
</body>
|
||||
</html>""";
|
||||
|
||||
@Override
|
||||
public void handle(ServerHttpRequest request, ServerHttpResponse response) throws IOException {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -59,26 +59,22 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
|
|||
|
||||
|
||||
static {
|
||||
StringBuilder sb = new StringBuilder(
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
</head><body><h2>Don't panic!</h2>
|
||||
<script>
|
||||
document.domain = document.domain;
|
||||
var c = parent.%s;
|
||||
c.start();
|
||||
function p(d) {c.message(d);};
|
||||
window.onload = function() {c.stop();};
|
||||
</script>"""
|
||||
);
|
||||
StringBuilder sb = new StringBuilder("""
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
</head><body><h2>Don't panic!</h2>
|
||||
<script>
|
||||
document.domain = document.domain;
|
||||
var c = parent.%s;
|
||||
c.start();
|
||||
function p(d) {c.message(d);};
|
||||
window.onload = function() {c.stop();};
|
||||
</script>""");
|
||||
|
||||
while (sb.length() < MINIMUM_PARTIAL_HTML_CONTENT_LENGTH) {
|
||||
sb.append(' ');
|
||||
}
|
||||
PARTIAL_HTML_CONTENT = sb.toString();
|
||||
sb.append(" ".repeat(MINIMUM_PARTIAL_HTML_CONTENT_LENGTH - sb.length()));
|
||||
PARTIAL_HTML_CONTENT = sb.append('\n').toString();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -45,7 +45,7 @@ public abstract class AbstractHttpRequestTests {
|
|||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
protected void setup() {
|
||||
resetRequestAndResponse();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.springframework.web.socket.config.annotation;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
@ -47,67 +46,62 @@ import static org.mockito.Mockito.mock;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class WebMvcStompWebSocketEndpointRegistrationTests {
|
||||
class WebMvcStompWebSocketEndpointRegistrationTests {
|
||||
|
||||
private SubProtocolWebSocketHandler handler;
|
||||
private final SubProtocolWebSocketHandler handler =
|
||||
new SubProtocolWebSocketHandler(mock(MessageChannel.class), mock(SubscribableChannel.class));
|
||||
|
||||
private TaskScheduler scheduler;
|
||||
private final TaskScheduler scheduler = mock(TaskScheduler.class);
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.handler = new SubProtocolWebSocketHandler(mock(MessageChannel.class), mock(SubscribableChannel.class));
|
||||
this.scheduler = mock(TaskScheduler.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimalRegistration() {
|
||||
void minimalRegistration() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
|
||||
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
|
||||
assertThat(((WebSocketHttpRequestHandler) entry.getKey()).getWebSocketHandler()).isNotNull();
|
||||
assertThat(((WebSocketHttpRequestHandler) entry.getKey()).getHandshakeInterceptors().size()).isEqualTo(1);
|
||||
assertThat(entry.getValue()).isEqualTo(List.of("/foo"));
|
||||
assertThat(((WebSocketHttpRequestHandler) entry.getKey()).getHandshakeInterceptors()).hasSize(1);
|
||||
assertThat(entry.getValue()).containsExactly("/foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allowedOrigins() {
|
||||
void allowedOrigins() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
registration.setAllowedOrigins();
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
HttpRequestHandler handler = mappings.entrySet().iterator().next().getKey();
|
||||
WebSocketHttpRequestHandler wsHandler = (WebSocketHttpRequestHandler) handler;
|
||||
assertThat(wsHandler.getWebSocketHandler()).isNotNull();
|
||||
assertThat(wsHandler.getHandshakeInterceptors().size()).isEqualTo(1);
|
||||
assertThat(wsHandler.getHandshakeInterceptors()).hasSize(1);
|
||||
assertThat(wsHandler.getHandshakeInterceptors().get(0).getClass()).isEqualTo(OriginHandshakeInterceptor.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameOrigin() {
|
||||
void sameOrigin() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration(
|
||||
new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
registration.setAllowedOrigins();
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
HttpRequestHandler handler = mappings.entrySet().iterator().next().getKey();
|
||||
WebSocketHttpRequestHandler wsHandler = (WebSocketHttpRequestHandler) handler;
|
||||
assertThat(wsHandler.getWebSocketHandler()).isNotNull();
|
||||
assertThat(wsHandler.getHandshakeInterceptors().size()).isEqualTo(1);
|
||||
assertThat(wsHandler.getHandshakeInterceptors()).hasSize(1);
|
||||
assertThat(wsHandler.getHandshakeInterceptors().get(0).getClass()).isEqualTo(OriginHandshakeInterceptor.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allowedOriginsWithSockJsService() {
|
||||
void allowedOriginsWithSockJsService() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
|
@ -115,7 +109,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
registration.setAllowedOrigins(origin).withSockJS();
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
|
||||
assertThat(requestHandler.getSockJsService()).isNotNull();
|
||||
DefaultSockJsService sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
|
||||
|
@ -126,7 +120,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
registration.withSockJS().setAllowedOrigins(origin);
|
||||
mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
|
||||
assertThat(requestHandler.getSockJsService()).isNotNull();
|
||||
sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
|
||||
|
@ -135,7 +129,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void allowedOriginPatterns() {
|
||||
void allowedOriginPatterns() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
|
@ -143,7 +137,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
registration.setAllowedOriginPatterns(origin).withSockJS();
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
|
||||
assertThat(requestHandler.getSockJsService()).isNotNull();
|
||||
DefaultSockJsService sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
|
||||
|
@ -153,7 +147,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
registration.withSockJS().setAllowedOriginPatterns(origin);
|
||||
mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
|
||||
assertThat(requestHandler.getSockJsService()).isNotNull();
|
||||
sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
|
||||
|
@ -161,14 +155,14 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
}
|
||||
|
||||
@Test // SPR-12283
|
||||
public void disableCorsWithSockJsService() {
|
||||
void disableCorsWithSockJsService() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
registration.withSockJS().setSuppressCors(true);
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler)mappings.entrySet().iterator().next().getKey();
|
||||
assertThat(requestHandler.getSockJsService()).isNotNull();
|
||||
DefaultSockJsService sockJsService = (DefaultSockJsService)requestHandler.getSockJsService();
|
||||
|
@ -176,7 +170,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handshakeHandlerAndInterceptor() {
|
||||
void handshakeHandlerAndInterceptor() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
|
@ -186,21 +180,21 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor);
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
|
||||
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
|
||||
assertThat(entry.getValue()).isEqualTo(List.of("/foo"));
|
||||
assertThat(entry.getValue()).containsExactly("/foo");
|
||||
|
||||
WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler) entry.getKey();
|
||||
assertThat(requestHandler.getWebSocketHandler()).isNotNull();
|
||||
assertThat(requestHandler.getHandshakeHandler()).isSameAs(handshakeHandler);
|
||||
assertThat(requestHandler.getHandshakeInterceptors().size()).isEqualTo(2);
|
||||
assertThat(requestHandler.getHandshakeInterceptors()).hasSize(2);
|
||||
assertThat(requestHandler.getHandshakeInterceptors().get(0)).isEqualTo(interceptor);
|
||||
assertThat(requestHandler.getHandshakeInterceptors().get(1).getClass()).isEqualTo(OriginHandshakeInterceptor.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handshakeHandlerAndInterceptorWithAllowedOrigins() {
|
||||
void handshakeHandlerAndInterceptorWithAllowedOrigins() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
|
@ -210,21 +204,21 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor).setAllowedOrigins(origin);
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
|
||||
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
|
||||
assertThat(entry.getValue()).isEqualTo(List.of("/foo"));
|
||||
assertThat(entry.getValue()).containsExactly("/foo");
|
||||
|
||||
WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler) entry.getKey();
|
||||
assertThat(requestHandler.getWebSocketHandler()).isNotNull();
|
||||
assertThat(requestHandler.getHandshakeHandler()).isSameAs(handshakeHandler);
|
||||
assertThat(requestHandler.getHandshakeInterceptors().size()).isEqualTo(2);
|
||||
assertThat(requestHandler.getHandshakeInterceptors()).hasSize(2);
|
||||
assertThat(requestHandler.getHandshakeInterceptors().get(0)).isEqualTo(interceptor);
|
||||
assertThat(requestHandler.getHandshakeInterceptors().get(1).getClass()).isEqualTo(OriginHandshakeInterceptor.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handshakeHandlerInterceptorWithSockJsService() {
|
||||
void handshakeHandlerInterceptorWithSockJsService() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
|
@ -234,10 +228,10 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
registration.setHandshakeHandler(handshakeHandler).addInterceptors(interceptor).withSockJS();
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
|
||||
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
|
||||
assertThat(entry.getValue()).isEqualTo(List.of("/foo/**"));
|
||||
assertThat(entry.getValue()).containsExactly("/foo/**");
|
||||
|
||||
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler) entry.getKey();
|
||||
assertThat(requestHandler.getWebSocketHandler()).isNotNull();
|
||||
|
@ -248,13 +242,13 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
Map<TransportType, TransportHandler> handlers = sockJsService.getTransportHandlers();
|
||||
WebSocketTransportHandler transportHandler = (WebSocketTransportHandler) handlers.get(TransportType.WEBSOCKET);
|
||||
assertThat(transportHandler.getHandshakeHandler()).isSameAs(handshakeHandler);
|
||||
assertThat(sockJsService.getHandshakeInterceptors().size()).isEqualTo(2);
|
||||
assertThat(sockJsService.getHandshakeInterceptors()).hasSize(2);
|
||||
assertThat(sockJsService.getHandshakeInterceptors().get(0)).isEqualTo(interceptor);
|
||||
assertThat(sockJsService.getHandshakeInterceptors().get(1).getClass()).isEqualTo(OriginHandshakeInterceptor.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handshakeHandlerInterceptorWithSockJsServiceAndAllowedOrigins() {
|
||||
void handshakeHandlerInterceptorWithSockJsServiceAndAllowedOrigins() {
|
||||
WebMvcStompWebSocketEndpointRegistration registration =
|
||||
new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler);
|
||||
|
||||
|
@ -266,10 +260,10 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
.addInterceptors(interceptor).setAllowedOrigins(origin).withSockJS();
|
||||
|
||||
MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings).hasSize(1);
|
||||
|
||||
Map.Entry<HttpRequestHandler, List<String>> entry = mappings.entrySet().iterator().next();
|
||||
assertThat(entry.getValue()).isEqualTo(List.of("/foo/**"));
|
||||
assertThat(entry.getValue()).containsExactly("/foo/**");
|
||||
|
||||
SockJsHttpRequestHandler requestHandler = (SockJsHttpRequestHandler) entry.getKey();
|
||||
assertThat(requestHandler.getWebSocketHandler()).isNotNull();
|
||||
|
@ -280,7 +274,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests {
|
|||
Map<TransportType, TransportHandler> handlers = sockJsService.getTransportHandlers();
|
||||
WebSocketTransportHandler transportHandler = (WebSocketTransportHandler) handlers.get(TransportType.WEBSOCKET);
|
||||
assertThat(transportHandler.getHandshakeHandler()).isSameAs(handshakeHandler);
|
||||
assertThat(sockJsService.getHandshakeInterceptors().size()).isEqualTo(2);
|
||||
assertThat(sockJsService.getHandshakeInterceptors()).hasSize(2);
|
||||
assertThat(sockJsService.getHandshakeInterceptors().get(0)).isEqualTo(interceptor);
|
||||
assertThat(sockJsService.getHandshakeInterceptors().get(1).getClass()).isEqualTo(OriginHandshakeInterceptor.class);
|
||||
assertThat(sockJsService.getAllowedOrigins().contains(origin)).isTrue();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -88,7 +88,7 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.protocolHandler = new StompSubProtocolHandler();
|
||||
this.channel = Mockito.mock(MessageChannel.class);
|
||||
this.messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
|
@ -101,24 +101,22 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithConnectedFrame() {
|
||||
|
||||
void handleMessageToClientWithConnectedFrame() {
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECTED);
|
||||
Message<byte[]> message = MessageBuilder.createMessage(EMPTY_PAYLOAD, headers.getMessageHeaders());
|
||||
this.protocolHandler.handleMessageToClient(this.session, message);
|
||||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
WebSocketMessage<?> textMessage = this.session.getSentMessages().get(0);
|
||||
assertThat(textMessage.getPayload()).isEqualTo(("""
|
||||
assertThat(textMessage.getPayload()).isEqualTo("""
|
||||
CONNECTED
|
||||
user-name:joe
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithDestinationUserNameProvider() {
|
||||
|
||||
void handleMessageToClientWithDestinationUserNameProvider() {
|
||||
this.session.setPrincipal(new UniqueUser("joe"));
|
||||
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECTED);
|
||||
|
@ -127,16 +125,15 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
WebSocketMessage<?> textMessage = this.session.getSentMessages().get(0);
|
||||
assertThat(textMessage.getPayload()).isEqualTo(("""
|
||||
assertThat(textMessage.getPayload()).isEqualTo("""
|
||||
CONNECTED
|
||||
user-name:joe
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithSimpConnectAck() {
|
||||
|
||||
void handleMessageToClientWithSimpConnectAck() {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
accessor.setHeartbeat(10000, 10000);
|
||||
accessor.setAcceptVersion("1.0,1.1,1.2");
|
||||
|
@ -150,18 +147,17 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
TextMessage actual = (TextMessage) this.session.getSentMessages().get(0);
|
||||
assertThat(actual.getPayload()).isEqualTo(("""
|
||||
assertThat(actual.getPayload()).isEqualTo("""
|
||||
CONNECTED
|
||||
version:1.2
|
||||
heart-beat:15000,15000
|
||||
user-name:joe
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithSimpConnectAckDefaultHeartBeat() {
|
||||
|
||||
void handleMessageToClientWithSimpConnectAckDefaultHeartBeat() {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
accessor.setHeartbeat(10000, 10000);
|
||||
accessor.setAcceptVersion("1.0");
|
||||
|
@ -174,18 +170,17 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
TextMessage actual = (TextMessage) this.session.getSentMessages().get(0);
|
||||
assertThat(actual.getPayload()).isEqualTo(("""
|
||||
assertThat(actual.getPayload()).isEqualTo("""
|
||||
CONNECTED
|
||||
version:1.0
|
||||
heart-beat:0,0
|
||||
user-name:joe
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithSimpDisconnectAck() {
|
||||
|
||||
void handleMessageToClientWithSimpDisconnectAck() {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.DISCONNECT);
|
||||
Message<?> connectMessage = MessageBuilder.createMessage(EMPTY_PAYLOAD, accessor.getMessageHeaders());
|
||||
|
||||
|
@ -196,17 +191,16 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
TextMessage actual = (TextMessage) this.session.getSentMessages().get(0);
|
||||
assertThat(actual.getPayload()).isEqualTo(("""
|
||||
assertThat(actual.getPayload()).isEqualTo("""
|
||||
ERROR
|
||||
message:Session closed.
|
||||
content-length:0
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithSimpDisconnectAckAndReceipt() {
|
||||
|
||||
void handleMessageToClientWithSimpDisconnectAckAndReceipt() {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.DISCONNECT);
|
||||
accessor.setReceipt("message-123");
|
||||
Message<?> connectMessage = MessageBuilder.createMessage(EMPTY_PAYLOAD, accessor.getMessageHeaders());
|
||||
|
@ -218,16 +212,15 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
TextMessage actual = (TextMessage) this.session.getSentMessages().get(0);
|
||||
assertThat(actual.getPayload()).isEqualTo(("""
|
||||
assertThat(actual.getPayload()).isEqualTo("""
|
||||
RECEIPT
|
||||
receipt-id:message-123
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithSimpHeartbeat() {
|
||||
|
||||
void handleMessageToClientWithSimpHeartbeat() {
|
||||
SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create(SimpMessageType.HEARTBEAT);
|
||||
accessor.setSessionId("s1");
|
||||
accessor.setUser(new TestPrincipal("joe"));
|
||||
|
@ -240,8 +233,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithHeartbeatSuppressingSockJsHeartbeat() throws IOException {
|
||||
|
||||
void handleMessageToClientWithHeartbeatSuppressingSockJsHeartbeat() throws IOException {
|
||||
SockJsSession sockJsSession = Mockito.mock(SockJsSession.class);
|
||||
given(sockJsSession.getId()).willReturn("s1");
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECTED);
|
||||
|
@ -269,8 +261,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithUserDestination() {
|
||||
|
||||
void handleMessageToClientWithUserDestination() {
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.MESSAGE);
|
||||
headers.setMessageId("mess0");
|
||||
headers.setSubscriptionId("sub0");
|
||||
|
@ -288,8 +279,7 @@ public class StompSubProtocolHandlerTests {
|
|||
// SPR-12475
|
||||
|
||||
@Test
|
||||
public void handleMessageToClientWithBinaryWebSocketMessage() {
|
||||
|
||||
void handleMessageToClientWithBinaryWebSocketMessage() {
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.MESSAGE);
|
||||
headers.setMessageId("mess0");
|
||||
headers.setSubscriptionId("sub0");
|
||||
|
@ -318,8 +308,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageFromClient() {
|
||||
|
||||
void handleMessageFromClient() {
|
||||
TextMessage textMessage = StompTextMessageBuilder.create(StompCommand.STOMP).headers(
|
||||
"login:guest", "passcode:guest", "accept-version:1.1,1.0", "heart-beat:10000,10000").build();
|
||||
|
||||
|
@ -347,7 +336,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageFromClientWithImmutableMessageInterceptor() {
|
||||
void handleMessageFromClientWithImmutableMessageInterceptor() {
|
||||
AtomicReference<Boolean> mutable = new AtomicReference<>();
|
||||
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel();
|
||||
channel.addInterceptor(new ChannelInterceptor() {
|
||||
|
@ -369,7 +358,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageFromClientWithoutImmutableMessageInterceptor() {
|
||||
void handleMessageFromClientWithoutImmutableMessageInterceptor() {
|
||||
AtomicReference<Boolean> mutable = new AtomicReference<>();
|
||||
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel();
|
||||
channel.addInterceptor(new ChannelInterceptor() {
|
||||
|
@ -390,7 +379,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test // SPR-14690
|
||||
public void handleMessageFromClientWithTokenAuthentication() {
|
||||
void handleMessageFromClientWithTokenAuthentication() {
|
||||
ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel();
|
||||
channel.addInterceptor(new AuthenticationInterceptor("__pete__@gmail.com"));
|
||||
channel.addInterceptor(new ImmutableMessageChannelInterceptor());
|
||||
|
@ -416,17 +405,15 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages()).hasSize(1);
|
||||
WebSocketMessage<?> textMessage = this.session.getSentMessages().get(0);
|
||||
assertThat(textMessage.getPayload())
|
||||
.isEqualTo("""
|
||||
CONNECTED
|
||||
user-name:__pete__@gmail.com
|
||||
assertThat(textMessage.getPayload()).isEqualTo("""
|
||||
CONNECTED
|
||||
user-name:__pete__@gmail.com
|
||||
|
||||
\u0000""");
|
||||
\u0000""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageFromClientWithInvalidStompCommand() {
|
||||
|
||||
void handleMessageFromClientWithInvalidStompCommand() {
|
||||
TextMessage textMessage = new TextMessage("FOO\n\n\0");
|
||||
|
||||
this.protocolHandler.afterSessionStarted(this.session, this.channel);
|
||||
|
@ -439,8 +426,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void eventPublication() {
|
||||
|
||||
void eventPublication() {
|
||||
TestPublisher publisher = new TestPublisher();
|
||||
|
||||
this.protocolHandler.setApplicationEventPublisher(publisher);
|
||||
|
@ -476,8 +462,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void eventPublicationWithExceptions() {
|
||||
|
||||
void eventPublicationWithExceptions() {
|
||||
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);
|
||||
|
||||
this.protocolHandler.setApplicationEventPublisher(publisher);
|
||||
|
@ -500,11 +485,11 @@ public class StompSubProtocolHandlerTests {
|
|||
|
||||
assertThat(this.session.getSentMessages().size()).isEqualTo(1);
|
||||
textMessage = (TextMessage) this.session.getSentMessages().get(0);
|
||||
assertThat(textMessage.getPayload()).isEqualTo(("""
|
||||
assertThat(textMessage.getPayload()).isEqualTo("""
|
||||
CONNECTED
|
||||
user-name:joe
|
||||
|
||||
\u0000"""));
|
||||
\u0000""");
|
||||
|
||||
this.protocolHandler.afterSessionEnded(this.session, CloseStatus.BAD_DATA, this.channel);
|
||||
|
||||
|
@ -518,8 +503,7 @@ public class StompSubProtocolHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void webSocketScope() {
|
||||
|
||||
void webSocketScope() {
|
||||
Runnable runnable = Mockito.mock(Runnable.class);
|
||||
SimpAttributes simpAttributes = new SimpAttributes(this.session.getId(), this.session.getAttributes());
|
||||
simpAttributes.setAttribute("name", "value");
|
||||
|
@ -610,4 +594,5 @@ public class StompSubProtocolHandlerTests {
|
|||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -54,6 +53,7 @@ import org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec;
|
|||
import org.springframework.web.socket.sockjs.frame.SockJsFrame;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
@ -66,7 +66,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class RestTemplateXhrTransportTests {
|
||||
class RestTemplateXhrTransportTests {
|
||||
|
||||
private static final Jackson2SockJsMessageCodec CODEC = new Jackson2SockJsMessageCodec();
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class RestTemplateXhrTransportTests {
|
|||
|
||||
|
||||
@Test
|
||||
public void connectReceiveAndClose() throws Exception {
|
||||
void connectReceiveAndClose() throws Exception {
|
||||
String body = """
|
||||
o
|
||||
a["foo"]
|
||||
|
@ -89,12 +89,13 @@ public class RestTemplateXhrTransportTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void connectReceiveAndCloseWithPrelude() throws Exception {
|
||||
StringBuilder sb = new StringBuilder(2048);
|
||||
for (int i = 0; i < 2048; i++) {
|
||||
sb.append('h');
|
||||
}
|
||||
String body = sb + "\n" + "o\n" + "a[\"foo\"]\n" + "c[3000,\"Go away!\"]";
|
||||
void connectReceiveAndCloseWithPrelude() throws Exception {
|
||||
String prelude = "h".repeat(2048);
|
||||
String body = """
|
||||
%s
|
||||
o
|
||||
a["foo"]
|
||||
c[3000,"Go away!"]""".formatted(prelude);
|
||||
ClientHttpResponse response = response(HttpStatus.OK, body);
|
||||
connect(response);
|
||||
|
||||
|
@ -105,16 +106,19 @@ public class RestTemplateXhrTransportTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void connectReceiveAndCloseWithStompFrame() throws Exception {
|
||||
void connectReceiveAndCloseWithStompFrame() throws Exception {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND);
|
||||
accessor.setDestination("/destination");
|
||||
MessageHeaders headers = accessor.getMessageHeaders();
|
||||
Message<byte[]> message = MessageBuilder.createMessage("body".getBytes(StandardCharsets.UTF_8), headers);
|
||||
Message<byte[]> message = MessageBuilder.createMessage("body".getBytes(UTF_8), headers);
|
||||
byte[] bytes = new StompEncoder().encode(message);
|
||||
TextMessage textMessage = new TextMessage(bytes);
|
||||
SockJsFrame frame = SockJsFrame.messageFrame(new Jackson2SockJsMessageCodec(), textMessage.getPayload());
|
||||
|
||||
String body = "o\n" + frame.getContent() + "\n" + "c[3000,\"Go away!\"]";
|
||||
String body = """
|
||||
o
|
||||
%s
|
||||
c[3000,"Go away!"]""".formatted(frame.getContent());
|
||||
ClientHttpResponse response = response(HttpStatus.OK, body);
|
||||
connect(response);
|
||||
|
||||
|
@ -126,7 +130,7 @@ public class RestTemplateXhrTransportTests {
|
|||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void connectFailure() throws Exception {
|
||||
void connectFailure() throws Exception {
|
||||
final HttpServerErrorException expected = new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
RestOperations restTemplate = mock(RestOperations.class);
|
||||
given(restTemplate.execute((URI) any(), eq(HttpMethod.POST), any(), any())).willThrow(expected);
|
||||
|
@ -149,7 +153,7 @@ public class RestTemplateXhrTransportTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void errorResponseStatus() throws Exception {
|
||||
void errorResponseStatus() throws Exception {
|
||||
connect(response(HttpStatus.OK, "o\n"), response(HttpStatus.INTERNAL_SERVER_ERROR, "Oops"));
|
||||
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(any());
|
||||
|
@ -159,7 +163,7 @@ public class RestTemplateXhrTransportTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void responseClosedAfterDisconnected() throws Exception {
|
||||
void responseClosedAfterDisconnected() throws Exception {
|
||||
String body = """
|
||||
o
|
||||
c[3000,"Go away!"]
|
||||
|
@ -205,7 +209,7 @@ public class RestTemplateXhrTransportTests {
|
|||
}
|
||||
|
||||
private InputStream getInputStream(String content) {
|
||||
byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] bytes = content.getBytes(UTF_8);
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -22,7 +22,6 @@ import java.util.Collections;
|
|||
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
@ -49,23 +48,13 @@ import static org.mockito.Mockito.verify;
|
|||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class SockJsServiceTests extends AbstractHttpRequestTests {
|
||||
class SockJsServiceTests extends AbstractHttpRequestTests {
|
||||
|
||||
private TestSockJsService service;
|
||||
|
||||
private WebSocketHandler handler;
|
||||
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
super.setup();
|
||||
this.service = new TestSockJsService(new ThreadPoolTaskScheduler());
|
||||
}
|
||||
private final TestSockJsService service = new TestSockJsService(new ThreadPoolTaskScheduler());
|
||||
|
||||
|
||||
@Test
|
||||
public void validateRequest() {
|
||||
void validateRequest() {
|
||||
this.service.setWebSocketEnabled(false);
|
||||
resetResponseAndHandleRequest("GET", "/echo/server/session/websocket", HttpStatus.NOT_FOUND);
|
||||
|
||||
|
@ -84,7 +73,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleInfoGet() throws IOException {
|
||||
void handleInfoGet() throws IOException {
|
||||
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.OK);
|
||||
|
||||
assertThat(this.servletResponse.getContentType()).isEqualTo("application/json;charset=UTF-8");
|
||||
|
@ -113,7 +102,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-12226 and SPR-12660
|
||||
public void handleInfoGetWithOrigin() throws IOException {
|
||||
void handleInfoGetWithOrigin() throws IOException {
|
||||
this.servletRequest.setServerName("mydomain2.example");
|
||||
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "http://mydomain2.example");
|
||||
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.OK);
|
||||
|
@ -140,7 +129,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-11443
|
||||
public void handleInfoGetCorsFilter() {
|
||||
void handleInfoGetCorsFilter() {
|
||||
// Simulate scenario where Filter would have already set CORS headers
|
||||
this.servletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "foobar:123");
|
||||
|
||||
|
@ -150,7 +139,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-11919
|
||||
public void handleInfoGetWildflyNPE() throws IOException {
|
||||
void handleInfoGetWildflyNPE() throws IOException {
|
||||
HttpServletResponse mockResponse = mock(HttpServletResponse.class);
|
||||
ServletOutputStream ous = mock(ServletOutputStream.class);
|
||||
given(mockResponse.getHeaders(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).willThrow(NullPointerException.class);
|
||||
|
@ -163,7 +152,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-12660
|
||||
public void handleInfoOptions() {
|
||||
void handleInfoOptions() {
|
||||
this.servletRequest.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Last-Modified");
|
||||
resetResponseAndHandleRequest("OPTIONS", "/echo/info", HttpStatus.NO_CONTENT);
|
||||
assertThat(this.service.getCorsConfiguration(this.servletRequest)).isNull();
|
||||
|
@ -174,7 +163,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-12226 and SPR-12660
|
||||
public void handleInfoOptionsWithAllowedOrigin() {
|
||||
void handleInfoOptionsWithAllowedOrigin() {
|
||||
this.servletRequest.setServerName("mydomain2.example");
|
||||
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "http://mydomain2.example");
|
||||
this.servletRequest.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
|
||||
|
@ -196,7 +185,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-16304
|
||||
public void handleInfoOptionsWithForbiddenOrigin() {
|
||||
void handleInfoOptionsWithForbiddenOrigin() {
|
||||
this.servletRequest.setServerName("mydomain3.com");
|
||||
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "https://mydomain2.example");
|
||||
this.servletRequest.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
|
||||
|
@ -212,7 +201,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test // SPR-12283
|
||||
public void handleInfoOptionsWithOriginAndCorsHeadersDisabled() {
|
||||
void handleInfoOptionsWithOriginAndCorsHeadersDisabled() {
|
||||
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "https://mydomain2.example");
|
||||
this.service.setAllowedOriginPatterns(Collections.singletonList("*"));
|
||||
this.service.setSuppressCors(true);
|
||||
|
@ -233,7 +222,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleIframeRequest() throws IOException {
|
||||
void handleIframeRequest() throws IOException {
|
||||
resetResponseAndHandleRequest("GET", "/echo/iframe.html", HttpStatus.OK);
|
||||
|
||||
assertThat(this.servletResponse.getContentType()).isEqualTo("text/html;charset=UTF-8");
|
||||
|
@ -244,23 +233,22 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleIframeRequestNotModified() {
|
||||
void handleIframeRequestNotModified() {
|
||||
this.servletRequest.addHeader("If-None-Match", "\"096aaf2482e2a85effc0ab65a61993ae0\"");
|
||||
resetResponseAndHandleRequest("GET", "/echo/iframe.html", HttpStatus.NOT_MODIFIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleRawWebSocketRequest() throws IOException {
|
||||
void handleRawWebSocketRequest() throws IOException {
|
||||
resetResponseAndHandleRequest("GET", "/echo", HttpStatus.OK);
|
||||
assertThat(this.servletResponse.getContentAsString()).isEqualTo("Welcome to SockJS!\n");
|
||||
|
||||
resetResponseAndHandleRequest("GET", "/echo/websocket", HttpStatus.OK);
|
||||
assertThat(this.service.sessionId).as("Raw WebSocket should not open a SockJS session").isNull();
|
||||
assertThat(this.service.handler).isSameAs(this.handler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleEmptyContentType() {
|
||||
void handleEmptyContentType() {
|
||||
this.servletRequest.setContentType("");
|
||||
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.OK);
|
||||
|
||||
|
@ -276,7 +264,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
private void handleRequest(String httpMethod, String uri, HttpStatus httpStatus) {
|
||||
setRequest(httpMethod, uri);
|
||||
String sockJsPath = uri.substring("/echo".length());
|
||||
this.service.handleRequest(this.request, this.response, sockJsPath, this.handler);
|
||||
this.service.handleRequest(this.request, this.response, sockJsPath, null);
|
||||
|
||||
assertThat(this.servletResponse.getStatus()).isEqualTo(httpStatus.value());
|
||||
}
|
||||
|
@ -286,27 +274,20 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
|
|||
|
||||
private String sessionId;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String transport;
|
||||
|
||||
private WebSocketHandler handler;
|
||||
|
||||
public TestSockJsService(TaskScheduler scheduler) {
|
||||
TestSockJsService(TaskScheduler scheduler) {
|
||||
super(scheduler);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRawWebSocketRequest(ServerHttpRequest req, ServerHttpResponse res,
|
||||
WebSocketHandler handler) throws IOException {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTransportRequest(ServerHttpRequest req, ServerHttpResponse res, WebSocketHandler handler,
|
||||
String sessionId, String transport) throws SockJsException {
|
||||
this.sessionId = sessionId;
|
||||
this.transport = transport;
|
||||
this.handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package org.springframework.web.socket.sockjs.transport.handler;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.web.socket.AbstractHttpRequestTests;
|
||||
|
@ -28,6 +26,7 @@ import org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSes
|
|||
import org.springframework.web.socket.sockjs.transport.session.StubSockJsServiceConfig;
|
||||
import org.springframework.web.socket.sockjs.transport.session.TestHttpSockJsSession;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
@ -37,41 +36,41 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link AbstractHttpReceivingTransportHandler} and subclasses
|
||||
* Test fixture for {@link AbstractHttpReceivingTransportHandler} and
|
||||
* {@link XhrReceivingTransportHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class HttpReceivingTransportHandlerTests extends AbstractHttpRequestTests {
|
||||
class HttpReceivingTransportHandlerTests extends AbstractHttpRequestTests {
|
||||
|
||||
@Test
|
||||
public void readMessagesXhr() throws Exception {
|
||||
this.servletRequest.setContent("[\"x\"]".getBytes(StandardCharsets.UTF_8));
|
||||
void readMessagesXhr() throws Exception {
|
||||
this.servletRequest.setContent("[\"x\"]".getBytes(UTF_8));
|
||||
handleRequest(new XhrReceivingTransportHandler());
|
||||
|
||||
assertThat(this.servletResponse.getStatus()).isEqualTo(204);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readMessagesBadContent() throws Exception {
|
||||
this.servletRequest.setContent("".getBytes(StandardCharsets.UTF_8));
|
||||
void readMessagesBadContent() throws Exception {
|
||||
this.servletRequest.setContent("".getBytes(UTF_8));
|
||||
handleRequestAndExpectFailure();
|
||||
|
||||
this.servletRequest.setContent("[\"x]".getBytes(StandardCharsets.UTF_8));
|
||||
this.servletRequest.setContent("[\"x]".getBytes(UTF_8));
|
||||
handleRequestAndExpectFailure();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readMessagesNoSession() throws Exception {
|
||||
void readMessagesNoSession() throws Exception {
|
||||
WebSocketHandler webSocketHandler = mock(WebSocketHandler.class);
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new XhrReceivingTransportHandler().handleRequest(this.request, this.response, webSocketHandler, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegateMessageException() throws Exception {
|
||||
void delegateMessageException() throws Exception {
|
||||
StubSockJsServiceConfig sockJsConfig = new StubSockJsServiceConfig();
|
||||
this.servletRequest.setContent("[\"x\"]".getBytes(StandardCharsets.UTF_8));
|
||||
this.servletRequest.setContent("[\"x\"]".getBytes(UTF_8));
|
||||
|
||||
WebSocketHandler wsHandler = mock(WebSocketHandler.class);
|
||||
TestHttpSockJsSession session = new TestHttpSockJsSession("1", sockJsConfig, wsHandler, null);
|
||||
|
|
|
@ -40,7 +40,7 @@ import static org.mockito.Mockito.verify;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests {
|
||||
class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests {
|
||||
|
||||
private WebSocketHandler webSocketHandler;
|
||||
|
||||
|
@ -51,7 +51,7 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
protected void setup() {
|
||||
super.setup();
|
||||
|
||||
this.webSocketHandler = mock(WebSocketHandler.class);
|
||||
|
@ -65,7 +65,7 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
|
||||
|
||||
@Test
|
||||
public void handleRequestXhr() throws Exception {
|
||||
void handleRequestXhr() throws Exception {
|
||||
XhrPollingTransportHandler transportHandler = new XhrPollingTransportHandler();
|
||||
transportHandler.initialize(this.sockJsConfig);
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleRequestXhrStreaming() throws Exception {
|
||||
void handleRequestXhrStreaming() throws Exception {
|
||||
XhrStreamingTransportHandler transportHandler = new XhrStreamingTransportHandler();
|
||||
transportHandler.initialize(this.sockJsConfig);
|
||||
AbstractSockJsSession session = transportHandler.createSession("1", this.webSocketHandler, null);
|
||||
|
@ -104,7 +104,7 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
}
|
||||
|
||||
@Test
|
||||
public void htmlFileTransport() throws Exception {
|
||||
void htmlFileTransport() throws Exception {
|
||||
HtmlFileTransportHandler transportHandler = new HtmlFileTransportHandler();
|
||||
transportHandler.initialize(this.sockJsConfig);
|
||||
StreamingSockJsSession session = transportHandler.createSession("1", this.webSocketHandler, null);
|
||||
|
@ -126,7 +126,7 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
}
|
||||
|
||||
@Test
|
||||
public void eventSourceTransport() throws Exception {
|
||||
void eventSourceTransport() throws Exception {
|
||||
EventSourceTransportHandler transportHandler = new EventSourceTransportHandler();
|
||||
transportHandler.initialize(this.sockJsConfig);
|
||||
StreamingSockJsSession session = transportHandler.createSession("1", this.webSocketHandler, null);
|
||||
|
@ -139,7 +139,7 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
}
|
||||
|
||||
@Test
|
||||
public void frameFormats() throws Exception {
|
||||
void frameFormats() throws Exception {
|
||||
this.servletRequest.setQueryString("c=callback");
|
||||
this.servletRequest.addParameter("c", "callback");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -29,25 +29,20 @@ import static org.mockito.Mockito.mock;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public abstract class AbstractSockJsSessionTests<S extends AbstractSockJsSession> {
|
||||
abstract class AbstractSockJsSessionTests<S extends AbstractSockJsSession> {
|
||||
|
||||
protected WebSocketHandler webSocketHandler;
|
||||
protected WebSocketHandler webSocketHandler = mock(WebSocketHandler.class);
|
||||
|
||||
protected StubSockJsServiceConfig sockJsConfig;
|
||||
protected TaskScheduler taskScheduler = mock(TaskScheduler.class);
|
||||
|
||||
protected TaskScheduler taskScheduler;
|
||||
protected StubSockJsServiceConfig sockJsConfig = new StubSockJsServiceConfig();
|
||||
|
||||
protected S session;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
this.webSocketHandler = mock(WebSocketHandler.class);
|
||||
this.taskScheduler = mock(TaskScheduler.class);
|
||||
|
||||
this.sockJsConfig = new StubSockJsServiceConfig();
|
||||
protected void setUp() {
|
||||
this.sockJsConfig.setTaskScheduler(this.taskScheduler);
|
||||
|
||||
this.session = initSockJsSession();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -44,17 +44,17 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class HttpSockJsSessionTests extends AbstractSockJsSessionTests<TestAbstractHttpSockJsSession> {
|
||||
class HttpSockJsSessionTests extends AbstractSockJsSessionTests<TestAbstractHttpSockJsSession> {
|
||||
|
||||
protected ServerHttpRequest request;
|
||||
protected MockHttpServletRequest servletRequest = new MockHttpServletRequest();
|
||||
|
||||
protected ServerHttpResponse response;
|
||||
protected MockHttpServletResponse servletResponse = new MockHttpServletResponse();
|
||||
|
||||
protected MockHttpServletRequest servletRequest;
|
||||
protected ServerHttpRequest request = new ServletServerHttpRequest(this.servletRequest);
|
||||
|
||||
protected MockHttpServletResponse servletResponse;
|
||||
protected ServerHttpResponse response = new ServletServerHttpResponse(this.servletResponse);
|
||||
|
||||
private SockJsFrameFormat frameFormat;
|
||||
private SockJsFrameFormat frameFormat = new DefaultSockJsFrameFormat("%s");
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -63,23 +63,14 @@ public class HttpSockJsSessionTests extends AbstractSockJsSessionTests<TestAbstr
|
|||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
super.setUp();
|
||||
|
||||
this.frameFormat = new DefaultSockJsFrameFormat("%s");
|
||||
|
||||
this.servletResponse = new MockHttpServletResponse();
|
||||
this.response = new ServletServerHttpResponse(this.servletResponse);
|
||||
|
||||
this.servletRequest = new MockHttpServletRequest();
|
||||
this.servletRequest.setAsyncSupported(true);
|
||||
this.request = new ServletServerHttpRequest(this.servletRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleInitialRequest() throws Exception {
|
||||
|
||||
void handleInitialRequest() throws Exception {
|
||||
this.session.handleInitialRequest(this.request, this.response, this.frameFormat);
|
||||
|
||||
assertThat(this.servletResponse.getContentAsString()).isEqualTo("hhh\no");
|
||||
|
@ -89,8 +80,7 @@ public class HttpSockJsSessionTests extends AbstractSockJsSessionTests<TestAbstr
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleSuccessiveRequest() throws Exception {
|
||||
|
||||
void handleSuccessiveRequest() throws Exception {
|
||||
this.session.getMessageCache().add("x");
|
||||
this.session.handleSuccessiveRequest(this.request, this.response, this.frameFormat);
|
||||
|
||||
|
@ -112,7 +102,7 @@ public class HttpSockJsSessionTests extends AbstractSockJsSessionTests<TestAbstr
|
|||
private boolean heartbeatScheduled;
|
||||
|
||||
|
||||
public TestAbstractHttpSockJsSession(SockJsServiceConfig config, WebSocketHandler handler,
|
||||
TestAbstractHttpSockJsSession(SockJsServiceConfig config, WebSocketHandler handler,
|
||||
Map<String, Object> attributes) {
|
||||
|
||||
super("1", config, handler, attributes);
|
||||
|
@ -123,15 +113,15 @@ public class HttpSockJsSessionTests extends AbstractSockJsSessionTests<TestAbstr
|
|||
return "hhh\n".getBytes();
|
||||
}
|
||||
|
||||
public boolean wasCacheFlushed() {
|
||||
boolean wasCacheFlushed() {
|
||||
return this.cacheFlushed;
|
||||
}
|
||||
|
||||
public boolean wasHeartbeatScheduled() {
|
||||
boolean wasHeartbeatScheduled() {
|
||||
return this.heartbeatScheduled;
|
||||
}
|
||||
|
||||
public void setExceptionOnWriteFrame(IOException exceptionOnWriteFrame) {
|
||||
void setExceptionOnWriteFrame(IOException exceptionOnWriteFrame) {
|
||||
this.exceptionOnWriteFrame = exceptionOnWriteFrame;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSession> {
|
||||
|
||||
class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSession> {
|
||||
|
||||
@Override
|
||||
protected TestSockJsSession initSockJsSession() {
|
||||
|
@ -54,7 +53,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
|
||||
|
||||
@Test
|
||||
public void getTimeSinceLastActive() throws Exception {
|
||||
void getTimeSinceLastActive() throws Exception {
|
||||
Thread.sleep(1);
|
||||
|
||||
long time1 = this.session.getTimeSinceLastActive();
|
||||
|
@ -77,7 +76,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void delegateConnectionEstablished() throws Exception {
|
||||
void delegateConnectionEstablished() throws Exception {
|
||||
assertNew();
|
||||
this.session.delegateConnectionEstablished();
|
||||
assertOpen();
|
||||
|
@ -85,15 +84,14 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void delegateError() throws Exception {
|
||||
void delegateError() throws Exception {
|
||||
Exception ex = new Exception();
|
||||
this.session.delegateError(ex);
|
||||
verify(this.webSocketHandler).handleTransportError(this.session, ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegateMessages() throws Exception {
|
||||
|
||||
void delegateMessages() throws Exception {
|
||||
String msg1 = "message 1";
|
||||
String msg2 = "message 2";
|
||||
|
||||
|
@ -105,8 +103,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void delegateMessagesWithError() throws Exception {
|
||||
|
||||
void delegateMessagesWithError() throws Exception {
|
||||
TestSockJsSession session = new TestSockJsSession("1", this.sockJsConfig,
|
||||
new ExceptionWebSocketHandlerDecorator(this.webSocketHandler), Collections.emptyMap());
|
||||
|
||||
|
@ -127,8 +124,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test // gh-23828
|
||||
public void delegateMessagesEmptyAfterConnectionClosed() throws Exception {
|
||||
|
||||
void delegateMessagesEmptyAfterConnectionClosed() throws Exception {
|
||||
TestSockJsSession session = new TestSockJsSession("1", this.sockJsConfig,
|
||||
new ExceptionWebSocketHandlerDecorator(this.webSocketHandler), Collections.emptyMap());
|
||||
|
||||
|
@ -144,7 +140,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void delegateConnectionClosed() throws Exception {
|
||||
void delegateConnectionClosed() throws Exception {
|
||||
this.session.delegateConnectionEstablished();
|
||||
this.session.delegateConnectionClosed(CloseStatus.GOING_AWAY);
|
||||
|
||||
|
@ -154,7 +150,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void closeWhenNotOpen() throws Exception {
|
||||
void closeWhenNotOpen() throws Exception {
|
||||
assertNew();
|
||||
|
||||
this.session.close();
|
||||
|
@ -172,7 +168,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void closeWhenNotActive() throws Exception {
|
||||
void closeWhenNotActive() throws Exception {
|
||||
this.session.delegateConnectionEstablished();
|
||||
assertOpen();
|
||||
|
||||
|
@ -183,7 +179,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void close() throws Exception {
|
||||
void close() throws Exception {
|
||||
this.session.delegateConnectionEstablished();
|
||||
assertOpen();
|
||||
|
||||
|
@ -202,7 +198,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void closeWithWriteFrameExceptions() throws Exception {
|
||||
void closeWithWriteFrameExceptions() throws Exception {
|
||||
this.session.setExceptionOnWrite(new IOException());
|
||||
|
||||
this.session.delegateConnectionEstablished();
|
||||
|
@ -214,7 +210,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void closeWithWebSocketHandlerExceptions() throws Exception {
|
||||
void closeWithWebSocketHandlerExceptions() throws Exception {
|
||||
willThrow(new Exception()).given(this.webSocketHandler).afterConnectionClosed(this.session, CloseStatus.NORMAL);
|
||||
|
||||
this.session.delegateConnectionEstablished();
|
||||
|
@ -226,7 +222,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void tryCloseWithWebSocketHandlerExceptions() throws Exception {
|
||||
void tryCloseWithWebSocketHandlerExceptions() throws Exception {
|
||||
this.session.delegateConnectionEstablished();
|
||||
this.session.setActive(true);
|
||||
this.session.tryCloseWithSockJsTransportError(new Exception(), CloseStatus.BAD_DATA);
|
||||
|
@ -236,7 +232,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void writeFrame() {
|
||||
void writeFrame() {
|
||||
this.session.writeFrame(SockJsFrame.openFrame());
|
||||
|
||||
assertThat(this.session.getSockJsFramesWritten().size()).isEqualTo(1);
|
||||
|
@ -244,7 +240,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void writeFrameIoException() throws Exception {
|
||||
void writeFrameIoException() throws Exception {
|
||||
this.session.setExceptionOnWrite(new IOException());
|
||||
this.session.delegateConnectionEstablished();
|
||||
|
||||
|
@ -255,7 +251,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void sendHeartbeat() {
|
||||
void sendHeartbeat() {
|
||||
this.session.setActive(true);
|
||||
this.session.sendHeartbeat();
|
||||
|
||||
|
@ -267,7 +263,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void scheduleHeartbeatNotActive() {
|
||||
void scheduleHeartbeatNotActive() {
|
||||
this.session.setActive(false);
|
||||
this.session.scheduleHeartbeat();
|
||||
|
||||
|
@ -275,7 +271,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void sendHeartbeatWhenDisabled() {
|
||||
void sendHeartbeatWhenDisabled() {
|
||||
this.session.disableHeartbeat();
|
||||
this.session.setActive(true);
|
||||
this.session.sendHeartbeat();
|
||||
|
@ -284,7 +280,7 @@ public class SockJsSessionTests extends AbstractSockJsSessionTests<TestSockJsSes
|
|||
}
|
||||
|
||||
@Test
|
||||
public void scheduleAndCancelHeartbeat() {
|
||||
void scheduleAndCancelHeartbeat() {
|
||||
ScheduledFuture<?> task = mock(ScheduledFuture.class);
|
||||
willReturn(task).given(this.taskScheduler).schedule(any(Runnable.class), any(Instant.class));
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -18,8 +18,6 @@ package org.springframework.web.socket.sockjs.transport.session;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -46,13 +44,14 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTests<TestWebSocketServerSockJsSession> {
|
||||
class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTests<TestWebSocketServerSockJsSession> {
|
||||
|
||||
private TestWebSocketSession webSocketSession;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
@Override
|
||||
protected void setUp() {
|
||||
super.setUp();
|
||||
this.webSocketSession = new TestWebSocketSession();
|
||||
this.webSocketSession.setOpen(true);
|
||||
|
@ -60,12 +59,12 @@ public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTest
|
|||
|
||||
@Override
|
||||
protected TestWebSocketServerSockJsSession initSockJsSession() {
|
||||
return new TestWebSocketServerSockJsSession(this.sockJsConfig, this.webSocketHandler,
|
||||
Collections.<String, Object>emptyMap());
|
||||
return new TestWebSocketServerSockJsSession(this.sockJsConfig, this.webSocketHandler, Map.of());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void isActive() throws Exception {
|
||||
void isActive() throws Exception {
|
||||
assertThat(this.session.isActive()).isFalse();
|
||||
|
||||
this.session.initializeDelegateSession(this.webSocketSession);
|
||||
|
@ -76,17 +75,17 @@ public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void afterSessionInitialized() throws Exception {
|
||||
void afterSessionInitialized() throws Exception {
|
||||
this.session.initializeDelegateSession(this.webSocketSession);
|
||||
assertThat(this.webSocketSession.getSentMessages()).isEqualTo(Collections.singletonList(new TextMessage("o")));
|
||||
assertThat(this.session.heartbeatSchedulingEvents).isEqualTo(List.of("schedule"));
|
||||
assertThat(this.webSocketSession.getSentMessages()).containsExactly(new TextMessage("o"));
|
||||
assertThat(this.session.heartbeatSchedulingEvents).containsExactly("schedule");
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(this.session);
|
||||
verifyNoMoreInteractions(this.taskScheduler, this.webSocketHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void afterSessionInitializedOpenFrameFirst() throws Exception {
|
||||
void afterSessionInitializedOpenFrameFirst() throws Exception {
|
||||
TextWebSocketHandler handler = new TextWebSocketHandler() {
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
|
@ -95,19 +94,17 @@ public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTest
|
|||
};
|
||||
TestWebSocketServerSockJsSession session = new TestWebSocketServerSockJsSession(this.sockJsConfig, handler, null);
|
||||
session.initializeDelegateSession(this.webSocketSession);
|
||||
List<TextMessage> expected = Arrays.asList(new TextMessage("o"), new TextMessage("a[\"go go\"]"));
|
||||
assertThat(this.webSocketSession.getSentMessages()).isEqualTo(expected);
|
||||
assertThat(this.webSocketSession.getSentMessages()).containsExactly(new TextMessage("o"), new TextMessage("a[\"go go\"]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageEmptyPayload() throws Exception {
|
||||
void handleMessageEmptyPayload() throws Exception {
|
||||
this.session.handleMessage(new TextMessage(""), this.webSocketSession);
|
||||
verifyNoMoreInteractions(this.webSocketHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessage() throws Exception {
|
||||
|
||||
void handleMessage() throws Exception {
|
||||
TextMessage message = new TextMessage("[\"x\"]");
|
||||
this.session.handleMessage(message, this.webSocketSession);
|
||||
|
||||
|
@ -116,7 +113,7 @@ public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageBadData() throws Exception {
|
||||
void handleMessageBadData() throws Exception {
|
||||
TextMessage message = new TextMessage("[\"x]");
|
||||
this.session.handleMessage(message, this.webSocketSession);
|
||||
|
||||
|
@ -126,19 +123,16 @@ public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void sendMessageInternal() throws Exception {
|
||||
|
||||
void sendMessageInternal() throws Exception {
|
||||
this.session.initializeDelegateSession(this.webSocketSession);
|
||||
this.session.sendMessageInternal("x");
|
||||
|
||||
assertThat(this.webSocketSession.getSentMessages()).isEqualTo(Arrays.asList(new TextMessage("o"), new TextMessage("a[\"x\"]")));
|
||||
|
||||
assertThat(this.session.heartbeatSchedulingEvents).isEqualTo(Arrays.asList("schedule", "cancel", "schedule"));
|
||||
assertThat(this.webSocketSession.getSentMessages()).containsExactly(new TextMessage("o"), new TextMessage("a[\"x\"]"));
|
||||
assertThat(this.session.heartbeatSchedulingEvents).containsExactly("schedule", "cancel", "schedule");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disconnect() throws Exception {
|
||||
|
||||
void disconnect() throws Exception {
|
||||
this.session.initializeDelegateSession(this.webSocketSession);
|
||||
this.session.close(CloseStatus.NOT_ACCEPTABLE);
|
||||
|
||||
|
@ -150,7 +144,7 @@ public class WebSocketServerSockJsSessionTests extends AbstractSockJsSessionTest
|
|||
|
||||
private final List<String> heartbeatSchedulingEvents = new ArrayList<>();
|
||||
|
||||
public TestWebSocketServerSockJsSession(SockJsServiceConfig config, WebSocketHandler handler,
|
||||
TestWebSocketServerSockJsSession(SockJsServiceConfig config, WebSocketHandler handler,
|
||||
Map<String, Object> attributes) {
|
||||
|
||||
super("1", config, handler, attributes);
|
||||
|
|
Loading…
Reference in New Issue