Add EndpointRequestUpgradeStrategy
Now there is just one EndpointHandshakeRequestHandler that works on different runtimes.
This commit is contained in:
parent
741927664c
commit
30ab5953f9
|
@ -33,12 +33,14 @@ import org.springframework.util.Assert;
|
|||
* Java WebSocket runtime and also configures the underlying
|
||||
* {@link javax.websocket.server.ServerContainer}.
|
||||
*
|
||||
* <p>If the runtime is a Servlet container, use {@link ServletEndpointExporter}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ServerEndpointExporter implements BeanPostProcessor, InitializingBean {
|
||||
public class EndpointExporter implements BeanPostProcessor, InitializingBean {
|
||||
|
||||
private static Log logger = LogFactory.getLog(ServerEndpointExporter.class);
|
||||
private static Log logger = LogFactory.getLog(EndpointExporter.class);
|
||||
|
||||
private Long maxSessionIdleTimeout;
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.server.endpoint;
|
||||
|
||||
import javax.websocket.Endpoint;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.websocket.WebSocketHandler;
|
||||
import org.springframework.websocket.endpoint.StandardWebSocketHandlerAdapter;
|
||||
import org.springframework.websocket.server.AbstractHandshakeRequestHandler;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class EndpointHandshakeRequestHandler extends AbstractHandshakeRequestHandler {
|
||||
|
||||
private static final boolean tomcatWebSocketPresent = ClassUtils.isPresent(
|
||||
"org.apache.tomcat.websocket.server.WsHandshakeRequest", EndpointHandshakeRequestHandler.class.getClassLoader());
|
||||
|
||||
private final EndpointRegistration endpointRegistration;
|
||||
|
||||
private final EndpointRequestUpgradeStrategy upgradeStrategy;
|
||||
|
||||
|
||||
public EndpointHandshakeRequestHandler(WebSocketHandler webSocketHandler) {
|
||||
this(new StandardWebSocketHandlerAdapter(webSocketHandler));
|
||||
}
|
||||
|
||||
public EndpointHandshakeRequestHandler(Endpoint endpoint) {
|
||||
this.endpointRegistration = new EndpointRegistration("/dummy", endpoint);
|
||||
this.upgradeStrategy = createRequestUpgradeStrategy();
|
||||
}
|
||||
|
||||
private static EndpointRequestUpgradeStrategy createRequestUpgradeStrategy() {
|
||||
String className;
|
||||
if (tomcatWebSocketPresent) {
|
||||
className = "org.springframework.websocket.server.endpoint.TomcatRequestUpgradeStrategy";
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("No suitable EndpointRequestUpgradeStrategy");
|
||||
}
|
||||
try {
|
||||
Class<?> clazz = ClassUtils.forName(className, EndpointHandshakeRequestHandler.class.getClassLoader());
|
||||
return (EndpointRequestUpgradeStrategy) BeanUtils.instantiateClass(clazz.getConstructor());
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new IllegalStateException("Failed to instantiate " + className, t);
|
||||
}
|
||||
}
|
||||
|
||||
public EndpointRegistration getEndpointRegistration() {
|
||||
return this.endpointRegistration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHandshakeInternal(ServerHttpRequest request, ServerHttpResponse response, String protocol)
|
||||
throws Exception {
|
||||
|
||||
logger.debug("Upgrading HTTP request");
|
||||
this.upgradeStrategy.upgrade(request, response, protocol, this.endpointRegistration);
|
||||
}
|
||||
|
||||
}
|
|
@ -46,13 +46,13 @@ import org.springframework.websocket.endpoint.StandardWebSocketHandlerAdapter;
|
|||
* which case it will be adapted via {@link StandardWebSocketHandlerAdapter}.
|
||||
*
|
||||
* <p>
|
||||
* Beans of this type are detected by {@link ServerEndpointExporter} and
|
||||
* Beans of this type are detected by {@link EndpointExporter} and
|
||||
* registered with a Java WebSocket runtime at startup.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ServerEndpointRegistration implements ServerEndpointConfig, BeanFactoryAware {
|
||||
public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAware {
|
||||
|
||||
private final String path;
|
||||
|
||||
|
@ -69,14 +69,14 @@ public class ServerEndpointRegistration implements ServerEndpointConfig, BeanFac
|
|||
private final Configurator configurator = new Configurator() {};
|
||||
|
||||
|
||||
public ServerEndpointRegistration(String path, String beanName) {
|
||||
public EndpointRegistration(String path, String beanName) {
|
||||
Assert.hasText(path, "path must not be empty");
|
||||
Assert.notNull(beanName, "beanName is required");
|
||||
this.path = path;
|
||||
this.bean = beanName;
|
||||
}
|
||||
|
||||
public ServerEndpointRegistration(String path, Object bean) {
|
||||
public EndpointRegistration(String path, Object bean) {
|
||||
Assert.hasText(path, "path must not be empty");
|
||||
Assert.notNull(bean, "bean is required");
|
||||
this.path = path;
|
||||
|
@ -104,7 +104,7 @@ public class ServerEndpointRegistration implements ServerEndpointConfig, BeanFac
|
|||
}
|
||||
}
|
||||
|
||||
protected Endpoint getEndpoint() {
|
||||
public Endpoint getEndpoint() {
|
||||
Object bean = this.bean;
|
||||
if (this.bean instanceof String) {
|
||||
bean = this.beanFactory.getBean((String) this.bean);
|
||||
|
@ -166,23 +166,23 @@ public class ServerEndpointRegistration implements ServerEndpointConfig, BeanFac
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
|
||||
return (T) ServerEndpointRegistration.this.getEndpoint();
|
||||
return (T) EndpointRegistration.this.getEndpoint();
|
||||
}
|
||||
@Override
|
||||
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
|
||||
ServerEndpointRegistration.this.modifyHandshake(request, response);
|
||||
EndpointRegistration.this.modifyHandshake(request, response);
|
||||
}
|
||||
@Override
|
||||
public boolean checkOrigin(String originHeaderValue) {
|
||||
return ServerEndpointRegistration.this.checkOrigin(originHeaderValue);
|
||||
return EndpointRegistration.this.checkOrigin(originHeaderValue);
|
||||
}
|
||||
@Override
|
||||
public String getNegotiatedSubprotocol(List<String> supported, List<String> requested) {
|
||||
return ServerEndpointRegistration.this.selectSubProtocol(requested);
|
||||
return EndpointRegistration.this.selectSubProtocol(requested);
|
||||
}
|
||||
@Override
|
||||
public List<Extension> getNegotiatedExtensions(List<Extension> installed, List<Extension> requested) {
|
||||
return ServerEndpointRegistration.this.selectExtensions(requested);
|
||||
return EndpointRegistration.this.selectExtensions(requested);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.server.endpoint;
|
||||
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
|
||||
|
||||
/**
|
||||
* A strategy for performing the actual request upgrade after the handshake checks have
|
||||
* passed, encapsulating runtime-specific steps of the handshake.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface EndpointRequestUpgradeStrategy {
|
||||
|
||||
void upgrade(ServerHttpRequest request, ServerHttpResponse response, String protocol,
|
||||
EndpointRegistration registration) throws Exception;
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ import org.springframework.web.context.ServletContextAware;
|
|||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ServletServerEndpointExporter extends ServerEndpointExporter implements ServletContextAware {
|
||||
public class ServletEndpointExporter extends EndpointExporter implements ServletContextAware {
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
|
@ -43,7 +43,8 @@ public class ServletServerEndpointExporter extends ServerEndpointExporter implem
|
|||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// TODO: remove hard dependency on Tomcat (see Tomcat's WsListener)
|
||||
|
||||
// TODO: this is needed (see WsListener) but remove hard dependency
|
||||
WsServerContainer sc = WsServerContainer.getServerContainer();
|
||||
sc.setServletContext(this.servletContext);
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.server.endpoint;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
|
||||
import org.apache.tomcat.websocket.server.WsHandshakeRequest;
|
||||
import org.apache.tomcat.websocket.server.WsHttpUpgradeHandler;
|
||||
import org.apache.tomcat.websocket.server.WsServerContainer;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.websocket.WebSocketHandler;
|
||||
import org.springframework.websocket.endpoint.StandardWebSocketHandlerAdapter;
|
||||
import org.springframework.websocket.server.AbstractHandshakeRequestHandler;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class TomcatHandshakeRequestHandler extends AbstractHandshakeRequestHandler {
|
||||
|
||||
private final Endpoint endpoint;
|
||||
|
||||
private final ServerEndpointConfig endpointConfig;
|
||||
|
||||
|
||||
public TomcatHandshakeRequestHandler(WebSocketHandler webSocketHandler) {
|
||||
this(new StandardWebSocketHandlerAdapter(webSocketHandler));
|
||||
}
|
||||
|
||||
public TomcatHandshakeRequestHandler(Endpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
this.endpointConfig = new ServerEndpointRegistration("/dummy", this.endpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHandshakeInternal(ServerHttpRequest request, ServerHttpResponse response, String protocol) throws Exception {
|
||||
|
||||
logger.debug("Upgrading HTTP request");
|
||||
|
||||
Assert.isTrue(request instanceof ServletServerHttpRequest);
|
||||
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
|
||||
|
||||
WsHandshakeRequest wsRequest = new WsHandshakeRequest(servletRequest);
|
||||
Method method = ReflectionUtils.findMethod(WsHandshakeRequest.class, "finished");
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
method.invoke(wsRequest);
|
||||
|
||||
WsHttpUpgradeHandler wsHandler = servletRequest.upgrade(WsHttpUpgradeHandler.class);
|
||||
|
||||
wsHandler.preInit(this.endpoint, this.endpointConfig, WsServerContainer.getServerContainer(),
|
||||
wsRequest, protocol, Collections.<String, String> emptyMap(), servletRequest.isSecure());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.server.endpoint;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.tomcat.websocket.server.WsHandshakeRequest;
|
||||
import org.apache.tomcat.websocket.server.WsHttpUpgradeHandler;
|
||||
import org.apache.tomcat.websocket.server.WsServerContainer;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class TomcatRequestUpgradeStrategy implements EndpointRequestUpgradeStrategy {
|
||||
|
||||
|
||||
@Override
|
||||
public void upgrade(ServerHttpRequest request, ServerHttpResponse response, String protocol,
|
||||
EndpointRegistration registration) throws Exception {
|
||||
|
||||
Assert.isTrue(request instanceof ServletServerHttpRequest);
|
||||
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
|
||||
|
||||
WsHttpUpgradeHandler wsHandler = servletRequest.upgrade(WsHttpUpgradeHandler.class);
|
||||
|
||||
WsHandshakeRequest wsRequest = new WsHandshakeRequest(servletRequest);
|
||||
Method method = ReflectionUtils.findMethod(WsHandshakeRequest.class, "finished");
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
method.invoke(wsRequest);
|
||||
|
||||
wsHandler.preInit(registration.getEndpoint(), registration,
|
||||
WsServerContainer.getServerContainer(), wsRequest, protocol,
|
||||
Collections.<String, String> emptyMap(), servletRequest.isSecure());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/**
|
||||
*
|
||||
* Server-specific support for working with standard Java WebSocket Endpoint's.
|
||||
* Server-specific support for configuring and adapting standard Java WebSocket endpoint's.
|
||||
*
|
||||
*/
|
||||
package org.springframework.websocket.server.endpoint;
|
||||
|
|
Loading…
Reference in New Issue