Revised Jetty 9.3 vs 9.4 differentiation
Issue: SPR-14940
This commit is contained in:
@@ -42,15 +42,13 @@ public abstract class AbstractWebSocketSession<T> implements NativeWebSocketSess
|
|||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(NativeWebSocketSession.class);
|
protected static final Log logger = LogFactory.getLog(NativeWebSocketSession.class);
|
||||||
|
|
||||||
|
private final Map<String, Object> attributes = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private T nativeSession;
|
private T nativeSession;
|
||||||
|
|
||||||
private final Map<String, Object> attributes = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance and associate the given attributes with it.
|
* Create a new instance and associate the given attributes with it.
|
||||||
*
|
|
||||||
* @param attributes attributes from the HTTP handshake to associate with the WebSocket
|
* @param attributes attributes from the HTTP handshake to associate with the WebSocket
|
||||||
* session; the provided attributes are copied, the original map is not used.
|
* session; the provided attributes are copied, the original map is not used.
|
||||||
*/
|
*/
|
||||||
@@ -83,7 +81,7 @@ public abstract class AbstractWebSocketSession<T> implements NativeWebSocketSess
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initializeNativeSession(T session) {
|
public void initializeNativeSession(T session) {
|
||||||
Assert.notNull(session, "session must not be null");
|
Assert.notNull(session, "WebSocket session must not be null");
|
||||||
this.nativeSession = session;
|
this.nativeSession = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +123,7 @@ public abstract class AbstractWebSocketSession<T> implements NativeWebSocketSess
|
|||||||
|
|
||||||
protected abstract void sendPongMessage(PongMessage message) throws IOException;
|
protected abstract void sendPongMessage(PongMessage message) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void close() throws IOException {
|
public final void close() throws IOException {
|
||||||
close(CloseStatus.NORMAL);
|
close(CloseStatus.NORMAL);
|
||||||
|
|||||||
@@ -45,25 +45,45 @@ import org.springframework.web.socket.WebSocketSession;
|
|||||||
import org.springframework.web.socket.adapter.AbstractWebSocketSession;
|
import org.springframework.web.socket.adapter.AbstractWebSocketSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link WebSocketSession} for use with the Jetty 9 WebSocket API.
|
* A {@link WebSocketSession} for use with the Jetty 9.3/9.4 WebSocket API.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
||||||
|
|
||||||
// As of Jetty 9.4, UpgradeRequest and UpgradeResponse are interfaces instead of classes
|
// As of Jetty 9.4, UpgradeRequest and UpgradeResponse are interfaces instead of classes
|
||||||
private static final boolean isJetty94;
|
private static final boolean directInterfaceCalls;
|
||||||
|
|
||||||
private static Method getUpgradeRequest;
|
private static Method getUpgradeRequest;
|
||||||
private static Method getUpgradeResponse;
|
private static Method getUpgradeResponse;
|
||||||
private static Method getRequestURI;
|
private static Method getRequestURI;
|
||||||
private static Method getHeaders;
|
private static Method getHeaders;
|
||||||
|
private static Method getUserPrincipal;
|
||||||
private static Method getAcceptedSubProtocol;
|
private static Method getAcceptedSubProtocol;
|
||||||
private static Method getExtensions;
|
private static Method getExtensions;
|
||||||
private static Method getUserPrincipal;
|
|
||||||
|
static {
|
||||||
|
directInterfaceCalls = UpgradeRequest.class.isInterface();
|
||||||
|
if (!directInterfaceCalls) {
|
||||||
|
try {
|
||||||
|
getUpgradeRequest = Session.class.getMethod("getUpgradeRequest");
|
||||||
|
getUpgradeResponse = Session.class.getMethod("getUpgradeResponse");
|
||||||
|
getRequestURI = UpgradeRequest.class.getMethod("getRequestURI");
|
||||||
|
getHeaders = UpgradeRequest.class.getMethod("getHeaders");
|
||||||
|
getUserPrincipal = UpgradeRequest.class.getMethod("getUserPrincipal");
|
||||||
|
getAcceptedSubProtocol = UpgradeResponse.class.getMethod("getAcceptedSubProtocol");
|
||||||
|
getExtensions = UpgradeResponse.class.getMethod("getExtensions");
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException ex) {
|
||||||
|
throw new IllegalStateException("Incompatible Jetty API", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@@ -77,27 +97,9 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
|||||||
|
|
||||||
private Principal user;
|
private Principal user;
|
||||||
|
|
||||||
static {
|
|
||||||
isJetty94 = UpgradeRequest.class.isInterface();
|
|
||||||
if (!isJetty94) {
|
|
||||||
try {
|
|
||||||
getUpgradeRequest = Session.class.getMethod("getUpgradeRequest");
|
|
||||||
getUpgradeResponse = Session.class.getMethod("getUpgradeResponse");
|
|
||||||
getRequestURI = UpgradeRequest.class.getMethod("getRequestURI");
|
|
||||||
getHeaders = UpgradeRequest.class.getMethod("getHeaders");
|
|
||||||
getAcceptedSubProtocol = UpgradeResponse.class.getMethod("getAcceptedSubProtocol");
|
|
||||||
getExtensions = UpgradeResponse.class.getMethod("getExtensions");
|
|
||||||
getUserPrincipal = UpgradeRequest.class.getMethod("getUserPrincipal");
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException ex) {
|
|
||||||
throw new IllegalStateException("Incompatible Jetty API", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link JettyWebSocketSession} instance.
|
* Create a new {@link JettyWebSocketSession} instance.
|
||||||
*
|
|
||||||
* @param attributes attributes from the HTTP handshake to associate with the WebSocket session
|
* @param attributes attributes from the HTTP handshake to associate with the WebSocket session
|
||||||
*/
|
*/
|
||||||
public JettyWebSocketSession(Map<String, Object> attributes) {
|
public JettyWebSocketSession(Map<String, Object> attributes) {
|
||||||
@@ -106,11 +108,10 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link JettyWebSocketSession} instance associated with the given user.
|
* Create a new {@link JettyWebSocketSession} instance associated with the given user.
|
||||||
*
|
|
||||||
* @param attributes attributes from the HTTP handshake to associate with the WebSocket
|
* @param attributes attributes from the HTTP handshake to associate with the WebSocket
|
||||||
* session; the provided attributes are copied, the original map is not used.
|
* session; the provided attributes are copied, the original map is not used.
|
||||||
* @param user the user associated with the session; if {@code null} we'll fallback on the user
|
* @param user the user associated with the session; if {@code null} we'll fallback on the
|
||||||
* available via {@link org.eclipse.jetty.websocket.api.Session#getUpgradeRequest()}
|
* user available via {@link org.eclipse.jetty.websocket.api.Session#getUpgradeRequest()}
|
||||||
*/
|
*/
|
||||||
public JettyWebSocketSession(Map<String, Object> attributes, Principal user) {
|
public JettyWebSocketSession(Map<String, Object> attributes, Principal user) {
|
||||||
super(attributes);
|
super(attributes);
|
||||||
@@ -191,23 +192,49 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return ((getNativeSession() != null) && getNativeSession().isOpen());
|
return (getNativeSession() != null && getNativeSession().isOpen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeNativeSession(Session session) {
|
public void initializeNativeSession(Session session) {
|
||||||
super.initializeNativeSession(session);
|
super.initializeNativeSession(session);
|
||||||
if (isJetty94) {
|
if (directInterfaceCalls) {
|
||||||
initializeJetty94Session(session);
|
initializeJettySessionDirectly(session);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
initializeJettySession(session);
|
initializeJettySessionReflectively(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeJettySessionDirectly(Session session) {
|
||||||
|
this.id = ObjectUtils.getIdentityHexString(getNativeSession());
|
||||||
|
this.uri = session.getUpgradeRequest().getRequestURI();
|
||||||
|
|
||||||
|
this.headers = new HttpHeaders();
|
||||||
|
this.headers.putAll(session.getUpgradeRequest().getHeaders());
|
||||||
|
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||||
|
|
||||||
|
this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol();
|
||||||
|
|
||||||
|
List<ExtensionConfig> source = session.getUpgradeResponse().getExtensions();
|
||||||
|
if (source != null) {
|
||||||
|
this.extensions = new ArrayList<>(source.size());
|
||||||
|
for (ExtensionConfig ec : source) {
|
||||||
|
this.extensions.add(new WebSocketExtension(ec.getName(), ec.getParameters()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.extensions = new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.user == null) {
|
||||||
|
this.user = session.getUpgradeRequest().getUserPrincipal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void initializeJettySession(Session session) {
|
private void initializeJettySessionReflectively(Session session) {
|
||||||
|
|
||||||
Object request = ReflectionUtils.invokeMethod(getUpgradeRequest, session);
|
Object request = ReflectionUtils.invokeMethod(getUpgradeRequest, session);
|
||||||
Object response = ReflectionUtils.invokeMethod(getUpgradeResponse, session);
|
Object response = ReflectionUtils.invokeMethod(getUpgradeResponse, session);
|
||||||
|
|
||||||
@@ -236,31 +263,6 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeJetty94Session(Session session) {
|
|
||||||
this.id = ObjectUtils.getIdentityHexString(getNativeSession());
|
|
||||||
this.uri = session.getUpgradeRequest().getRequestURI();
|
|
||||||
|
|
||||||
this.headers = new HttpHeaders();
|
|
||||||
this.headers.putAll(session.getUpgradeRequest().getHeaders());
|
|
||||||
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
|
||||||
|
|
||||||
this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol();
|
|
||||||
|
|
||||||
List<ExtensionConfig> source = session.getUpgradeResponse().getExtensions();
|
|
||||||
if (source != null) {
|
|
||||||
this.extensions = new ArrayList<>(source.size());
|
|
||||||
for (ExtensionConfig ec : source) {
|
|
||||||
this.extensions.add(new WebSocketExtension(ec.getName(), ec.getParameters()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.extensions = new ArrayList<>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.user == null) {
|
|
||||||
this.user = session.getUpgradeRequest().getUserPrincipal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sendTextMessage(TextMessage message) throws IOException {
|
protected void sendTextMessage(TextMessage message) throws IOException {
|
||||||
@@ -287,7 +289,7 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
|
|||||||
return getNativeSession().getRemote();
|
return getNativeSession().getRemote();
|
||||||
}
|
}
|
||||||
catch (WebSocketException ex) {
|
catch (WebSocketException ex) {
|
||||||
throw new IOException("Unable to obtain RemoteEndpoint in session=" + getId(), ex);
|
throw new IOException("Unable to obtain RemoteEndpoint in session " + getId(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import java.security.Principal;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -60,75 +59,59 @@ import org.springframework.web.socket.server.RequestUpgradeStrategy;
|
|||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle, ServletContextAware {
|
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, ServletContextAware, Lifecycle {
|
||||||
|
|
||||||
private static final ThreadLocal<WebSocketHandlerContainer> wsContainerHolder =
|
private static final ThreadLocal<WebSocketHandlerContainer> wsContainerHolder =
|
||||||
new NamedThreadLocal<>("WebSocket Handler Container");
|
new NamedThreadLocal<>("WebSocket Handler Container");
|
||||||
|
|
||||||
// Actually 9.3.15+
|
private final WebSocketServerFactoryAdapter factoryAdapter =
|
||||||
private static boolean isJetty94 = ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class);
|
(ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class) ?
|
||||||
|
new ModernJettyWebSocketServerFactoryAdapter() : new LegacyJettyWebSocketServerFactoryAdapter());
|
||||||
|
|
||||||
private WebSocketServerFactoryAdapter factoryAdapter;
|
private ServletContext servletContext;
|
||||||
|
|
||||||
|
private volatile boolean running = false;
|
||||||
|
|
||||||
private volatile List<WebSocketExtension> supportedExtensions;
|
private volatile List<WebSocketExtension> supportedExtensions;
|
||||||
|
|
||||||
protected ServletContext servletContext;
|
|
||||||
|
|
||||||
private volatile boolean running = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor that creates {@link WebSocketServerFactory} through
|
* Default constructor that creates {@link WebSocketServerFactory} through
|
||||||
* its default constructor thus using a default {@link WebSocketPolicy}.
|
* its default constructor thus using a default {@link WebSocketPolicy}.
|
||||||
*/
|
*/
|
||||||
public JettyRequestUpgradeStrategy() {
|
public JettyRequestUpgradeStrategy() {
|
||||||
this(WebSocketPolicy.newServerPolicy());
|
this.factoryAdapter.setPolicy(WebSocketPolicy.newServerPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constructor accepting a {@link WebSocketPolicy}
|
* A constructor accepting a {@link WebSocketPolicy} to be used when
|
||||||
* to be used when creating the {@link WebSocketServerFactory} instance.
|
* creating the {@link WebSocketServerFactory} instance.
|
||||||
* @since 4.3
|
* @param policy the policy to use
|
||||||
|
* @since 4.3.5
|
||||||
*/
|
*/
|
||||||
public JettyRequestUpgradeStrategy(WebSocketPolicy webSocketPolicy) {
|
public JettyRequestUpgradeStrategy(WebSocketPolicy policy) {
|
||||||
this.factoryAdapter = isJetty94 ? new Jetty94WebSocketServerFactoryAdapter()
|
Assert.notNull(policy, "WebSocketPolicy must not be null");
|
||||||
: new JettyWebSocketServerFactoryAdapter();
|
this.factoryAdapter.setPolicy(policy);
|
||||||
this.factoryAdapter.setWebSocketPolicy(webSocketPolicy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String[] getSupportedVersions() {
|
* A constructor accepting a {@link WebSocketServerFactory}.
|
||||||
return new String[] {String.valueOf(HandshakeRFC6455.VERSION)};
|
* @param factory the pre-configured factory to use
|
||||||
|
*/
|
||||||
|
public JettyRequestUpgradeStrategy(WebSocketServerFactory factory) {
|
||||||
|
Assert.notNull(factory, "WebSocketServerFactory must not be null");
|
||||||
|
this.factoryAdapter.setFactory(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<WebSocketExtension> getSupportedExtensions(ServerHttpRequest request) {
|
|
||||||
if (this.supportedExtensions == null) {
|
|
||||||
this.supportedExtensions = getWebSocketExtensions();
|
|
||||||
}
|
|
||||||
return this.supportedExtensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<WebSocketExtension> getWebSocketExtensions() {
|
|
||||||
List<WebSocketExtension> result = new ArrayList<>();
|
|
||||||
for (String name : this.factoryAdapter.getFactory().getExtensionFactory().getExtensionNames()) {
|
|
||||||
result.add(new WebSocketExtension(name));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setServletContext(ServletContext servletContext) {
|
public void setServletContext(ServletContext servletContext) {
|
||||||
this.servletContext = servletContext;
|
this.servletContext = servletContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRunning() {
|
|
||||||
return this.running;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
if (!isRunning()) {
|
if (!isRunning()) {
|
||||||
@@ -136,7 +119,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
|
|||||||
try {
|
try {
|
||||||
this.factoryAdapter.start();
|
this.factoryAdapter.start();
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalStateException("Unable to start Jetty WebSocketServerFactory", ex);
|
throw new IllegalStateException("Unable to start Jetty WebSocketServerFactory", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,12 +132,39 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
|
|||||||
this.running = false;
|
this.running = false;
|
||||||
this.factoryAdapter.stop();
|
this.factoryAdapter.stop();
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex);
|
throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRunning() {
|
||||||
|
return this.running;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedVersions() {
|
||||||
|
return new String[] { String.valueOf(HandshakeRFC6455.VERSION) };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<WebSocketExtension> getSupportedExtensions(ServerHttpRequest request) {
|
||||||
|
if (this.supportedExtensions == null) {
|
||||||
|
this.supportedExtensions = buildWebSocketExtensions();
|
||||||
|
}
|
||||||
|
return this.supportedExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<WebSocketExtension> buildWebSocketExtensions() {
|
||||||
|
List<WebSocketExtension> result = new ArrayList<>();
|
||||||
|
for (String name : this.factoryAdapter.getFactory().getExtensionFactory().getExtensionNames()) {
|
||||||
|
result.add(new WebSocketExtension(name));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
|
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
|
||||||
String selectedProtocol, List<WebSocketExtension> selectedExtensions, Principal user,
|
String selectedProtocol, List<WebSocketExtension> selectedExtensions, Principal user,
|
||||||
@@ -197,7 +207,9 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
|
|||||||
|
|
||||||
private final List<ExtensionConfig> extensionConfigs;
|
private final List<ExtensionConfig> extensionConfigs;
|
||||||
|
|
||||||
public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter handler, String protocol, List<WebSocketExtension> extensions) {
|
public WebSocketHandlerContainer(
|
||||||
|
JettyWebSocketHandlerAdapter handler, String protocol, List<WebSocketExtension> extensions) {
|
||||||
|
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.selectedProtocol = protocol;
|
this.selectedProtocol = protocol;
|
||||||
if (CollectionUtils.isEmpty(extensions)) {
|
if (CollectionUtils.isEmpty(extensions)) {
|
||||||
@@ -224,21 +236,29 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static abstract class WebSocketServerFactoryAdapter {
|
private static abstract class WebSocketServerFactoryAdapter {
|
||||||
|
|
||||||
protected WebSocketServerFactory factory;
|
private WebSocketPolicy policy;
|
||||||
|
|
||||||
protected WebSocketPolicy webSocketPolicy;
|
private WebSocketServerFactory factory;
|
||||||
|
|
||||||
|
public void setPolicy(WebSocketPolicy policy) {
|
||||||
|
this.policy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFactory(WebSocketServerFactory factory) {
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
public WebSocketServerFactory getFactory() {
|
public WebSocketServerFactory getFactory() {
|
||||||
return factory;
|
return this.factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWebSocketPolicy(WebSocketPolicy webSocketPolicy) {
|
public void start() throws Exception {
|
||||||
this.webSocketPolicy = webSocketPolicy;
|
if (this.factory == null) {
|
||||||
}
|
this.factory = createFactory(this.policy);
|
||||||
|
}
|
||||||
protected void configureFactory() {
|
|
||||||
this.factory.setCreator(new WebSocketCreator() {
|
this.factory.setCreator(new WebSocketCreator() {
|
||||||
@Override
|
@Override
|
||||||
public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) {
|
public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) {
|
||||||
@@ -249,43 +269,60 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
|
|||||||
return container.getHandler();
|
return container.getHandler();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
startFactory(this.factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void start() throws Exception;
|
public void stop() throws Exception {
|
||||||
|
if (this.factory != null) {
|
||||||
|
stopFactory(this.factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract void stop() throws Exception;
|
protected abstract WebSocketServerFactory createFactory(WebSocketPolicy policy) throws Exception;
|
||||||
|
|
||||||
|
protected abstract void startFactory(WebSocketServerFactory factory) throws Exception;
|
||||||
|
|
||||||
|
protected abstract void stopFactory(WebSocketServerFactory factory) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
|
|
||||||
|
// Jetty 9.3.15+
|
||||||
|
private class ModernJettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void start() throws Exception {
|
protected WebSocketServerFactory createFactory(WebSocketPolicy policy) throws Exception {
|
||||||
this.factory = WebSocketServerFactory.class.getConstructor(WebSocketPolicy.class)
|
|
||||||
.newInstance(this.webSocketPolicy);
|
|
||||||
configureFactory();
|
|
||||||
WebSocketServerFactory.class.getMethod("init", ServletContext.class)
|
|
||||||
.invoke(this.factory, servletContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void stop() throws Exception {
|
|
||||||
WebSocketServerFactory.class.getMethod("cleanup").invoke(this.factory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Jetty94WebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void start() throws Exception {
|
|
||||||
servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory());
|
servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory());
|
||||||
this.factory = new WebSocketServerFactory(servletContext, this.webSocketPolicy);
|
return new WebSocketServerFactory(servletContext, policy);
|
||||||
configureFactory();
|
|
||||||
this.factory.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void stop() throws Exception {
|
protected void startFactory(WebSocketServerFactory factory) throws Exception {
|
||||||
this.factory.stop();
|
factory.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void stopFactory(WebSocketServerFactory factory) throws Exception {
|
||||||
|
factory.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Jetty <9.3.15
|
||||||
|
private class LegacyJettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WebSocketServerFactory createFactory(WebSocketPolicy policy) throws Exception {
|
||||||
|
return WebSocketServerFactory.class.getConstructor(WebSocketPolicy.class).newInstance(policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startFactory(WebSocketServerFactory factory) throws Exception {
|
||||||
|
WebSocketServerFactory.class.getMethod("init", ServletContext.class).invoke(factory, servletContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void stopFactory(WebSocketServerFactory factory) throws Exception {
|
||||||
|
WebSocketServerFactory.class.getMethod("cleanup").invoke(factory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user