public abstract class AbstractHandshakeHandler extends Object implements HandshakeHandler, Lifecycle
HandshakeHandler
implementations, independent from the Servlet API.
Performs initial validation of the WebSocket handshake request - possibly rejecting it through the appropriate HTTP status code - while also allowing its subclasses to override various parts of the negotiation process (e.g. origin validation, sub-protocol negotiation, extensions negotiation, etc).
If the negotiation succeeds, the actual upgrade is delegated to a server-specific
RequestUpgradeStrategy
, which will update
the response as necessary and initialize the WebSocket. Currently supported servers are
Jetty 9.0-9.3, Tomcat 7.0.47+ and 8.x, Undertow 1.0-1.3, GlassFish 4.1+, WebLogic 12.1.3+.
JettyRequestUpgradeStrategy
,
TomcatRequestUpgradeStrategy
,
UndertowRequestUpgradeStrategy
,
GlassFishRequestUpgradeStrategy
,
WebLogicRequestUpgradeStrategy
Modifier | Constructor and Description |
---|---|
protected |
AbstractHandshakeHandler()
Default constructor that auto-detects and instantiates a
RequestUpgradeStrategy suitable for the runtime container. |
protected |
AbstractHandshakeHandler(RequestUpgradeStrategy requestUpgradeStrategy)
A constructor that accepts a runtime-specific
RequestUpgradeStrategy . |
Modifier and Type | Method and Description |
---|---|
protected List<String> |
determineHandlerSupportedProtocols(WebSocketHandler handler)
Determine the sub-protocols supported by the given WebSocketHandler by
checking whether it is an instance of
SubProtocolCapable . |
protected Principal |
determineUser(ServerHttpRequest request,
WebSocketHandler wsHandler,
Map<String,Object> attributes)
A method that can be used to associate a user with the WebSocket session
in the process of being established.
|
boolean |
doHandshake(ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map<String,Object> attributes)
Initiate the handshake.
|
protected void |
doStart() |
protected void |
doStop() |
protected List<WebSocketExtension> |
filterRequestedExtensions(ServerHttpRequest request,
List<WebSocketExtension> requestedExtensions,
List<WebSocketExtension> supportedExtensions)
Filter the list of requested WebSocket extensions.
|
RequestUpgradeStrategy |
getRequestUpgradeStrategy()
Return the
RequestUpgradeStrategy for WebSocket requests. |
String[] |
getSupportedProtocols()
Return the list of supported sub-protocols.
|
protected String[] |
getSupportedVersions() |
protected void |
handleInvalidConnectHeader(ServerHttpRequest request,
ServerHttpResponse response) |
protected void |
handleInvalidUpgradeHeader(ServerHttpRequest request,
ServerHttpResponse response) |
protected void |
handleWebSocketVersionNotSupported(ServerHttpRequest request,
ServerHttpResponse response) |
boolean |
isRunning()
Check whether this component is currently running.
|
protected boolean |
isValidOrigin(ServerHttpRequest request)
Return whether the request
Origin header value is valid or not. |
protected boolean |
isWebSocketVersionSupported(WebSocketHttpHeaders httpHeaders) |
protected String |
selectProtocol(List<String> requestedProtocols,
WebSocketHandler webSocketHandler)
Perform the sub-protocol negotiation based on requested and supported sub-protocols.
|
void |
setSupportedProtocols(String... protocols)
Use this property to configure the list of supported sub-protocols.
|
void |
start()
Start this component.
|
void |
stop()
Stop this component, typically in a synchronous fashion, such that the component is
fully stopped upon return of this method.
|
protected final Log logger
protected AbstractHandshakeHandler()
RequestUpgradeStrategy
suitable for the runtime container.IllegalStateException
- if no RequestUpgradeStrategy
can be found.protected AbstractHandshakeHandler(RequestUpgradeStrategy requestUpgradeStrategy)
RequestUpgradeStrategy
.requestUpgradeStrategy
- the upgrade strategy to usepublic RequestUpgradeStrategy getRequestUpgradeStrategy()
RequestUpgradeStrategy
for WebSocket requests.public void setSupportedProtocols(String... protocols)
Note that if the WebSocketHandler passed in at runtime is an instance of
SubProtocolCapable
then there is not need to explicitly configure
this property. That is certainly the case with the built-in STOMP over
WebSocket support. Therefore this property should be configured explicitly
only if the WebSocketHandler does not implement SubProtocolCapable
.
public String[] getSupportedProtocols()
public void start()
Lifecycle
Should not throw an exception if the component is already running.
In the case of a container, this will propagate the start signal to all components that apply.
start
in interface Lifecycle
SmartLifecycle.isAutoStartup()
protected void doStart()
public void stop()
Lifecycle
SmartLifecycle
and its stop(Runnable)
variant when asynchronous stop behavior is necessary.
Note that this stop notification is not guaranteed to come before destruction:
On regular shutdown, Lifecycle
beans will first receive a stop notification
before the general destruction callbacks are being propagated; however, on hot
refresh during a context's lifetime or on aborted refresh attempts, a given bean's
destroy method will be called without any consideration of stop signals upfront.
Should not throw an exception if the component is not running (not started yet).
In the case of a container, this will propagate the stop signal to all components that apply.
stop
in interface Lifecycle
SmartLifecycle.stop(Runnable)
,
DisposableBean.destroy()
protected void doStop()
public boolean isRunning()
Lifecycle
In the case of a container, this will return true
only if all
components that apply are currently running.
public final boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String,Object> attributes) throws HandshakeFailureException
HandshakeHandler
doHandshake
in interface HandshakeHandler
request
- the current requestresponse
- the current responsewsHandler
- the handler to process WebSocket messages; see
PerConnectionWebSocketHandler
for providing a handler with
per-connection lifecycle.attributes
- attributes from the HTTP handshake to associate with the WebSocket
session; the provided attributes are copied, the original map is not used.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.protected void handleInvalidUpgradeHeader(ServerHttpRequest request, ServerHttpResponse response) throws IOException
IOException
protected void handleInvalidConnectHeader(ServerHttpRequest request, ServerHttpResponse response) throws IOException
IOException
protected boolean isWebSocketVersionSupported(WebSocketHttpHeaders httpHeaders)
protected String[] getSupportedVersions()
protected void handleWebSocketVersionNotSupported(ServerHttpRequest request, ServerHttpResponse response)
protected boolean isValidOrigin(ServerHttpRequest request)
Origin
header value is valid or not.
By default, all origins as considered as valid. Consider using an
OriginHandshakeInterceptor
for filtering origins if needed.protected String selectProtocol(List<String> requestedProtocols, WebSocketHandler webSocketHandler)
SubProtocolCapable
and then also checks if any
sub-protocols have been explicitly configured with
setSupportedProtocols(String...)
.requestedProtocols
- the requested sub-protocolswebSocketHandler
- the WebSocketHandler that will be usednull
determineHandlerSupportedProtocols(WebSocketHandler)
protected final List<String> determineHandlerSupportedProtocols(WebSocketHandler handler)
SubProtocolCapable
.handler
- the handler to checkprotected List<WebSocketExtension> filterRequestedExtensions(ServerHttpRequest request, List<WebSocketExtension> requestedExtensions, List<WebSocketExtension> supportedExtensions)
As of 4.1, the default implementation of this method filters the list to leave only extensions that are both requested and supported.
request
- the current requestrequestedExtensions
- the list of extensions requested by the clientsupportedExtensions
- the list of extensions supported by the serverprotected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String,Object> attributes)
ServerHttpRequest.getPrincipal()
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).
request
- the handshake requestwsHandler
- the WebSocket handler that will handle messagesattributes
- handshake attributes to pass to the WebSocket sessionnull
if not available