From b6fdcffc94a17ec30e5a9d24d7e62e2a54b928ca Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 20 Oct 2014 23:32:46 +0200 Subject: [PATCH] HttpSessionHandshakeInterceptor and related web.socket.server polishing Issue: SPR-12352 --- .../server/HandshakeFailureException.java | 18 ++---- .../web/socket/server/HandshakeHandler.java | 8 +-- .../socket/server/HandshakeInterceptor.java | 10 +-- .../socket/server/RequestUpgradeStrategy.java | 11 ++-- .../jetty/JettyRequestUpgradeStrategy.java | 4 +- .../web/socket/server/jetty/package-info.java | 19 +----- .../web/socket/server/package-info.java | 17 ----- .../AbstractStandardUpgradeStrategy.java | 10 +-- .../AbstractTyrusRequestUpgradeStrategy.java | 62 ++++++++++--------- .../GlassFishRequestUpgradeStrategy.java | 19 +++--- .../standard/ServerEndpointRegistration.java | 2 +- .../server/standard/SpringConfigurator.java | 5 +- .../TomcatRequestUpgradeStrategy.java | 20 +++--- .../UndertowRequestUpgradeStrategy.java | 13 ++-- .../WebLogicRequestUpgradeStrategy.java | 39 ++++++------ .../socket/server/standard/package-info.java | 19 +----- .../support/DefaultHandshakeHandler.java | 46 +++++++------- .../support/HandshakeInterceptorChain.java | 12 ++-- .../HttpSessionHandshakeInterceptor.java | 11 ++-- .../support/WebSocketHttpRequestHandler.java | 27 ++++---- .../socket/server/support/package-info.java | 21 +------ 21 files changed, 158 insertions(+), 235 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeFailureException.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeFailureException.java index f470229893e..a87d88fd2d4 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeFailureException.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeFailureException.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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 + * 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, @@ -34,18 +34,12 @@ import org.springframework.core.NestedRuntimeException; @SuppressWarnings("serial") public class HandshakeFailureException extends NestedRuntimeException { - /** - * Constructor with message and root cause. - */ - public HandshakeFailureException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructor without a message. - */ public HandshakeFailureException(String message) { super(message); } + public HandshakeFailureException(String message, Throwable cause) { + super(message, cause); + } + } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeHandler.java index 7660673edf9..0f0c23c40ea 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeHandler.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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 + * 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, @@ -28,7 +28,6 @@ import org.springframework.web.socket.handler.PerConnectionWebSocketHandler; * * @author Rossen Stoyanchev * @since 4.0 - * * @see HandshakeInterceptor * @see org.springframework.web.socket.server.support.WebSocketHttpRequestHandler * @see org.springframework.web.socket.sockjs.SockJsService @@ -37,7 +36,6 @@ public interface HandshakeHandler { /** * Initiate the handshake. - * * @param request the current request * @param response the current response * @param wsHandler the handler to process WebSocket messages; see @@ -45,11 +43,9 @@ public interface HandshakeHandler { * per-connection lifecycle. * @param attributes attributes from the HTTP handshake to associate with the WebSocket * session; the provided attributes are copied, the original map is not used. - * * @return whether the handshake negotiation was successful or not. In either case the * response status, headers, and body will have been updated to reflect the * result of the negotiation - * * @throws HandshakeFailureException thrown when handshake processing failed to * complete due to an internal, unrecoverable error, i.e. a server error as * opposed to a failure to successfully negotiate the handshake. diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeInterceptor.java index a3575a052d7..72825402892 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/HandshakeInterceptor.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -41,18 +41,18 @@ public interface HandshakeInterceptor { * @param wsHandler the target WebSocket handler * @param attributes attributes from the HTTP handshake to associate with the WebSocket * session; the provided attributes are copied, the original map is not used. - * @return whether to proceed with the handshake {@code true} or abort {@code false} + * @return whether to proceed with the handshake ({@code true}) or abort ({@code false}) */ boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception; /** - * Invoked after the handshake is done. The response status and headers indicate the - * results of the handshake, i.e. whether it was successful or not. + * Invoked after the handshake is done. The response status and headers indicate + * the results of the handshake, i.e. whether it was successful or not. * @param request the current request * @param response the current response * @param wsHandler the target WebSocket handler - * @param exception an exception raised during the handshake, or {@code null} + * @param exception an exception raised during the handshake, or {@code null} if none */ void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/RequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/RequestUpgradeStrategy.java index d7553e18736..4d05f1eb72a 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/RequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/RequestUpgradeStrategy.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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 + * 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, @@ -39,7 +39,7 @@ public interface RequestUpgradeStrategy { String[] getSupportedVersions(); /** - * @return the WebSocket protocol extensions supported by the underlying WebSocket server. + * Return the WebSocket protocol extensions supported by the underlying WebSocket server. */ List getSupportedExtensions(ServerHttpRequest request); @@ -53,9 +53,8 @@ public interface RequestUpgradeStrategy { * @param user the user to associate with the WebSocket session * @param wsHandler the handler for WebSocket messages * @param attributes handshake request specific attributes to be set on the WebSocket - * session via {@link org.springframework.web.socket.server.HandshakeInterceptor} - * and thus made available to the - * {@link org.springframework.web.socket.WebSocketHandler}; + * session via {@link org.springframework.web.socket.server.HandshakeInterceptor} and + * thus made available to the {@link org.springframework.web.socket.WebSocketHandler} * @throws HandshakeFailureException thrown when handshake processing failed to * complete due to an internal, unrecoverable error, i.e. a server error as * opposed to a failure to successfully negotiate the requirements of the diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java index 714b2957e88..9bb42fd03d0 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -63,7 +63,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { new NamedThreadLocal("WebSocket Handler Container"); - private WebSocketServerFactory factory; + private final WebSocketServerFactory factory; private volatile List supportedExtensions; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/package-info.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/package-info.java index 892998ce30a..2a3627773a1 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/package-info.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/package-info.java @@ -1,21 +1,4 @@ -/* - * Copyright 2002-2013 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. - */ - /** - * Server-side support for the Jetty WebSocket API. + * Server-side support for the Jetty 9+ WebSocket API. */ package org.springframework.web.socket.server.jetty; - diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/package-info.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/package-info.java index 1ec1f9a532e..c3b8df4a892 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/package-info.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/package-info.java @@ -1,21 +1,4 @@ -/* - * Copyright 2002-2013 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. - */ - /** * Server-side abstractions for WebSocket interactions. */ package org.springframework.web.socket.server; - diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java index 7f1115d4638..7ca2f7ac185 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractStandardUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -112,15 +112,15 @@ public abstract class AbstractStandardUpgradeStrategy implements RequestUpgradeS StandardWebSocketHandlerAdapter endpoint = new StandardWebSocketHandlerAdapter(wsHandler, session); List extensions = new ArrayList(); - for (WebSocketExtension e : selectedExtensions) { - extensions.add(new WebSocketToStandardExtensionAdapter(e)); + for (WebSocketExtension extension : selectedExtensions) { + extensions.add(new WebSocketToStandardExtensionAdapter(extension)); } upgradeInternal(request, response, selectedProtocol, extensions, endpoint); } protected abstract void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response, - String selectedProtocol, List selectedExtensions, - Endpoint endpoint) throws HandshakeFailureException; + String selectedProtocol, List selectedExtensions, Endpoint endpoint) + throws HandshakeFailureException; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java index 56a51a19319..9a871e3dded 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/AbstractTyrusRequestUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -16,6 +16,23 @@ package org.springframework.web.socket.server.standard; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.websocket.DeploymentException; +import javax.websocket.Endpoint; +import javax.websocket.EndpointConfig; +import javax.websocket.Extension; +import javax.websocket.WebSocketContainer; + import org.glassfish.tyrus.core.ComponentProviderService; import org.glassfish.tyrus.core.RequestContext; import org.glassfish.tyrus.core.TyrusEndpoint; @@ -26,6 +43,7 @@ import org.glassfish.tyrus.core.Version; import org.glassfish.tyrus.core.WebSocketApplication; import org.glassfish.tyrus.server.TyrusServerContainer; import org.glassfish.tyrus.spi.WebSocketEngine.UpgradeInfo; + import org.springframework.beans.DirectFieldAccessor; import org.springframework.http.HttpHeaders; import org.springframework.http.server.ServerHttpRequest; @@ -35,23 +53,6 @@ import org.springframework.util.StringUtils; import org.springframework.web.socket.WebSocketExtension; import org.springframework.web.socket.server.HandshakeFailureException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.DeploymentException; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.Extension; -import javax.websocket.WebSocketContainer; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; - /** * An base class for WebSocket servers using Tyrus. * @@ -65,7 +66,6 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda private static final Random random = new Random(); - private final ComponentProviderService componentProvider = ComponentProviderService.create(); @@ -78,17 +78,15 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda try { return super.getInstalledExtensions(container); } - catch (UnsupportedOperationException e) { - return new ArrayList(); + catch (UnsupportedOperationException ex) { + return new ArrayList(0); } } - protected abstract TyrusEndpointHelper getEndpointHelper(); - - @Override public void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response, - String subProtocol, List extensions, Endpoint endpoint) throws HandshakeFailureException { + String selectedProtocol, List extensions, Endpoint endpoint) + throws HandshakeFailureException { HttpServletRequest servletRequest = getHttpServletRequest(request); HttpServletResponse servletResponse = getHttpServletResponse(response); @@ -100,7 +98,7 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda try { // Shouldn't matter for processing but must be unique String path = "/" + random.nextLong(); - tyrusEndpoint = createTyrusEndpoint(endpoint, path, subProtocol, extensions, serverContainer, engine); + tyrusEndpoint = createTyrusEndpoint(endpoint, path, selectedProtocol, extensions, serverContainer, engine); getEndpointHelper().register(engine, tyrusEndpoint); HttpHeaders headers = request.getHeaders(); @@ -133,9 +131,6 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda } } - protected abstract void handleSuccess(HttpServletRequest request, HttpServletResponse response, - UpgradeInfo upgradeInfo, TyrusUpgradeResponse upgradeResponse) throws IOException, ServletException; - private Object createTyrusEndpoint(Endpoint endpoint, String endpointPath, String protocol, List extensions, WebSocketContainer container, TyrusWebSocketEngine engine) throws DeploymentException { @@ -161,6 +156,12 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda } + protected abstract TyrusEndpointHelper getEndpointHelper(); + + protected abstract void handleSuccess(HttpServletRequest request, HttpServletResponse response, + UpgradeInfo upgradeInfo, TyrusUpgradeResponse upgradeResponse) throws IOException, ServletException; + + /** * Helps with the creation, registration, and un-registration of endpoints. */ @@ -172,9 +173,9 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda void register(TyrusWebSocketEngine engine, Object endpoint); void unregister(TyrusWebSocketEngine engine, Object endpoint); - } + protected static class Tyrus17EndpointHelper implements TyrusEndpointHelper { private static final Constructor constructor; @@ -243,6 +244,7 @@ public abstract class AbstractTyrusRequestUpgradeStrategy extends AbstractStanda } } + protected static class Tyrus135EndpointHelper implements TyrusEndpointHelper { private static final Method registerMethod; diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java index 651692da159..a37abe304f8 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/GlassFishRequestUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -16,22 +16,23 @@ package org.springframework.web.socket.server.standard; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.List; +import java.util.Map; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.glassfish.tyrus.core.TyrusUpgradeResponse; import org.glassfish.tyrus.core.Utils; import org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler; import org.glassfish.tyrus.spi.WebSocketEngine.UpgradeInfo; import org.glassfish.tyrus.spi.Writer; + import org.springframework.util.ReflectionUtils; import org.springframework.web.socket.server.HandshakeFailureException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.util.List; -import java.util.Map; - /** * A WebSocket {@code RequestUpgradeStrategy} for GlassFish 4.0.1 and beyond. * diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java index f20993d9d8d..5e066de54e7 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServerEndpointRegistration.java @@ -5,7 +5,7 @@ * 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 + * 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, diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java index 31a54287e0b..1bd00abe229 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/SpringConfigurator.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -16,6 +16,7 @@ package org.springframework.web.socket.server.standard; +import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.websocket.server.ServerEndpoint; @@ -114,7 +115,7 @@ public class SpringConfigurator extends Configurator { beanNamesByType.put(endpointClass, NO_VALUE); if (names.length > 1) { throw new IllegalStateException("Found multiple @ServerEndpoint's of type [" + - endpointClass.getName() + "]: bean names " + names); + endpointClass.getName() + "]: bean names " + Arrays.asList(names)); } } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java index 95358efcf0b..a99995ac69f 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -34,11 +34,10 @@ import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.server.HandshakeFailureException; /** - * Tomcat support for upgrading an {@link HttpServletRequest} during a WebSocket - * handshake. To modify properties of the underlying - * {@link javax.websocket.server.ServerContainer} you can use - * {@link ServletServerContainerFactoryBean} in XML configuration or if using Java - * configuration, access the container instance through the + * Tomcat support for upgrading an {@link HttpServletRequest} during a WebSocket handshake. + * To modify properties of the underlying {@link javax.websocket.server.ServerContainer} + * you can use {@link ServletServerContainerFactoryBean} in XML configuration or, + * when using Java configuration, access the container instance through the * "javax.websocket.server.ServerContainer" ServletContext attribute. * * @author Rossen Stoyanchev @@ -46,16 +45,15 @@ import org.springframework.web.socket.server.HandshakeFailureException; */ public class TomcatRequestUpgradeStrategy extends AbstractStandardUpgradeStrategy { - @Override public String[] getSupportedVersions() { - return new String[] { "13" }; + return new String[] {"13"}; } @Override public void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response, - String selectedProtocol, List selectedExtensions, - Endpoint endpoint) throws HandshakeFailureException { + String selectedProtocol, List selectedExtensions, Endpoint endpoint) + throws HandshakeFailureException { HttpServletRequest servletRequest = getHttpServletRequest(request); HttpServletResponse servletResponse = getHttpServletResponse(response); @@ -85,4 +83,4 @@ public class TomcatRequestUpgradeStrategy extends AbstractStandardUpgradeStrateg return (WsServerContainer) super.getContainer(request); } -} \ No newline at end of file +} diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java index 57fc9c38673..5a38b9e988b 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -45,11 +45,11 @@ import io.undertow.websockets.jsr.handshake.HandshakeUtil; import io.undertow.websockets.jsr.handshake.JsrHybi07Handshake; import io.undertow.websockets.jsr.handshake.JsrHybi08Handshake; import io.undertow.websockets.jsr.handshake.JsrHybi13Handshake; -import org.springframework.util.ClassUtils; import org.xnio.StreamConnection; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; +import org.springframework.util.ClassUtils; import org.springframework.web.socket.server.HandshakeFailureException; @@ -87,7 +87,7 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat }; - private Set peerConnections; + private final Set peerConnections; public UndertowRequestUpgradeStrategy() { @@ -106,8 +106,9 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat } @Override - protected void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response, String selectedProtocol, - List selectedExtensions, final Endpoint endpoint) throws HandshakeFailureException { + protected void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response, + String selectedProtocol, List selectedExtensions, final Endpoint endpoint) + throws HandshakeFailureException { HttpServletRequest servletRequest = getHttpServletRequest(request); HttpServletResponse servletResponse = getHttpServletResponse(response); @@ -168,7 +169,7 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat private ConfiguredServerEndpoint createConfiguredServerEndpoint(String selectedProtocol, List selectedExtensions, Endpoint endpoint, HttpServletRequest servletRequest) { - String path = servletRequest.getRequestURI(); // shouldn't matter + String path = servletRequest.getRequestURI(); // shouldn't matter ServerEndpointRegistration endpointRegistration = new ServerEndpointRegistration(path, endpoint); endpointRegistration.setSubprotocols(Arrays.asList(selectedProtocol)); endpointRegistration.setExtensions(selectedExtensions); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java index c7ff8038fc3..b52e5c66e05 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/WebLogicRequestUpgradeStrategy.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -16,30 +16,31 @@ package org.springframework.web.socket.server.standard; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import javax.servlet.AsyncContext; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletRequestWrapper; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.websocket.CloseReason; + import org.glassfish.tyrus.core.TyrusUpgradeResponse; import org.glassfish.tyrus.core.Utils; import org.glassfish.tyrus.spi.Connection; import org.glassfish.tyrus.spi.WebSocketEngine.UpgradeInfo; import org.glassfish.tyrus.spi.Writer; + import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import org.springframework.util.ReflectionUtils; import org.springframework.web.socket.server.HandshakeFailureException; -import javax.servlet.AsyncContext; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.websocket.CloseReason; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; - /** * A WebSocket {@code RequestUpgradeStrategy} for WebLogic 12.1.3. * @@ -60,7 +61,6 @@ public class WebLogicRequestUpgradeStrategy extends AbstractTyrusRequestUpgradeS return endpointHelper; } - @Override protected void handleSuccess(HttpServletRequest request, HttpServletResponse response, UpgradeInfo upgradeInfo, TyrusUpgradeResponse upgradeResponse) throws IOException, ServletException { @@ -90,7 +90,7 @@ public class WebLogicRequestUpgradeStrategy extends AbstractTyrusRequestUpgradeS } private static Object getNativeRequest(ServletRequest request) { - while ((request instanceof ServletRequestWrapper)) { + while (request instanceof ServletRequestWrapper) { request = ((ServletRequestWrapper) request).getRequest(); } return request; @@ -104,6 +104,7 @@ public class WebLogicRequestUpgradeStrategy extends AbstractTyrusRequestUpgradeS } }; + /** * Helps to create and invoke {@code weblogic.servlet.internal.MuxableSocketHTTP}. */ @@ -156,11 +157,12 @@ public class WebLogicRequestUpgradeStrategy extends AbstractTyrusRequestUpgradeS webSocketReadEventMethod.invoke(webSocket); } catch (Exception ex) { - throw new HandshakeFailureException("Failed to register WebSocket for read event.", ex); + throw new HandshakeFailureException("Failed to register WebSocket for read event", ex); } } } + /** * Helps to create and invoke {@code weblogic.websocket.tyrus.TyrusServletWriter}. */ @@ -183,7 +185,6 @@ public class WebLogicRequestUpgradeStrategy extends AbstractTyrusRequestUpgradeS } } - private Writer newInstance(HttpServletResponse response, Object webSocket, boolean isProtected) { try { return (Writer) constructor.newInstance(webSocket, response, null, isProtected); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/package-info.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/package-info.java index a015a6eaa4f..a7e557c3483 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/package-info.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/package-info.java @@ -1,21 +1,4 @@ -/* - * Copyright 2002-2013 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. - */ - /** - * Server-side classes for use with standard Java WebSocket endpoints. + * Server-side classes for use with standard JSR-356 WebSocket endpoints. */ package org.springframework.web.socket.server.standard; - diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java index 62457fe2342..8a022dec9f0 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/DefaultHandshakeHandler.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -60,8 +60,6 @@ import org.springframework.web.socket.server.RequestUpgradeStrategy; */ public class DefaultHandshakeHandler implements HandshakeHandler { - protected Log logger = LogFactory.getLog(getClass()); - private static final boolean jettyWsPresent = ClassUtils.isPresent( "org.eclipse.jetty.websocket.server.WebSocketServerFactory", DefaultHandshakeHandler.class.getClassLoader()); @@ -78,6 +76,8 @@ public class DefaultHandshakeHandler implements HandshakeHandler { "weblogic.websocket.tyrus.TyrusServletWriter", DefaultHandshakeHandler.class.getClassLoader()); + protected final Log logger = LogFactory.getLog(getClass()); + private final RequestUpgradeStrategy requestUpgradeStrategy; private final List supportedProtocols = new ArrayList(); @@ -92,6 +92,16 @@ public class DefaultHandshakeHandler implements HandshakeHandler { this(initRequestUpgradeStrategy()); } + /** + * A constructor that accepts a runtime-specific {@link RequestUpgradeStrategy}. + * @param requestUpgradeStrategy the upgrade strategy to use + */ + public DefaultHandshakeHandler(RequestUpgradeStrategy requestUpgradeStrategy) { + Assert.notNull(requestUpgradeStrategy, "RequestUpgradeStrategy must not be null"); + this.requestUpgradeStrategy = requestUpgradeStrategy; + } + + private static RequestUpgradeStrategy initRequestUpgradeStrategy() { String className; if (jettyWsPresent) { @@ -121,15 +131,6 @@ public class DefaultHandshakeHandler implements HandshakeHandler { } } - /** - * A constructor that accepts a runtime-specific {@link RequestUpgradeStrategy}. - * @param requestUpgradeStrategy the upgrade strategy to use - */ - public DefaultHandshakeHandler(RequestUpgradeStrategy requestUpgradeStrategy) { - Assert.notNull(requestUpgradeStrategy, "RequestUpgradeStrategy must not be null"); - this.requestUpgradeStrategy = requestUpgradeStrategy; - } - /** * Use this property to configure the list of supported sub-protocols. @@ -290,18 +291,18 @@ public class DefaultHandshakeHandler implements HandshakeHandler { } /** - * Determine the sub-protocols supported by the given WebSocketHandler by checking - * whether it is an instance of {@link SubProtocolCapable}. + * Determine the sub-protocols supported by the given WebSocketHandler by + * checking whether it is an instance of {@link SubProtocolCapable}. * @param handler the handler to check - * @return a list of supported protocols or an empty list + * @return a list of supported protocols, or an empty list if none available */ protected final List determineHandlerSupportedProtocols(WebSocketHandler handler) { - handler = WebSocketHandlerDecorator.unwrap(handler); + WebSocketHandler handlerToCheck = WebSocketHandlerDecorator.unwrap(handler); List subProtocols = null; - if (handler instanceof SubProtocolCapable) { - subProtocols = ((SubProtocolCapable) handler).getSubProtocols(); + if (handlerToCheck instanceof SubProtocolCapable) { + subProtocols = ((SubProtocolCapable) handlerToCheck).getSubProtocols(); } - return (subProtocols != null) ? subProtocols : Collections.emptyList(); + return (subProtocols != null ? subProtocols : Collections.emptyList()); } /** @@ -329,16 +330,13 @@ public class DefaultHandshakeHandler implements HandshakeHandler { * A method that can be used to associate a user with the WebSocket session * in the process of being established. The default implementation calls * {@link org.springframework.http.server.ServerHttpRequest#getPrincipal()} - *

- * Sub-classes can provide custom logic for associating a user with a session, + *

Subclasses can provide custom logic for associating a user with a session, * for example for assigning a name to anonymous users (i.e. not fully * authenticated). - * * @param request the handshake request * @param wsHandler the WebSocket handler that will handle messages * @param attributes handshake attributes to pass to the WebSocket session - * - * @return the user for the WebSocket session or {@code null} + * @return the user for the WebSocket session, or {@code null} if not available */ protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map attributes) { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HandshakeInterceptorChain.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HandshakeInterceptorChain.java index dc26caba136..3ffd4f7f2b6 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HandshakeInterceptorChain.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HandshakeInterceptorChain.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -46,7 +46,7 @@ public class HandshakeInterceptorChain { public HandshakeInterceptorChain(List interceptors, WebSocketHandler wsHandler) { - this.interceptors = (interceptors != null) ? interceptors : Collections.emptyList(); + this.interceptors = (interceptors != null ? interceptors : Collections.emptyList()); this.wsHandler = wsHandler; } @@ -58,7 +58,7 @@ public class HandshakeInterceptorChain { HandshakeInterceptor interceptor = this.interceptors.get(i); if (!interceptor.beforeHandshake(request, response, this.wsHandler, attributes)) { if (logger.isDebugEnabled()) { - logger.debug(interceptor + " return false precluding handshake."); + logger.debug(interceptor + " returns false from beforeHandshake - precluding handshake"); } applyAfterHandshake(request, response, null); return false; @@ -75,8 +75,10 @@ public class HandshakeInterceptorChain { try { interceptor.afterHandshake(request, response, this.wsHandler, failure); } - catch (Throwable t) { - logger.warn("HandshakeInterceptor afterHandshake threw exception " + t); + catch (Throwable ex) { + if (logger.isWarnEnabled()) { + logger.warn(interceptor + " threw exception in afterHandshake: " + ex); + } } } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java index a76bdbcda23..ba7de0c02df 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -25,7 +25,6 @@ import javax.servlet.http.HttpSession; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.util.CollectionUtils; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.server.HandshakeInterceptor; @@ -88,8 +87,8 @@ public class HttpSessionHandshakeInterceptor implements HandshakeInterceptor { } /** - * Whether to copy all attributes from the HTTP session. If set to "true" any - * explicitly configured attribute names are ignored. + * Whether to copy all attributes from the HTTP session. If set to "true", + * any explicitly configured attribute names are ignored. *

By default this is set to either "true" or "false" depending on which * constructor was used (default or with attribute names respectively). * @param copyAllAttributes whether to copy all attributes @@ -145,8 +144,8 @@ public class HttpSessionHandshakeInterceptor implements HandshakeInterceptor { private HttpSession getSession(ServerHttpRequest request) { if (request instanceof ServletServerHttpRequest) { - ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; - return servletRequest.getServletRequest().getSession(false); + ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request; + return serverRequest.getServletRequest().getSession(false); } return null; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java index 1be811288ce..dbb888c1213 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; @@ -34,38 +35,36 @@ import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.util.Assert; import org.springframework.web.HttpRequestHandler; import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator; +import org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator; import org.springframework.web.socket.server.HandshakeFailureException; import org.springframework.web.socket.server.HandshakeHandler; import org.springframework.web.socket.server.HandshakeInterceptor; -import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator; -import org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator; /** * A {@link HttpRequestHandler} for processing WebSocket handshake requests. * *

This is the main class to use when configuring a server WebSocket at a specific URL. - * It is a very thin wrapper around a {@link HandshakeHandler} and a - * {@link WebSocketHandler} instance also adapting the {@link HttpServletRequest} and - * {@link HttpServletResponse} to {@link ServerHttpRequest} and {@link ServerHttpResponse} - * respectively. + * It is a very thin wrapper around a {@link WebSocketHandler} and a {@link HandshakeHandler}, + * also adapting the {@link HttpServletRequest} and {@link HttpServletResponse} to + * {@link ServerHttpRequest} and {@link ServerHttpResponse}, respectively. * * @author Rossen Stoyanchev * @since 4.0 */ public class WebSocketHttpRequestHandler implements HttpRequestHandler { - private static final Log logger = LogFactory.getLog(WebSocketHttpRequestHandler.class); + private final Log logger = LogFactory.getLog(WebSocketHttpRequestHandler.class); + private final WebSocketHandler wsHandler; private final HandshakeHandler handshakeHandler; - private final WebSocketHandler wsHandler; - private final List interceptors = new ArrayList(); - public WebSocketHttpRequestHandler(WebSocketHandler webSocketHandler) { - this(webSocketHandler, new DefaultHandshakeHandler()); + public WebSocketHttpRequestHandler(WebSocketHandler wsHandler) { + this(wsHandler, new DefaultHandshakeHandler()); } public WebSocketHttpRequestHandler(WebSocketHandler wsHandler, HandshakeHandler handshakeHandler) { @@ -132,8 +131,8 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler { catch (HandshakeFailureException ex) { failure = ex; } - catch (Throwable t) { - failure = new HandshakeFailureException("Uncaught failure for request " + request.getURI(), t); + catch (Throwable ex) { + failure = new HandshakeFailureException("Uncaught failure for request " + request.getURI(), ex); } finally { if (failure != null) { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/package-info.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/package-info.java index 41c16bb7b7d..33b4aec1832 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/package-info.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/package-info.java @@ -1,22 +1,5 @@ -/* - * Copyright 2002-2013 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. - */ - /** - * Server-side support classes including container-specific strategies for upgrading a - * request. + * Server-side support classes including container-specific strategies + * for upgrading a request. */ package org.springframework.web.socket.server.support; -