mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-03 12:29:31 +00:00
Post cherry-pick cleanup of jetty-9.4.x...master jetty-websocket
This commit is contained in:
parent
a037d8bbcb
commit
67cccd610a
@ -60,8 +60,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpUpgradeHandler;
|
||||
import javax.servlet.http.Part;
|
||||
import javax.servlet.http.PushBuilder;
|
||||
import javax.servlet.http.HttpServletMapping;
|
||||
|
||||
import org.eclipse.jetty.http.BadMessageException;
|
||||
import org.eclipse.jetty.http.HostPortHttpField;
|
||||
@ -2464,89 +2462,4 @@ public class Request implements HttpServletRequest
|
||||
{
|
||||
throw new ServletException("HttpServletRequest.upgrade() not supported in Jetty");
|
||||
}
|
||||
|
||||
|
||||
public void setPathSpec(PathSpec pathSpec)
|
||||
{
|
||||
_pathSpec = pathSpec;
|
||||
}
|
||||
|
||||
public PathSpec getPathSpec()
|
||||
{
|
||||
return _pathSpec;
|
||||
}
|
||||
|
||||
|
||||
// TODO replace with overriden version from API
|
||||
public HttpServletMapping getMapping()
|
||||
{
|
||||
final PathSpec pathSpec = _pathSpec;
|
||||
final MappingMatch match;
|
||||
final String mapping;
|
||||
if (pathSpec instanceof ServletPathSpec)
|
||||
{
|
||||
switch(((ServletPathSpec)pathSpec).getGroup())
|
||||
{
|
||||
case ROOT:
|
||||
match = MappingMatch.CONTEXT_ROOT;
|
||||
mapping = "";
|
||||
break;
|
||||
case DEFAULT:
|
||||
match = MappingMatch.DEFAULT;
|
||||
mapping = "/";
|
||||
break;
|
||||
case EXACT:
|
||||
match = MappingMatch.EXACT;
|
||||
mapping = _servletPath;
|
||||
break;
|
||||
case SUFFIX_GLOB:
|
||||
match = MappingMatch.EXTENSION;
|
||||
int dot = _servletPath.lastIndexOf('.');
|
||||
mapping = _servletPath.substring(0,dot);
|
||||
break;
|
||||
case PREFIX_GLOB:
|
||||
match = MappingMatch.PATH;
|
||||
mapping = _servletPath;
|
||||
break;
|
||||
default:
|
||||
match = null;
|
||||
mapping = _servletPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
match = null;
|
||||
mapping = _servletPath;
|
||||
}
|
||||
|
||||
return new HttpServletMapping()
|
||||
{
|
||||
@Override
|
||||
public String getMatchValue()
|
||||
{
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPattern()
|
||||
{
|
||||
if (pathSpec!=null)
|
||||
pathSpec.toString();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletName()
|
||||
{
|
||||
return Request.this.getServletName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingMatch getMappingMatch()
|
||||
{
|
||||
return match;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ public class Response implements HttpServletResponse
|
||||
private OutputType _outputType = OutputType.NONE;
|
||||
private ResponseWriter _writer;
|
||||
private long _contentLength = -1;
|
||||
private Supplier<HttpFields> _trailers;
|
||||
private Supplier<HttpFields> trailers;
|
||||
|
||||
private enum EncodingFrom { NOT_SET, INFERRED, SET_LOCALE, SET_CONTENT_TYPE, SET_CHARACTER_ENCODING }
|
||||
private static final EnumSet<EncodingFrom> __localeOverride = EnumSet.of(EncodingFrom.NOT_SET,EncodingFrom.INFERRED);
|
||||
@ -1314,27 +1314,12 @@ public class Response implements HttpServletResponse
|
||||
|
||||
public void setTrailers(Supplier<HttpFields> trailers)
|
||||
{
|
||||
this._trailers = trailers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrailerFields(Supplier<Map<String,String>> trailers)
|
||||
{
|
||||
// TODO new for 4.0 - avoid transient supplier?
|
||||
this._trailers = new HttpFieldsSupplier(trailers);
|
||||
this.trailers = trailers;
|
||||
}
|
||||
|
||||
public Supplier<HttpFields> getTrailers()
|
||||
{
|
||||
return _trailers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<Map<String,String>> getTrailerFields()
|
||||
{
|
||||
if (_trailers instanceof HttpFieldsSupplier)
|
||||
((HttpFieldsSupplier)_trailers).getSupplier();
|
||||
return null;
|
||||
return trailers;
|
||||
}
|
||||
|
||||
protected MetaData.Response newResponseMetaData()
|
||||
@ -1502,33 +1487,4 @@ public class Response implements HttpServletResponse
|
||||
response.setHeader(HttpHeader.ETAG.asString(),et);
|
||||
}
|
||||
}
|
||||
|
||||
private static class HttpFieldsSupplier implements Supplier<HttpFields>
|
||||
{
|
||||
private final Supplier<Map<String, String>> _supplier;
|
||||
|
||||
public HttpFieldsSupplier(Supplier<Map<String, String>> trailers)
|
||||
{
|
||||
_supplier = trailers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpFields get()
|
||||
{
|
||||
Map<String,String> t = _supplier.get();
|
||||
if (t==null)
|
||||
return null;
|
||||
HttpFields fields = new HttpFields();
|
||||
for (Map.Entry<String,String> e : t.entrySet())
|
||||
{
|
||||
fields.add(e.getKey(),e.getValue());
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
public Supplier<Map<String, String>> getSupplier()
|
||||
{
|
||||
return _supplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,11 @@ package org.eclipse.jetty.util;
|
||||
* <p>Parse a string in the form "host:port", handling IPv4 an IPv6 hosts</p>
|
||||
*
|
||||
* <p>The System property "org.eclipse.jetty.util.HostPort.STRIP_IPV6" can be set to a boolean
|
||||
* value to control of the square brackets are stripped off IPv6 addresses (default true).</p>
|
||||
* value to control of the square brackets are stripped off IPv6 addresses (default false).</p>
|
||||
*/
|
||||
public class HostPort
|
||||
{
|
||||
private final static boolean STRIP_IPV6 = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.HostPort.STRIP_IPV6","true"));
|
||||
private final static boolean STRIP_IPV6 = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.HostPort.STRIP_IPV6","false"));
|
||||
|
||||
private final String _host;
|
||||
private final int _port;
|
||||
|
@ -20,16 +20,13 @@ package org.eclipse.jetty.websocket.jsr356;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
@ -58,6 +55,7 @@ import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.client.io.UpgradeListener;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||
import org.eclipse.jetty.websocket.common.scopes.DelegatedContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.jsr356.client.AnnotatedClientEndpointConfig;
|
||||
@ -79,9 +77,8 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||
/** The delegated Container Scope */
|
||||
private final WebSocketContainerScope scopeDelegate;
|
||||
/** The jetty websocket client in use for this container */
|
||||
private WebSocketClient client;
|
||||
|
||||
private List<Function<Object, EndpointConfig>> annotatedConfigFunctions = new ArrayList<>();
|
||||
private final WebSocketClient client;
|
||||
private final boolean internalClient;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #ClientContainer(WebSocketContainerScope)}
|
||||
@ -94,18 +91,64 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||
client.setDaemon(true);
|
||||
}
|
||||
|
||||
public ClientContainer(WebSocketContainerScope scope)
|
||||
/**
|
||||
* This is the entry point for ServerContainer, via ServletContext.getAttribute(ServerContainer.class.getName())
|
||||
*
|
||||
* @param scope the scope of the ServerContainer
|
||||
*/
|
||||
public ClientContainer(final WebSocketContainerScope scope)
|
||||
{
|
||||
boolean trustAll = Boolean.getBoolean("org.eclipse.jetty.websocket.jsr356.ssl-trust-all");
|
||||
this(scope, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the entry point for ServerContainer, via ServletContext.getAttribute(ServerContainer.class.getName())
|
||||
*
|
||||
* @param scope the scope of the ServerContainer
|
||||
* @param httpClient the HttpClient instance to use
|
||||
*/
|
||||
protected ClientContainer(final WebSocketContainerScope scope, final HttpClient httpClient)
|
||||
{
|
||||
String jsr356TrustAll = System.getProperty("org.eclipse.jetty.websocket.jsr356.ssl-trust-all");
|
||||
|
||||
WebSocketContainerScope clientScope;
|
||||
if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT)
|
||||
{
|
||||
clientScope = scope;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to wrap the scope for the CLIENT Policy behaviors
|
||||
clientScope = new DelegatedContainerScope(WebSocketPolicy.newClientPolicy(), scope);
|
||||
}
|
||||
|
||||
this.scopeDelegate = clientScope;
|
||||
this.client = new WebSocketClient(scopeDelegate);
|
||||
this.client.setSessionFactory(new JsrSessionFactory(this));
|
||||
this.internalClient = true;
|
||||
|
||||
if(jsr356TrustAll != null)
|
||||
{
|
||||
boolean trustAll = Boolean.parseBoolean(jsr356TrustAll);
|
||||
client.getSslContextFactory().setTrustAll(trustAll);
|
||||
}
|
||||
|
||||
this.scopeDelegate = scope;
|
||||
client = new WebSocketClient(scope, new SslContextFactory(trustAll));
|
||||
client.setSessionFactory(new JsrSessionFactory(this));
|
||||
addBean(client);
|
||||
|
||||
ShutdownThread.register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a ClientContainer with a specific WebSocketClient in mind.
|
||||
*
|
||||
* @param client the WebSocketClient to use.
|
||||
*/
|
||||
public ClientContainer(WebSocketClient client)
|
||||
{
|
||||
this.scopeDelegate = client;
|
||||
this.client = client;
|
||||
this.client.setSessionFactory(new JsrSessionFactory(this));
|
||||
this.internalClient = false;
|
||||
}
|
||||
|
||||
public EndpointFunctions newJsrEndpointFunction(Object endpoint,
|
||||
WebSocketPolicy sessionPolicy,
|
||||
AvailableEncoders availableEncoders,
|
||||
@ -124,10 +167,26 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||
|
||||
private Session connect(ConfiguredEndpoint instance, URI path) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(instance, "EndpointInstance cannot be null");
|
||||
Objects.requireNonNull(path, "Path cannot be null");
|
||||
synchronized (this.client)
|
||||
{
|
||||
if (this.internalClient && !this.client.isStarted())
|
||||
{
|
||||
try
|
||||
{
|
||||
this.client.start();
|
||||
addManaged(this.client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Unable to start Client", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClientEndpointConfig config = (ClientEndpointConfig) instance.getConfig();
|
||||
Objects.requireNonNull(instance,"EndpointInstance cannot be null");
|
||||
Objects.requireNonNull(path,"Path cannot be null");
|
||||
|
||||
ClientEndpointConfig config = (ClientEndpointConfig)instance.getConfig();
|
||||
ClientUpgradeRequest req = new ClientUpgradeRequest();
|
||||
UpgradeListener upgradeListener = null;
|
||||
|
||||
|
@ -24,7 +24,13 @@ import java.util.concurrent.Executor;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.ShutdownThread;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||
|
||||
@ -45,7 +51,7 @@ public class JettyClientContainerProvider extends ContainerProvider
|
||||
private static boolean useServerContainer = false;
|
||||
private static Executor commonExecutor;
|
||||
private static ByteBufferPool commonBufferPool;
|
||||
|
||||
|
||||
private static Object lock = new Object();
|
||||
|
||||
/**
|
||||
@ -141,35 +147,34 @@ public class JettyClientContainerProvider extends ContainerProvider
|
||||
@Override
|
||||
protected WebSocketContainer getContainer()
|
||||
{
|
||||
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy());
|
||||
QueuedThreadPool threadPool= new QueuedThreadPool();
|
||||
String name = "qtp-JSR356CLI-" + hashCode();
|
||||
threadPool.setName(name);
|
||||
threadPool.setDaemon(true);
|
||||
containerScope.setExecutor(threadPool);
|
||||
containerScope.addBean(threadPool);
|
||||
ClientContainer container = new ClientContainer(containerScope);
|
||||
try
|
||||
{
|
||||
// We need to start this container properly.
|
||||
container.start();
|
||||
return container;
|
||||
}
|
||||
catch (Exception e)
|
||||
synchronized (lock)
|
||||
{
|
||||
WebSocketContainer webSocketContainer = null;
|
||||
Object contextHandler = getContextHandler();
|
||||
|
||||
if (useServerContainer && contextHandler != null)
|
||||
{
|
||||
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy());
|
||||
QueuedThreadPool threadPool= new QueuedThreadPool();
|
||||
String name = "Jsr356Client@" + hashCode();
|
||||
threadPool.setName(name);
|
||||
threadPool.setDaemon(true);
|
||||
containerScope.setExecutor(threadPool);
|
||||
containerScope.addBean(threadPool);
|
||||
INSTANCE = new ClientContainer(containerScope);
|
||||
try
|
||||
{
|
||||
// Attempt to use the ServerContainer attribute.
|
||||
Method methodGetServletContext = contextHandler.getClass().getMethod("getServletContext");
|
||||
Object objServletContext = methodGetServletContext.invoke(contextHandler);
|
||||
if (objServletContext != null)
|
||||
{
|
||||
Method methodGetAttribute = objServletContext.getClass().getMethod("getAttribute", String.class);
|
||||
Object objServerContainer = methodGetAttribute.invoke(objServletContext, "javax.websocket.server.ServerContainer");
|
||||
if (objServerContainer != null && objServerContainer instanceof WebSocketContainer)
|
||||
{
|
||||
webSocketContainer = (WebSocketContainer) objServerContainer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Throwable ignore)
|
||||
{
|
||||
LOG.ignore(ignore);
|
||||
// continue, without server container
|
||||
}
|
||||
}
|
||||
|
||||
if (useSingleton && INSTANCE != null)
|
||||
@ -188,12 +193,12 @@ public class JettyClientContainerProvider extends ContainerProvider
|
||||
threadPool.setDaemon(true);
|
||||
commonExecutor = threadPool;
|
||||
}
|
||||
|
||||
|
||||
if (commonBufferPool == null)
|
||||
{
|
||||
commonBufferPool = new MappedByteBufferPool();
|
||||
}
|
||||
|
||||
|
||||
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(), commonBufferPool, commonExecutor, null);
|
||||
ClientContainer clientContainer = new ClientContainer(containerScope);
|
||||
|
||||
@ -209,7 +214,7 @@ public class JettyClientContainerProvider extends ContainerProvider
|
||||
// register JVM wide shutdown thread
|
||||
ShutdownThread.register(clientContainer);
|
||||
}
|
||||
|
||||
|
||||
if (!clientContainer.isStarted())
|
||||
{
|
||||
try
|
||||
|
@ -42,7 +42,6 @@ import javax.websocket.WebSocketContainer;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -37,6 +37,7 @@ import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
@ -46,7 +47,7 @@ import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.AvailableDecoders;
|
||||
import org.eclipse.jetty.websocket.jsr356.encoders.AvailableEncoders;
|
||||
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.server.NativeWebSocketConfiguration;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
|
||||
@ManagedObject("JSR356 Server Container")
|
||||
@ -54,18 +55,47 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ServerContainer.class);
|
||||
|
||||
private final MappedWebSocketCreator mappedCreator;
|
||||
private final WebSocketServerFactory webSocketServerFactory;
|
||||
/**
|
||||
* Get the WebSocketContainer out of the current ThreadLocal reference
|
||||
* of the active ContextHandler.
|
||||
*
|
||||
* @return the WebSocketContainer if found, null if not found.
|
||||
*/
|
||||
public static WebSocketContainer getWebSocketContainer()
|
||||
{
|
||||
ContextHandler.Context context = ContextHandler.getCurrentContext();
|
||||
if (context == null)
|
||||
return null;
|
||||
|
||||
ContextHandler handler = ContextHandler.getContextHandler(context);
|
||||
if (handler == null)
|
||||
return null;
|
||||
|
||||
if (!(handler instanceof ServletContextHandler))
|
||||
return null;
|
||||
|
||||
return (javax.websocket.WebSocketContainer) handler.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
|
||||
}
|
||||
|
||||
private final NativeWebSocketConfiguration configuration;
|
||||
private List<Class<?>> deferredEndpointClasses;
|
||||
private List<ServerEndpointConfig> deferredEndpointConfigs;
|
||||
|
||||
public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor)
|
||||
/**
|
||||
* @deprecated use {@code ServerContainer(NativeWebSocketConfiguration, HttpClient)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public ServerContainer(NativeWebSocketConfiguration configuration, Executor executor)
|
||||
{
|
||||
super(factory);
|
||||
this.mappedCreator = creator;
|
||||
this.webSocketServerFactory = factory;
|
||||
this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this));
|
||||
addBean(webSocketServerFactory);
|
||||
this(configuration, (HttpClient) null);
|
||||
}
|
||||
|
||||
public ServerContainer(NativeWebSocketConfiguration configuration, HttpClient httpClient)
|
||||
{
|
||||
super(configuration.getFactory(), httpClient);
|
||||
this.configuration = configuration;
|
||||
this.configuration.getFactory().addSessionFactory(new JsrSessionFactory(this));
|
||||
addBean(this.configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,7 +153,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||
deferredEndpointClasses.add(endpointClass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a ServerEndpointConfig to the server
|
||||
*
|
||||
@ -161,8 +191,8 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||
{
|
||||
assertIsValidEndpoint(config);
|
||||
|
||||
JsrCreator creator = new JsrCreator(this, config, webSocketServerFactory.getExtensionFactory());
|
||||
mappedCreator.addMapping(new UriTemplatePathSpec(config.getPath()), creator);
|
||||
JsrCreator creator = new JsrCreator(this, config, this.configuration.getFactory().getExtensionFactory());
|
||||
this.configuration.addMapping(new UriTemplatePathSpec(config.getPath()), creator);
|
||||
}
|
||||
|
||||
private void assertIsValidEndpoint(ServerEndpointConfig config) throws DeploymentException
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -82,34 +82,6 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Jetty Native approach.
|
||||
* <p>
|
||||
* Note: this will add the Upgrade filter to the existing list, with no regard for order. It will just be tacked onto the end of the list.
|
||||
*
|
||||
* @param context the servlet context handler
|
||||
* @return the created websocket server container
|
||||
* @throws ServletException if unable to create the websocket server container
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public static ServerContainer configureContext(ServletContextHandler context) throws ServletException
|
||||
{
|
||||
// Create Filter
|
||||
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
|
||||
filter.getFactory().init(context);
|
||||
|
||||
// Create the Jetty ServerContainer implementation
|
||||
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),context.getServer().getThreadPool());
|
||||
context.addBean(jettyContainer, true);
|
||||
|
||||
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
|
||||
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
|
||||
|
||||
return jettyContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a ServletContext for {@code init-param} or {@code attribute} at {@code keyName} for
|
||||
* true or false setting that determines if the specified feature is enabled (or not).
|
||||
@ -119,24 +91,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||
* @param defValue the default value, if the value is not specified in the context
|
||||
* @return the value for the feature key
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public static ServerContainer configureContext(ServletContext context, ServletContextHandler jettyContext) throws ServletException
|
||||
{
|
||||
// Create Filter
|
||||
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
|
||||
filter.getFactory().init(context);
|
||||
|
||||
// Create the Jetty ServerContainer implementation
|
||||
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),jettyContext.getServer().getThreadPool());
|
||||
jettyContext.addBean(jettyContainer, true);
|
||||
|
||||
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
|
||||
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
|
||||
|
||||
return jettyContainer;
|
||||
}
|
||||
|
||||
private boolean isEnabled(Set<Class<?>> c, ServletContext context)
|
||||
public static boolean isEnabledViaContext(ServletContext context, String keyName, boolean defValue)
|
||||
{
|
||||
// Try context parameters first
|
||||
String cp = context.getInitParameter(keyName);
|
||||
@ -176,7 +131,13 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||
}
|
||||
|
||||
/**
|
||||
* Embedded Jetty approach for non-bytecode scanning.
|
||||
* Jetty Native approach.
|
||||
* <p>
|
||||
* Note: this will add the Upgrade filter to the existing list, with no regard for order. It will just be tacked onto the end of the list.
|
||||
*
|
||||
* @param context the servlet context handler
|
||||
* @return the created websocket server container
|
||||
* @throws ServletException if unable to create the websocket server container
|
||||
*/
|
||||
public static ServerContainer configureContext(ServletContextHandler context) throws ServletException
|
||||
{
|
||||
@ -248,7 +209,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||
try(ThreadClassLoaderScope scope = new ThreadClassLoaderScope(context.getClassLoader()))
|
||||
{
|
||||
// Create the Jetty ServerContainer implementation
|
||||
ServerContainer jettyContainer = configureContext(context,jettyContext);
|
||||
ServerContainer jettyContainer = configureContext(jettyContext);
|
||||
context.addListener(new ContextDestroyListener()); // make sure context is cleaned up when the context stops
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -35,10 +35,10 @@ public class WebSocketPolicy
|
||||
return new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||
}
|
||||
|
||||
/* NOTE TO OTHER DEVELOPERS:
|
||||
/* NOTE TO OTHER DEVELOPERS:
|
||||
* If you change any of these default values,
|
||||
* make sure you sync the values with
|
||||
* org.eclipse.jetty.websocket.api.annotations.WebSocket
|
||||
* make sure you sync the values with
|
||||
* org.eclipse.jetty.websocket.api.annotations.WebSocket
|
||||
* annotation defaults
|
||||
*/
|
||||
|
||||
@ -53,11 +53,13 @@ public class WebSocketPolicy
|
||||
|
||||
/**
|
||||
* The maximum size of a text message buffer.
|
||||
* @deprecated see {@link #inputBufferSize}, {@link #outputBufferSize}, and {@link #maxAllowedFrameSize}
|
||||
* <p>
|
||||
* Used ONLY for stream based message writing.
|
||||
* <p>
|
||||
* Default: 32768 (32 K)
|
||||
*/
|
||||
@Deprecated
|
||||
private int maxTextMessageBufferSize;
|
||||
|
||||
private int maxTextMessageBufferSize = 32 * KB;
|
||||
|
||||
/**
|
||||
* The maximum size of a binary message during parsing/generating.
|
||||
* <p>
|
||||
@ -70,10 +72,11 @@ public class WebSocketPolicy
|
||||
/**
|
||||
* The maximum size of a binary message buffer
|
||||
* <p>
|
||||
* @deprecated see {@link #inputBufferSize}, {@link #outputBufferSize}, and {@link #maxAllowedFrameSize}
|
||||
* Used ONLY for for stream based message writing
|
||||
* <p>
|
||||
* Default: 32768 (32 K)
|
||||
*/
|
||||
@Deprecated
|
||||
private int maxBinaryMessageBufferSize;
|
||||
private int maxBinaryMessageBufferSize = 32 * KB;
|
||||
|
||||
/**
|
||||
* The timeout in ms (milliseconds) for async write operations.
|
||||
@ -168,7 +171,9 @@ public class WebSocketPolicy
|
||||
WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
|
||||
clone.idleTimeout = this.idleTimeout;
|
||||
clone.maxTextMessageSize = this.maxTextMessageSize;
|
||||
clone.maxTextMessageBufferSize = this.maxTextMessageBufferSize;
|
||||
clone.maxBinaryMessageSize = this.maxBinaryMessageSize;
|
||||
clone.maxBinaryMessageBufferSize = this.maxBinaryMessageBufferSize;
|
||||
clone.inputBufferSize = this.inputBufferSize;
|
||||
clone.outputBufferSize = this.outputBufferSize;
|
||||
clone.maxAllowedFrameSize = this.maxAllowedFrameSize;
|
||||
@ -208,7 +213,7 @@ public class WebSocketPolicy
|
||||
* <p>
|
||||
* This is the raw read operation buffer size, before the parsing of the websocket frames.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return the raw network buffer input size.
|
||||
*/
|
||||
public int getInputBufferSize()
|
||||
@ -248,12 +253,10 @@ public class WebSocketPolicy
|
||||
/**
|
||||
* Get the maximum size of a binary message buffer.
|
||||
* @return the maximum size of a binary message buffer
|
||||
* @deprecated see {@link #getInputBufferSize()}, {@link #getOutputBufferSize()}, and {@link #getMaxAllowedFrameSize()}
|
||||
*/
|
||||
@Deprecated
|
||||
public int getMaxBinaryMessageBufferSize()
|
||||
{
|
||||
return maxBinaryMessageSize;
|
||||
return maxBinaryMessageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -269,14 +272,13 @@ public class WebSocketPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum size of a text message buffer.
|
||||
* Get the maximum size of a text message buffer (for streaming writing)
|
||||
*
|
||||
* @return the maximum size of a text message buffer
|
||||
* @deprecated see {@link #getInputBufferSize()}, {@link #getOutputBufferSize()}, and {@link #getMaxAllowedFrameSize()}
|
||||
*/
|
||||
@Deprecated
|
||||
public int getMaxTextMessageBufferSize()
|
||||
{
|
||||
return maxTextMessageSize;
|
||||
return maxTextMessageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,15 +371,17 @@ public class WebSocketPolicy
|
||||
|
||||
/**
|
||||
* The maximum size of a binary message buffer.
|
||||
*
|
||||
* <p>
|
||||
* Used ONLY for stream based message writing.
|
||||
*
|
||||
* @param size
|
||||
* the maximum size of the binary message buffer
|
||||
* @deprecated see {@link #getInputBufferSize()}, {@link #getOutputBufferSize()}, and {@link #getMaxAllowedFrameSize()}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setMaxBinaryMessageBufferSize(int size)
|
||||
{
|
||||
/* does nothing */
|
||||
assertGreaterThan("MaxBinaryMessageBufferSize",size,1);
|
||||
|
||||
this.maxBinaryMessageBufferSize = size;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -410,22 +414,22 @@ public class WebSocketPolicy
|
||||
{
|
||||
if(size < 0) return; // no change (likely came from annotation)
|
||||
|
||||
assertGreaterThan("MaxBinaryMessageSize",size,1);
|
||||
|
||||
this.maxBinaryMessageSize = size;
|
||||
this.maxBinaryMessageSize = Math.max(-1, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum size of a text message buffer.
|
||||
*
|
||||
* <p>
|
||||
* Used ONLY for stream based message writing.
|
||||
*
|
||||
* @param size
|
||||
* the maximum size of the text message buffer
|
||||
* @deprecated see {@link #getInputBufferSize()}, {@link #getOutputBufferSize()}, and {@link #getMaxAllowedFrameSize()}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setMaxTextMessageBufferSize(int size)
|
||||
{
|
||||
/* does nothing */
|
||||
assertGreaterThan("MaxTextMessageBufferSize",size,1);
|
||||
|
||||
this.maxTextMessageBufferSize = size;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -444,7 +448,7 @@ public class WebSocketPolicy
|
||||
}
|
||||
this.setMaxTextMessageSize((int) size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The maximum size of a text message during parsing/generating.
|
||||
* <p>
|
||||
@ -457,9 +461,7 @@ public class WebSocketPolicy
|
||||
{
|
||||
if(size < 0) return; // no change (likely came from annotation)
|
||||
|
||||
assertGreaterThan("MaxTextMessageSize",size,1);
|
||||
|
||||
this.maxTextMessageSize = size;
|
||||
this.maxTextMessageSize = Math.max(-1, size);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StringBufferReplaceableByString")
|
||||
|
@ -42,42 +42,25 @@ public final class WSURI
|
||||
{
|
||||
Objects.requireNonNull(inputUri,"Input URI must not be null");
|
||||
String wsScheme = inputUri.getScheme();
|
||||
String httpScheme;
|
||||
//noinspection UnusedAssignment
|
||||
int port = -1;
|
||||
if ("http".equalsIgnoreCase(wsScheme))
|
||||
if ("http".equalsIgnoreCase(wsScheme) || "https".equalsIgnoreCase(wsScheme))
|
||||
{
|
||||
// leave alone
|
||||
httpScheme = wsScheme;
|
||||
}
|
||||
else if ("https".equalsIgnoreCase(wsScheme))
|
||||
{
|
||||
// leave alone
|
||||
httpScheme = wsScheme;
|
||||
return inputUri;
|
||||
}
|
||||
|
||||
if ("ws".equalsIgnoreCase(wsScheme))
|
||||
{
|
||||
// convert to http
|
||||
httpScheme = "http";
|
||||
return new URI("http" + inputUri.toString().substring(wsScheme.length()));
|
||||
}
|
||||
|
||||
if ("wss".equalsIgnoreCase(wsScheme))
|
||||
{
|
||||
// convert to https
|
||||
httpScheme = "https";
|
||||
return new URI("https" + inputUri.toString().substring(wsScheme.length()));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new URISyntaxException(inputUri.toString(),"Unrecognized WebSocket scheme");
|
||||
}
|
||||
|
||||
if (inputUri.getPort() > 0)
|
||||
{
|
||||
port = inputUri.getPort();
|
||||
}
|
||||
|
||||
return new URI(httpScheme,inputUri.getUserInfo(),inputUri.getHost(),port,inputUri.getPath(),inputUri.getQuery(),inputUri.getFragment());
|
||||
|
||||
throw new URISyntaxException(inputUri.toString(),"Unrecognized WebSocket scheme");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,40 +117,24 @@ public final class WSURI
|
||||
{
|
||||
Objects.requireNonNull(inputUri,"Input URI must not be null");
|
||||
String httpScheme = inputUri.getScheme();
|
||||
String wsScheme;
|
||||
//noinspection UnusedAssignment
|
||||
int port = -1;
|
||||
if ("ws".equalsIgnoreCase(httpScheme))
|
||||
if ("ws".equalsIgnoreCase(httpScheme) || "wss".equalsIgnoreCase(httpScheme))
|
||||
{
|
||||
// keep as-is
|
||||
wsScheme = httpScheme;
|
||||
}
|
||||
else if ("wss".equalsIgnoreCase(httpScheme))
|
||||
{
|
||||
// keep as-is
|
||||
wsScheme = httpScheme;
|
||||
return inputUri;
|
||||
}
|
||||
|
||||
if ("http".equalsIgnoreCase(httpScheme))
|
||||
{
|
||||
// convert to ws
|
||||
wsScheme = "ws";
|
||||
return new URI("ws" + inputUri.toString().substring(httpScheme.length()));
|
||||
}
|
||||
|
||||
if ("https".equalsIgnoreCase(httpScheme))
|
||||
{
|
||||
// convert to wss
|
||||
wsScheme = "wss";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new URISyntaxException(inputUri.toString(),"Unrecognized HTTP scheme");
|
||||
return new URI("wss" + inputUri.toString().substring(httpScheme.length()));
|
||||
}
|
||||
|
||||
if (inputUri.getPort() > 0)
|
||||
{
|
||||
port = inputUri.getPort();
|
||||
}
|
||||
return new URI(wsScheme,inputUri.getUserInfo(),inputUri.getHost(),port,inputUri.getPath(),inputUri.getQuery(),inputUri.getFragment());
|
||||
throw new URISyntaxException(inputUri.toString(),"Unrecognized HTTP scheme");
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
@ -64,22 +63,16 @@ import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
public class WebSocketClient extends ContainerLifeCycle implements WebSocketContainerScope
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketClient.class);
|
||||
|
||||
private final WebSocketPolicy containerPolicy;
|
||||
private final SslContextFactory sslContextFactory;
|
||||
|
||||
// From HttpClient
|
||||
private final HttpClient httpClient;
|
||||
|
||||
//
|
||||
private final WebSocketContainerScope containerScope;
|
||||
private final WebSocketExtensionFactory extensionRegistry;
|
||||
private boolean daemon = false;
|
||||
private SessionFactory sessionFactory;
|
||||
private ByteBufferPool bufferPool;
|
||||
private Executor executor;
|
||||
private DecoratedObjectFactory objectFactory;
|
||||
private Scheduler scheduler;
|
||||
private CookieStore cookieStore;
|
||||
private ConnectionManager connectionManager;
|
||||
private Masker masker;
|
||||
private SocketAddress bindAddress;
|
||||
private long connectTimeout = SelectorManager.DEFAULT_CONNECT_TIMEOUT;
|
||||
private boolean dispatchIO = true;
|
||||
|
||||
private final int id = ThreadLocalRandom.current().nextInt();
|
||||
|
||||
/**
|
||||
* Instantiate a WebSocketClient with defaults
|
||||
@ -115,7 +108,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
this.containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(),new MappedByteBufferPool(),objectFactory);
|
||||
this.httpClient = httpClient;
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(containerScope);
|
||||
this.eventDriverFactory = new EventDriverFactory(containerScope);
|
||||
this.sessionFactory = new WebSocketSessionFactory(containerScope);
|
||||
}
|
||||
|
||||
@ -196,27 +188,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
*/
|
||||
public WebSocketClient(WebSocketContainerScope scope, SslContextFactory sslContextFactory)
|
||||
{
|
||||
this.containerPolicy = scope.getPolicy();
|
||||
this.sslContextFactory = sslContextFactory;
|
||||
this.objectFactory = scope.getObjectFactory();
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(this);
|
||||
this.masker = new RandomMasker();
|
||||
|
||||
setExecutor(scope.getExecutor());
|
||||
setBufferPool(scope.getBufferPool());
|
||||
|
||||
if (scope instanceof LifeCycle)
|
||||
{
|
||||
addBean(scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sslContextFactory != null)
|
||||
addBean(sslContextFactory);
|
||||
addBean(this.executor);
|
||||
addBean(this.sslContextFactory);
|
||||
addBean(this.bufferPool);
|
||||
}
|
||||
this(sslContextFactory, scope.getExecutor(), scope.getBufferPool(), scope.getObjectFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,7 +231,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(containerScope);
|
||||
|
||||
this.eventDriverFactory = new EventDriverFactory(containerScope);
|
||||
this.sessionFactory = new WebSocketSessionFactory(containerScope);
|
||||
}
|
||||
|
||||
@ -286,7 +257,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
* @param sessionFactory
|
||||
* the SessionFactory to use
|
||||
*/
|
||||
public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory)
|
||||
public WebSocketClient(final WebSocketContainerScope scope, SessionFactory sessionFactory, HttpClient httpClient)
|
||||
{
|
||||
WebSocketContainerScope clientScope;
|
||||
if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT)
|
||||
@ -300,15 +271,17 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
}
|
||||
|
||||
this.containerScope = clientScope;
|
||||
SslContextFactory sslContextFactory = scope.getSslContextFactory();
|
||||
if(sslContextFactory == null)
|
||||
|
||||
if(httpClient == null)
|
||||
{
|
||||
sslContextFactory = new SslContextFactory();
|
||||
this.httpClient = HttpClientProvider.get(scope);
|
||||
addBean(this.httpClient);
|
||||
}
|
||||
this.httpClient = new HttpClient(sslContextFactory);
|
||||
this.httpClient.setExecutor(getExecutor(scope.getExecutor()));
|
||||
addBean(this.httpClient);
|
||||
|
||||
else
|
||||
{
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(containerScope);
|
||||
|
||||
this.sessionFactory = sessionFactory;
|
||||
@ -435,7 +408,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
*/
|
||||
public long getAsyncWriteTimeout()
|
||||
{
|
||||
return this.containerPolicy.getAsyncWriteTimeout();
|
||||
return getPolicy().getAsyncWriteTimeout();
|
||||
}
|
||||
|
||||
public SocketAddress getBindAddress()
|
||||
@ -511,7 +484,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
*/
|
||||
public long getMaxBinaryMessageSize()
|
||||
{
|
||||
return this.containerPolicy.getMaxBinaryMessageSize();
|
||||
return getPolicy().getMaxBinaryMessageSize();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -521,7 +494,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
*/
|
||||
public long getMaxIdleTimeout()
|
||||
{
|
||||
return this.containerPolicy.getIdleTimeout();
|
||||
return getPolicy().getIdleTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -544,7 +517,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
*/
|
||||
public long getMaxTextMessageSize()
|
||||
{
|
||||
return this.containerPolicy.getMaxTextMessageSize();
|
||||
return getPolicy().getMaxTextMessageSize();
|
||||
}
|
||||
|
||||
public DecoratedObjectFactory getObjectFactory()
|
||||
@ -559,7 +532,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
|
||||
public WebSocketPolicy getPolicy()
|
||||
{
|
||||
return this.containerPolicy;
|
||||
return this.containerScope.getPolicy();
|
||||
}
|
||||
|
||||
public SessionFactory getSessionFactory()
|
||||
@ -603,7 +576,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
|
||||
public void setAsyncWriteTimeout(long ms)
|
||||
{
|
||||
this.containerPolicy.setAsyncWriteTimeout(ms);
|
||||
getPolicy().setAsyncWriteTimeout(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -655,7 +628,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
||||
@Deprecated
|
||||
public void setDispatchIO(boolean dispatchIO)
|
||||
{
|
||||
this.dispatchIO = dispatchIO;
|
||||
this.httpClient.setDispatchIO(dispatchIO);
|
||||
}
|
||||
|
||||
public void setExecutor(Executor executor)
|
||||
|
@ -67,7 +67,6 @@ import org.eclipse.jetty.websocket.client.io.WebSocketClientConnection;
|
||||
import org.eclipse.jetty.websocket.common.AcceptHash;
|
||||
import org.eclipse.jetty.websocket.common.SessionFactory;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
import org.eclipse.jetty.websocket.common.extensions.ExtensionStack;
|
||||
|
||||
public class WebSocketUpgradeRequest extends HttpRequest implements CompleteListener, HttpConnectionUpgrader
|
||||
@ -353,8 +352,8 @@ public class WebSocketUpgradeRequest extends HttpRequest implements CompleteList
|
||||
}
|
||||
|
||||
private final WebSocketClient wsClient;
|
||||
private final EventDriver localEndpoint;
|
||||
private final CompletableFuture<Session> fut;
|
||||
private final Object localEndpoint;
|
||||
/** WebSocket API UpgradeRequest Facade to HttpClient HttpRequest */
|
||||
private final ClientUpgradeRequestFacade apiRequestFacade;
|
||||
private UpgradeListener upgradeListener;
|
||||
@ -526,7 +525,6 @@ public class WebSocketUpgradeRequest extends HttpRequest implements CompleteList
|
||||
|
||||
private void handleException(Throwable failure)
|
||||
{
|
||||
localEndpoint.incomingError(failure);
|
||||
fut.completeExceptionally(failure);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ import org.eclipse.jetty.websocket.common.frames.CloseFrame;
|
||||
|
||||
public class CloseInfo
|
||||
{
|
||||
private int statusCode;
|
||||
private int statusCode = 0;
|
||||
private String reason;
|
||||
|
||||
public CloseInfo()
|
||||
@ -124,7 +124,28 @@ public class CloseInfo
|
||||
this.statusCode = statusCode;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
|
||||
private void assertValidStatusCode(int statusCode)
|
||||
{
|
||||
// Status Codes outside of RFC6455 defined scope
|
||||
if ((statusCode <= 999) || (statusCode >= 5000))
|
||||
{
|
||||
throw new ProtocolException("Out of range close status code: " + statusCode);
|
||||
}
|
||||
|
||||
// Status Codes not allowed to exist in a Close frame (per RFC6455)
|
||||
if ((statusCode == StatusCode.NO_CLOSE) || (statusCode == StatusCode.NO_CODE) || (statusCode == StatusCode.FAILED_TLS_HANDSHAKE))
|
||||
{
|
||||
throw new ProtocolException("Frame forbidden close status code: " + statusCode);
|
||||
}
|
||||
|
||||
// Status Code is in defined "reserved space" and is declared (all others are invalid)
|
||||
if ((statusCode >= 1000) && (statusCode <= 2999) && !StatusCode.isTransmittable(statusCode))
|
||||
{
|
||||
throw new ProtocolException("RFC6455 and IANA Undefined close status code: " + statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a raw status code and reason into a WebSocket Close frame payload buffer.
|
||||
*
|
||||
@ -139,11 +160,11 @@ public class CloseInfo
|
||||
// codes that are not allowed to be used in endpoint.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
int len = 2; // status code
|
||||
|
||||
|
||||
byte reasonBytes[] = null;
|
||||
|
||||
|
||||
if (reason != null)
|
||||
{
|
||||
byte[] utf8Bytes = reason.getBytes(StandardCharsets.UTF_8);
|
||||
@ -156,24 +177,24 @@ public class CloseInfo
|
||||
{
|
||||
reasonBytes = utf8Bytes;
|
||||
}
|
||||
|
||||
|
||||
if ((reasonBytes != null) && (reasonBytes.length > 0))
|
||||
{
|
||||
len += reasonBytes.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ByteBuffer buf = BufferUtil.allocate(len);
|
||||
BufferUtil.flipToFill(buf);
|
||||
buf.put((byte) ((statusCode >>> 8) & 0xFF));
|
||||
buf.put((byte) ((statusCode >>> 0) & 0xFF));
|
||||
|
||||
|
||||
if ((reasonBytes != null) && (reasonBytes.length > 0))
|
||||
{
|
||||
buf.put(reasonBytes, 0, reasonBytes.length);
|
||||
}
|
||||
BufferUtil.flipToFlush(buf, 0);
|
||||
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -194,7 +215,7 @@ public class CloseInfo
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
public String getReason()
|
||||
{
|
||||
return this.reason;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -34,46 +34,51 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
|
||||
private final ByteBufferPool bufferPool;
|
||||
private final DecoratedObjectFactory objectFactory;
|
||||
private final WebSocketPolicy containerPolicy;
|
||||
private Executor executor;
|
||||
private final Executor executor;
|
||||
private SslContextFactory sslContextFactory;
|
||||
|
||||
public SimpleContainerScope(WebSocketPolicy containerPolicy)
|
||||
public SimpleContainerScope(WebSocketPolicy policy)
|
||||
{
|
||||
this(containerPolicy, new MappedByteBufferPool(), new DecoratedObjectFactory());
|
||||
this(policy, new MappedByteBufferPool(), new DecoratedObjectFactory());
|
||||
this.sslContextFactory = new SslContextFactory();
|
||||
}
|
||||
|
||||
public SimpleContainerScope(WebSocketPolicy containerPolicy, ByteBufferPool bufferPool)
|
||||
public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||
{
|
||||
this(containerPolicy, bufferPool, new DecoratedObjectFactory());
|
||||
this(policy, bufferPool, new DecoratedObjectFactory());
|
||||
}
|
||||
|
||||
public SimpleContainerScope(WebSocketPolicy containerPolicy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory)
|
||||
public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory)
|
||||
{
|
||||
this.containerPolicy = containerPolicy;
|
||||
this(policy, bufferPool, null, objectFactory);
|
||||
}
|
||||
|
||||
public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, Executor executor, DecoratedObjectFactory objectFactory)
|
||||
{
|
||||
this.containerPolicy = policy;
|
||||
this.bufferPool = bufferPool;
|
||||
this.objectFactory = objectFactory;
|
||||
}
|
||||
if (objectFactory == null)
|
||||
{
|
||||
this.objectFactory = new DecoratedObjectFactory();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.objectFactory = objectFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if(this.executor == null)
|
||||
if (executor == null)
|
||||
{
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
String name = this.getClass().getSimpleName() + ".QTP@" + hashCode();
|
||||
String name = "WebSocketContainer@" + hashCode();
|
||||
threadPool.setName(name);
|
||||
threadPool.setDaemon(true);
|
||||
this.executor = threadPool;
|
||||
addBean(executor);
|
||||
addBean(this.executor);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -87,12 +92,7 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
|
||||
{
|
||||
return this.executor;
|
||||
}
|
||||
|
||||
public void setExecutor(Executor executor)
|
||||
{
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DecoratedObjectFactory getObjectFactory()
|
||||
{
|
||||
|
@ -65,7 +65,14 @@ public interface WebSocketContainerScope
|
||||
* @return the SslContextFactory in use by the container (can be null if no SSL context is defined)
|
||||
*/
|
||||
SslContextFactory getSslContextFactory();
|
||||
|
||||
|
||||
/**
|
||||
* Test for if the container has been started.
|
||||
*
|
||||
* @return true if container is started and running
|
||||
*/
|
||||
boolean isRunning();
|
||||
|
||||
/**
|
||||
* A Session has been opened
|
||||
*
|
||||
|
@ -26,6 +26,11 @@ import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.common.DuplicateAnnotationException;
|
||||
|
||||
public class ReflectUtils
|
||||
{
|
||||
|
@ -14,6 +14,26 @@
|
||||
<bundle-symbolic-name>${project.groupId}.server</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Require-Capability>
|
||||
osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"
|
||||
</Require-Capability>
|
||||
<Provide-Capability>
|
||||
osgi.serviceloader; osgi.serviceloader=org.eclipse.jetty.webapp.Configuration
|
||||
</Provide-Capability>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
|
@ -120,21 +120,31 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||
|
||||
public WebSocketServerFactory(ServletContext context, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||
{
|
||||
handshakes.put(HandshakeRFC6455.VERSION, new HandshakeRFC6455());
|
||||
|
||||
addBean(scheduler);
|
||||
addBean(bufferPool);
|
||||
|
||||
this.contextClassloader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
this.registeredSocketClasses = new ArrayList<>();
|
||||
|
||||
this(Objects.requireNonNull(context, ServletContext.class.getName()), policy, null, null, bufferPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected entry point for {@link WebSocketHandler}
|
||||
*
|
||||
* @param policy the policy to use
|
||||
* @param executor the executor to use
|
||||
* @param bufferPool the buffer pool to use
|
||||
*/
|
||||
protected WebSocketServerFactory(WebSocketPolicy policy, Executor executor, ByteBufferPool bufferPool)
|
||||
{
|
||||
this(null, policy, new DecoratedObjectFactory(), executor, bufferPool);
|
||||
}
|
||||
|
||||
private WebSocketServerFactory(ServletContext context, WebSocketPolicy policy, DecoratedObjectFactory objectFactory, Executor executor, ByteBufferPool bufferPool)
|
||||
{
|
||||
this.context = context;
|
||||
this.containerPolicy = policy;
|
||||
this.objectFactory = objectFactory;
|
||||
this.executor = executor;
|
||||
this.bufferPool = bufferPool;
|
||||
|
||||
|
||||
this.creator = this;
|
||||
this.contextClassloader = Thread.currentThread().getContextClassLoader();
|
||||
this.eventDriverFactory = new EventDriverFactory(this);
|
||||
this.extensionFactory = new WebSocketExtensionFactory(this);
|
||||
|
||||
this.handshakes.put(HandshakeRFC6455.VERSION, new HandshakeRFC6455());
|
||||
@ -243,25 +253,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||
this.sessionFactories.addAll(Arrays.asList(factories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketServletFactory createFactory(WebSocketPolicy policy)
|
||||
{
|
||||
return new WebSocketServerFactory(policy, bufferPool);
|
||||
}
|
||||
|
||||
private WebSocketSession createSession(URI requestURI, Object websocket, LogicalConnection connection)
|
||||
{
|
||||
if (websocket == null)
|
||||
@ -493,11 +484,9 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||
* connection.
|
||||
* </p>
|
||||
*
|
||||
* @param http the raw http connection
|
||||
* @param request the request to upgrade
|
||||
* @param response the response to upgrade
|
||||
* @param websocket the websocket endpoint instance
|
||||
* @throws IOException if unable to upgrade
|
||||
* @param http the raw http connection
|
||||
* @param request The request to upgrade
|
||||
* @param response The response to upgrade
|
||||
*/
|
||||
private boolean upgrade(HttpConnection http, ServletUpgradeRequest request, ServletUpgradeResponse response, Object websocket) throws IOException
|
||||
{
|
||||
|
@ -43,8 +43,6 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||
|
||||
@ -134,25 +132,7 @@ public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, D
|
||||
@Override
|
||||
public void addMapping(PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
WebSocketCreator existingCreator = pathmap.get(spec);
|
||||
if (existingCreator != null)
|
||||
{
|
||||
if(existingCreator.equals(creator))
|
||||
{
|
||||
// Entry already exists, don't add it again.
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Duplicate path mapping for \"");
|
||||
err.append(spec.getDeclaration());
|
||||
err.append("\" both ");
|
||||
err.append(existingCreator);
|
||||
err.append(" and ");
|
||||
err.append(creator);
|
||||
throw new InvalidWebSocketException(err.toString());
|
||||
}
|
||||
pathmap.put(spec,creator);
|
||||
configuration.addMapping(spec, creator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,12 +244,8 @@ public class ServletUpgradeRequest implements UpgradeRequest
|
||||
return new InetSocketAddress(getLocalAddress(), getLocalPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@link HttpServletRequest#getLocale()}
|
||||
*
|
||||
* @return the preferred {@code Locale} for the client
|
||||
*/
|
||||
public Locale getLocale()
|
||||
@Override
|
||||
public String getMethod()
|
||||
{
|
||||
return request.getMethod();
|
||||
}
|
||||
@ -290,7 +286,7 @@ public class ServletUpgradeRequest implements UpgradeRequest
|
||||
public String getProtocolVersion()
|
||||
{
|
||||
String version = request.getHeader(WebSocketConstants.SEC_WEBSOCKET_VERSION);
|
||||
if(version == null)
|
||||
if(version == null)
|
||||
{
|
||||
return Integer.toString(WebSocketConstants.SPEC_VERSION);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-parent</artifactId>
|
||||
<version>10.0.0-SNAPSHOT</version>
|
||||
<version>9.4.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -131,7 +131,7 @@ public class LocalFuzzer implements AutoCloseable
|
||||
prefix = "Frame[" + i + "]";
|
||||
|
||||
WebSocketFrame expected = expect.get(i);
|
||||
WebSocketFrame actual = framesQueue.poll(10, TimeUnit.SECONDS);
|
||||
WebSocketFrame actual = framesQueue.poll(3, TimeUnit.SECONDS);
|
||||
assertThat(prefix + ".poll", actual, notNullValue());
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
@ -365,4 +365,4 @@ public class LocalFuzzer implements AutoCloseable
|
||||
|
||||
LocalConnector.LocalEndPoint newLocalConnection();
|
||||
}
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
||||
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
|
||||
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
@ -42,8 +43,12 @@ import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.PathResource;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.FragmentConfiguration;
|
||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebSocketConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
|
||||
/**
|
||||
* Utility to build out exploded directory WebApps, in the /target/tests/ directory, for testing out servers that use javax.websocket endpoints.
|
||||
@ -134,10 +139,15 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider
|
||||
context.setContextPath(this.contextPath);
|
||||
context.setBaseResource(new PathResource(this.contextDir));
|
||||
context.setAttribute("org.eclipse.jetty.websocket.jsr356", Boolean.TRUE);
|
||||
|
||||
context.addConfiguration(new AnnotationConfiguration());
|
||||
context.addConfiguration(new PlusConfiguration());
|
||||
context.addConfiguration(new WebSocketConfiguration());
|
||||
|
||||
context.setConfigurations(new Configuration[] {
|
||||
new AnnotationConfiguration(),
|
||||
new WebXmlConfiguration(),
|
||||
new WebInfConfiguration(),
|
||||
new PlusConfiguration(),
|
||||
new MetaInfConfiguration(),
|
||||
new FragmentConfiguration(),
|
||||
new EnvConfiguration()});
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -54,6 +54,7 @@ public class AnnotatedEchoTest
|
||||
public void testEcho() throws Exception
|
||||
{
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
server.addBean(container); // allow to shutdown with server
|
||||
Session session = null;
|
||||
try
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -81,6 +81,7 @@ public class ConfiguratorTest
|
||||
public void testEndpointHandshakeInfo() throws Exception
|
||||
{
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
server.addBean(container); // allow to shutdown with server
|
||||
JsrTrackingEndpoint clientSocket = new JsrTrackingEndpoint();
|
||||
|
||||
// Build Config
|
||||
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.websocket.jsr356.JettyClientContainerProvider;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.junit.After;
|
||||
|
@ -24,6 +24,9 @@ import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
@ -31,9 +34,10 @@ import java.util.concurrent.Executor;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.JettyClientContainerProvider;
|
||||
import org.eclipse.jetty.websocket.tests.server.jsr356.DelayedStartClientOnServerTest;
|
||||
import org.junit.Before;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DelayedStartClientTest
|
||||
@ -52,9 +56,56 @@ public class DelayedStartClientTest
|
||||
container = ContainerProvider.getWebSocketContainer();
|
||||
assertThat("Container", container, notNullValue());
|
||||
|
||||
List<String> threadNames = DelayedStartClientOnServerTest.getThreadNames(JettyClientContainerProvider.getInstance());
|
||||
List<String> threadNames = getThreadNames((ContainerLifeCycle)container);
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("HttpClient@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("Jsr356Client@"))));
|
||||
}
|
||||
|
||||
public static List<String> getThreadNames(ContainerLifeCycle... containers)
|
||||
{
|
||||
List<String> threadNames = new ArrayList<>();
|
||||
Set<Object> seen = new HashSet<>();
|
||||
for (ContainerLifeCycle container : containers)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
findConfiguredThreadNames(seen, threadNames, container);
|
||||
}
|
||||
seen.clear();
|
||||
// System.out.println("Threads: " + threadNames.stream().collect(Collectors.joining(", ", "[", "]")));
|
||||
return threadNames;
|
||||
}
|
||||
|
||||
private static void findConfiguredThreadNames(Set<Object> seen, List<String> threadNames, ContainerLifeCycle container)
|
||||
{
|
||||
if (seen.contains(container))
|
||||
{
|
||||
// skip
|
||||
return;
|
||||
}
|
||||
|
||||
seen.add(container);
|
||||
|
||||
Collection<Executor> executors = container.getBeans(Executor.class);
|
||||
for (Executor executor : executors)
|
||||
{
|
||||
if (executor instanceof QueuedThreadPool)
|
||||
{
|
||||
QueuedThreadPool qtp = (QueuedThreadPool) executor;
|
||||
threadNames.add(qtp.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("### Executor: " + executor);
|
||||
}
|
||||
}
|
||||
|
||||
for (ContainerLifeCycle child : container.getBeans(ContainerLifeCycle.class))
|
||||
{
|
||||
findConfiguredThreadNames(seen, threadNames, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,6 @@ public class EndpointEchoTest
|
||||
public void testEchoClassRef() throws Exception
|
||||
{
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
server.addBean(container); // allow to shutdown with server
|
||||
// Issue connect using class reference (class extends Endpoint)
|
||||
Session session = container.connectToServer(ClientEndpoint.class, server.getServerUri());
|
||||
session.getBasicRemote().sendText("Echo");
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
@ -319,4 +319,4 @@ public class AvailableDecodersTest
|
||||
expectedException.expectMessage(containsString("Duplicate"));
|
||||
decoders.register(TimeDecoder.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -46,37 +46,37 @@ public class CloseHandling_BadStatusCodesTest extends AbstractLocalServerCase
|
||||
{
|
||||
// The various Good UTF8 sequences as a String (hex form)
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
|
||||
// @formatter:off
|
||||
data.add(new Object[]{"7.9.1", 0});
|
||||
data.add(new Object[]{"7.9.2", 999});
|
||||
data.add(new Object[]{"7.9.3", 1004});
|
||||
data.add(new Object[]{"7.9.4", 1005});
|
||||
data.add(new Object[]{"7.9.5", 1006});
|
||||
data.add(new Object[]{"7.9.6", 1012});
|
||||
data.add(new Object[]{"7.9.7", 1013});
|
||||
data.add(new Object[]{"7.9.8", 1014});
|
||||
data.add(new Object[]{"7.9.9", 1015});
|
||||
data.add(new Object[]{"7.9.10", 1016});
|
||||
data.add(new Object[]{"7.9.11", 1100});
|
||||
data.add(new Object[]{"7.9.12", 2000});
|
||||
data.add(new Object[]{"7.9.13", 2999});
|
||||
data.add(new Object[] { "7.9.1", 0 });
|
||||
data.add(new Object[] { "7.9.2", 999 });
|
||||
data.add(new Object[] { "7.9.3", 1004 }); // RFC6455/UNDEFINED
|
||||
data.add(new Object[] { "7.9.4", 1005 }); // RFC6455/Cannot Be Transmitted
|
||||
data.add(new Object[] { "7.9.5", 1006 }); // RFC6455/Cannot Be Transmitted
|
||||
// data.add(new Object[] { "7.9.6", 1012 }); - IANA Defined
|
||||
// data.add(new Object[] { "7.9.7", 1013 }); - IANA Defined
|
||||
// data.add(new Object[] { "7.9.8", 1014 }); - IANA Defined
|
||||
data.add(new Object[] { "7.9.9", 1015 }); // RFC6455/Cannot Be Transmitted
|
||||
data.add(new Object[] { "7.9.10", 1016 });
|
||||
data.add(new Object[] { "7.9.11", 1100 });
|
||||
data.add(new Object[] { "7.9.12", 2000 });
|
||||
data.add(new Object[] { "7.9.13", 2999 });
|
||||
// -- close status codes, with undefined events in spec
|
||||
data.add(new Object[]{"7.13.1", 5000});
|
||||
data.add(new Object[]{"7.13.2", 65536});
|
||||
// @formatter:on
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
private final int statusCode;
|
||||
|
||||
|
||||
public CloseHandling_BadStatusCodesTest(String testId, int statusCode)
|
||||
{
|
||||
LOG.debug("Test ID: {}", testId);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* just the close code, no reason
|
||||
*
|
||||
@ -89,20 +89,20 @@ public class CloseHandling_BadStatusCodesTest extends AbstractLocalServerCase
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.putChar((char) statusCode);
|
||||
BufferUtil.flipToFlush(payload, 0);
|
||||
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseFrame().setPayload(payload.slice()));
|
||||
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
session.sendBulk(send);
|
||||
session.expect(expect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* the bad close code, with reason
|
||||
*
|
||||
@ -116,13 +116,13 @@ public class CloseHandling_BadStatusCodesTest extends AbstractLocalServerCase
|
||||
payload.putChar((char) statusCode);
|
||||
payload.put(StringUtil.getBytes("Reason"));
|
||||
BufferUtil.flipToFlush(payload, 0);
|
||||
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseFrame().setPayload(payload.slice()));
|
||||
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
session.sendBulk(send);
|
||||
|
@ -43,40 +43,43 @@ import org.junit.runners.Parameterized.Parameters;
|
||||
public class CloseHandling_GoodStatusCodesTest extends AbstractLocalServerCase
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(CloseHandling_GoodStatusCodesTest.class);
|
||||
|
||||
|
||||
@Parameters(name = "{0} {1}")
|
||||
public static Collection<Object[]> data()
|
||||
{
|
||||
// The various Good UTF8 sequences as a String (hex form)
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
|
||||
// @formatter:off
|
||||
data.add(new Object[]{"7.7.1", 1000});
|
||||
data.add(new Object[]{"7.7.2", 1001});
|
||||
data.add(new Object[]{"7.7.3", 1002});
|
||||
data.add(new Object[]{"7.7.4", 1003});
|
||||
data.add(new Object[]{"7.7.5", 1007});
|
||||
data.add(new Object[]{"7.7.6", 1008});
|
||||
data.add(new Object[]{"7.7.7", 1009});
|
||||
data.add(new Object[]{"7.7.8", 1010});
|
||||
data.add(new Object[]{"7.7.9", 1011});
|
||||
data.add(new Object[]{"7.7.10", 3000});
|
||||
data.add(new Object[]{"7.7.11", 3999});
|
||||
data.add(new Object[]{"7.7.12", 4000});
|
||||
data.add(new Object[]{"7.7.13", 4999});
|
||||
data.add(new Object[] { "7.7.1", 1000 });
|
||||
data.add(new Object[] { "7.7.2", 1001 });
|
||||
data.add(new Object[] { "7.7.3", 1002 });
|
||||
data.add(new Object[] { "7.7.4", 1003 });
|
||||
data.add(new Object[] { "7.7.5", 1007 });
|
||||
data.add(new Object[] { "7.7.6", 1008 });
|
||||
data.add(new Object[] { "7.7.7", 1009 });
|
||||
data.add(new Object[] { "7.7.8", 1010 });
|
||||
data.add(new Object[] { "7.7.9", 1011 });
|
||||
data.add(new Object[] { "IANA Assigned", 1012 });
|
||||
data.add(new Object[] { "IANA Assigned", 1013 });
|
||||
data.add(new Object[] { "IANA Assigned", 1014 });
|
||||
data.add(new Object[] { "7.7.10", 3000 });
|
||||
data.add(new Object[] { "7.7.11", 3999 });
|
||||
data.add(new Object[] { "7.7.12", 4000 });
|
||||
data.add(new Object[] { "7.7.13", 4999 });
|
||||
// @formatter:on
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
private final int statusCode;
|
||||
|
||||
|
||||
public CloseHandling_GoodStatusCodesTest(String testId, int statusCode)
|
||||
{
|
||||
LOG.debug("Test ID: {}", testId);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* just the close code, no reason
|
||||
*
|
||||
@ -89,20 +92,20 @@ public class CloseHandling_GoodStatusCodesTest extends AbstractLocalServerCase
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.putChar((char) statusCode);
|
||||
BufferUtil.flipToFlush(payload, 0);
|
||||
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseFrame().setPayload(payload.slice()));
|
||||
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseFrame().setPayload(DataUtils.copyOf(payload)));
|
||||
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
session.sendBulk(send);
|
||||
session.expect(expect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* the good close code, with reason
|
||||
*
|
||||
@ -115,13 +118,13 @@ public class CloseHandling_GoodStatusCodesTest extends AbstractLocalServerCase
|
||||
payload.putChar((char) statusCode);
|
||||
payload.put(StringUtil.getBytes("Reason"));
|
||||
payload.flip();
|
||||
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseFrame().setPayload(payload.slice()));
|
||||
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseFrame().setPayload(DataUtils.copyOf(payload)));
|
||||
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
session.sendBulk(send);
|
||||
|
@ -53,7 +53,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
@ -80,7 +80,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new TextFrame().setPayload("small")); // echo on good frame
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
@ -107,7 +107,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new TextFrame().setPayload("small")); // echo on good frame
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
@ -134,7 +134,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new TextFrame().setPayload("small")); // echo on good frame
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
@ -161,7 +161,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
@ -188,7 +188,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
@ -216,7 +216,7 @@ public class ReservedBitTest extends AbstractLocalServerCase
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer())
|
||||
{
|
||||
|
@ -0,0 +1,316 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.tests.server;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketConstants;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||
import org.eclipse.jetty.websocket.tests.LocalFuzzer;
|
||||
import org.eclipse.jetty.websocket.tests.SimpleServletServer;
|
||||
import org.eclipse.jetty.websocket.tests.UpgradeUtils;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests various close scenarios
|
||||
*/
|
||||
@Ignore
|
||||
public class WebSocketCloseTest
|
||||
{
|
||||
/**
|
||||
* On Message, return container information
|
||||
*/
|
||||
public static class ContainerSocket extends WebSocketAdapter
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.ContainerSocket.class);
|
||||
private final WebSocketServerFactory container;
|
||||
private Session session;
|
||||
|
||||
public ContainerSocket(WebSocketServerFactory container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketText(String message)
|
||||
{
|
||||
LOG.debug("onWebSocketText({})", message);
|
||||
if (message.equalsIgnoreCase("openSessions"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Collection<WebSocketSession> sessions = container.getOpenSessions();
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("openSessions.size=").append(sessions.size()).append('\n');
|
||||
int idx = 0;
|
||||
for (WebSocketSession sess : sessions)
|
||||
{
|
||||
ret.append('[').append(idx++).append("] ").append(sess.toString()).append('\n');
|
||||
}
|
||||
session.getRemote().sendString(ret.toString());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
session.close(StatusCode.NORMAL, "ContainerSocket");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session sess)
|
||||
{
|
||||
LOG.debug("onWebSocketConnect({})", sess);
|
||||
this.session = sess;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Connect, close socket
|
||||
*/
|
||||
public static class FastCloseSocket extends WebSocketAdapter
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.FastCloseSocket.class);
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session sess)
|
||||
{
|
||||
LOG.debug("onWebSocketConnect({})", sess);
|
||||
sess.close(StatusCode.NORMAL, "FastCloseServer");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Connect, throw unhandled exception
|
||||
*/
|
||||
public static class FastFailSocket extends WebSocketAdapter
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.FastFailSocket.class);
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session sess)
|
||||
{
|
||||
LOG.debug("onWebSocketConnect({})", sess);
|
||||
// Test failure due to unhandled exception
|
||||
// this should trigger a fast-fail closure during open/connect
|
||||
throw new RuntimeException("Intentional FastFail");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Message, drop connection
|
||||
*/
|
||||
public static class DropServerConnectionSocket extends WebSocketAdapter
|
||||
{
|
||||
@Override
|
||||
public void onWebSocketText(String message)
|
||||
{
|
||||
try
|
||||
{
|
||||
getSession().disconnect();
|
||||
}
|
||||
catch (IOException ignore)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CloseServlet extends WebSocketServlet implements WebSocketCreator
|
||||
{
|
||||
private WebSocketServerFactory serverFactory;
|
||||
|
||||
@Override
|
||||
public void configure(WebSocketServletFactory factory)
|
||||
{
|
||||
factory.setCreator(this);
|
||||
if (factory instanceof WebSocketServerFactory)
|
||||
{
|
||||
this.serverFactory = (WebSocketServerFactory) factory;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
if (req.hasSubProtocol("fastclose"))
|
||||
{
|
||||
return new FastCloseSocket();
|
||||
}
|
||||
|
||||
if (req.hasSubProtocol("fastfail"))
|
||||
{
|
||||
return new FastFailSocket();
|
||||
}
|
||||
|
||||
if (req.hasSubProtocol("drop"))
|
||||
{
|
||||
return new DropServerConnectionSocket();
|
||||
}
|
||||
|
||||
if (req.hasSubProtocol("container"))
|
||||
{
|
||||
return new ContainerSocket(serverFactory);
|
||||
}
|
||||
|
||||
return new RFC6455Socket();
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleServletServer server;
|
||||
|
||||
@Before
|
||||
public void startServer() throws Exception
|
||||
{
|
||||
server = new SimpleServletServer(new CloseServlet());
|
||||
server.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void stopServer() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fast close (bug #403817)
|
||||
*
|
||||
* @throws Exception on test failure
|
||||
*/
|
||||
@Test
|
||||
public void fastClose() throws Exception
|
||||
{
|
||||
Map<String, String> upgradeHeaders = UpgradeUtils.newDefaultUpgradeRequestHeaders();
|
||||
upgradeHeaders.put(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL, "fastclose");
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL, "FastCloseServer").asFrame());
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer("/", upgradeHeaders))
|
||||
{
|
||||
session.sendFrames(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
session.expect(expect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fast fail (bug #410537)
|
||||
*
|
||||
* @throws Exception on test failure
|
||||
*/
|
||||
@Test
|
||||
public void fastFail() throws Exception
|
||||
{
|
||||
Map<String, String> upgradeHeaders = UpgradeUtils.newDefaultUpgradeRequestHeaders();
|
||||
upgradeHeaders.put(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL, "fastfail");
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.SERVER_ERROR).asFrame());
|
||||
|
||||
try (StacklessLogging ignore = new StacklessLogging(FastFailSocket.class);
|
||||
LocalFuzzer session = server.newLocalFuzzer("/", upgradeHeaders))
|
||||
{
|
||||
session.expect(expect);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dropServerConnection() throws Exception
|
||||
{
|
||||
Map<String, String> upgradeHeaders = UpgradeUtils.newDefaultUpgradeRequestHeaders();
|
||||
upgradeHeaders.put(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL, "drop");
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer("/", upgradeHeaders))
|
||||
{
|
||||
session.sendFrames(new TextFrame().setPayload("drop"));
|
||||
BlockingQueue<WebSocketFrame> framesQueue = session.getOutputFrames();
|
||||
assertThat("No frames as output", framesQueue.size(), Matchers.is(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test session open session cleanup (bug #474936)
|
||||
*
|
||||
* @throws Exception on test failure
|
||||
*/
|
||||
@Test
|
||||
public void testOpenSessionCleanup() throws Exception
|
||||
{
|
||||
fastFail();
|
||||
fastClose();
|
||||
dropClientConnection();
|
||||
|
||||
Map<String, String> upgradeHeaders = UpgradeUtils.newDefaultUpgradeRequestHeaders();
|
||||
upgradeHeaders.put(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL, "container");
|
||||
|
||||
try (LocalFuzzer session = server.newLocalFuzzer("/?openSessions", upgradeHeaders))
|
||||
{
|
||||
session.sendFrames(
|
||||
new TextFrame().setPayload("openSessions"),
|
||||
new CloseInfo(StatusCode.NORMAL).asFrame()
|
||||
);
|
||||
|
||||
BlockingQueue<WebSocketFrame> framesQueue = session.getOutputFrames();
|
||||
WebSocketFrame frame = framesQueue.poll(3, TimeUnit.SECONDS);
|
||||
assertThat("Frame.opCode", frame.getOpCode(), is(OpCode.TEXT));
|
||||
assertThat("Frame.text-payload", frame.getPayloadAsUTF8(), containsString("openSessions.size=1\n"));
|
||||
}
|
||||
}
|
||||
|
||||
private void dropClientConnection() throws Exception
|
||||
{
|
||||
Map<String, String> upgradeHeaders = UpgradeUtils.newDefaultUpgradeRequestHeaders();
|
||||
upgradeHeaders.put(WebSocketConstants.SEC_WEBSOCKET_PROTOCOL, "container");
|
||||
|
||||
try (LocalFuzzer ignored = server.newLocalFuzzer("/", upgradeHeaders))
|
||||
{
|
||||
// do nothing, just let endpoint close
|
||||
}
|
||||
}
|
||||
}
|
@ -16,23 +16,22 @@
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.server;
|
||||
package org.eclipse.jetty.websocket.tests.server;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WebSocketServerFactoryTest
|
||||
@ -55,7 +54,6 @@ public class WebSocketServerFactoryTest
|
||||
public void testInit()
|
||||
{
|
||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||
Executor executor = new QueuedThreadPool();
|
||||
ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
|
||||
int wsFactoryLevel = setLogLevel(WebSocketServerFactory.class, StdErrLog.LEVEL_DEBUG);
|
||||
@ -63,7 +61,9 @@ public class WebSocketServerFactoryTest
|
||||
int containerLifecycleLevel = setLogLevel(ContainerLifeCycle.class, StdErrLog.LEVEL_DEBUG);
|
||||
try
|
||||
{
|
||||
WebSocketServerFactory wsFactory = new WebSocketServerFactory(policy, executor, bufferPool);
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
|
||||
WebSocketServerFactory wsFactory = new WebSocketServerFactory(context.getServletContext(), policy, bufferPool);
|
||||
// The above init caused NPE due to bad constructor initialization order with debug active
|
||||
assertThat("wsFactory.toString()", wsFactory.toString(), notNullValue());
|
||||
}
|
@ -47,9 +47,6 @@ public class AltFilterTest
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
@Rule
|
||||
public LeakTrackingBufferPoolRule bufferPool = new LeakTrackingBufferPoolRule("Test");
|
||||
|
||||
@Test
|
||||
public void testEcho() throws Exception
|
||||
{
|
||||
|
@ -59,7 +59,6 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.websocket.api.util.WSURI;
|
||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.JettyClientContainerProvider;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
||||
import org.junit.Test;
|
||||
@ -217,12 +216,11 @@ public class DelayedStartClientOnServerTest
|
||||
Server server = new Server(0);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
server.setHandler(contextHandler);
|
||||
WebSocketServerContainerInitializer.configureContext(contextHandler);
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
|
||||
List<String> threadNames = getThreadNames(server);
|
||||
|
||||
assertNoHttpClientPoolThreads(threadNames);
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketClient@"))));
|
||||
@ -250,9 +248,9 @@ public class DelayedStartClientOnServerTest
|
||||
String response = GET(server.getURI().resolve("/connect"));
|
||||
assertThat("Response", response, startsWith("Connected to ws://"));
|
||||
|
||||
List<String> threadNames = getThreadNames(server, JettyClientContainerProvider.getInstance());
|
||||
List<String> threadNames = getThreadNames(server, (ContainerLifeCycle)container);
|
||||
assertNoHttpClientPoolThreads(threadNames);
|
||||
assertThat("Threads", threadNames, hasItem(containsString("WebSocketClient@")));
|
||||
assertThat("Threads", threadNames, hasItem(containsString("Jsr356Client@")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -275,8 +273,7 @@ public class DelayedStartClientOnServerTest
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/connect"));
|
||||
assertThat("Response", response, startsWith("Connected to ws://"));
|
||||
|
||||
List<String> threadNames = getThreadNames(server, JettyClientContainerProvider.getInstance());
|
||||
List<String> threadNames = getThreadNames((ContainerLifeCycle)container, server);
|
||||
assertNoHttpClientPoolThreads(threadNames);
|
||||
assertThat("Threads", threadNames, hasItem(containsString("WebSocketClient@")));
|
||||
}
|
||||
@ -301,8 +298,7 @@ public class DelayedStartClientOnServerTest
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/configure"));
|
||||
assertThat("Response", response, startsWith("Configured " + ClientContainer.class.getName()));
|
||||
|
||||
List<String> threadNames = getThreadNames(server, JettyClientContainerProvider.getInstance());
|
||||
List<String> threadNames = getThreadNames((ContainerLifeCycle)container, server);
|
||||
assertNoHttpClientPoolThreads(threadNames);
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketClient@"))));
|
||||
@ -329,8 +325,7 @@ public class DelayedStartClientOnServerTest
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/configure"));
|
||||
assertThat("Response", response, startsWith("Configured " + ServerContainer.class.getName()));
|
||||
|
||||
List<String> threadNames = getThreadNames(server, JettyClientContainerProvider.getInstance());
|
||||
List<String> threadNames = getThreadNames((ContainerLifeCycle)container, server);
|
||||
assertNoHttpClientPoolThreads(threadNames);
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("Jsr356Client@"))));
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
@ -115,13 +115,13 @@ public class DeploymentExceptionTest
|
||||
contexts.addHandler(context);
|
||||
try
|
||||
{
|
||||
container.start();
|
||||
context.start();
|
||||
expectedException.expect(DeploymentException.class);
|
||||
container.addEndpoint(pojo);
|
||||
}
|
||||
finally
|
||||
{
|
||||
container.stop();
|
||||
context.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -42,7 +42,6 @@ import org.junit.Test;
|
||||
/**
|
||||
* Test Echo of Large messages, targeting the {@link javax.websocket.Session#setMaxTextMessageBufferSize(int)} functionality
|
||||
*/
|
||||
@Ignore
|
||||
public class LargeAnnotatedTest
|
||||
{
|
||||
@ServerEndpoint(value = "/echo/large")
|
||||
|
@ -47,7 +47,6 @@ import org.junit.Test;
|
||||
/**
|
||||
* Test Echo of Large messages, targeting the {@link javax.websocket.WebSocketContainer#setDefaultMaxTextMessageBufferSize(int)} functionality
|
||||
*/
|
||||
@Ignore
|
||||
public class LargeContainerTest
|
||||
{
|
||||
@ServerEndpoint(value = "/echo/large")
|
||||
|
@ -27,8 +27,11 @@ org.eclipse.jetty.LEVEL=WARN
|
||||
# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.client.LEVEL=DEBUG
|
||||
<<<<<<< HEAD
|
||||
# org.eclipse.jetty.io.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO
|
||||
=======
|
||||
>>>>>>> parent of 17f6c28... Issue #1503 Optionally strip IPv6. Default true
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.LEVEL=INFO
|
||||
# org.eclipse.jetty.websocket.jsr356.messages.LEVEL=DEBUG
|
||||
|
1
pom.xml
1
pom.xml
@ -21,7 +21,6 @@
|
||||
<jetty-test-policy-version>1.2</jetty-test-policy-version>
|
||||
<alpn.api.version>1.1.3.v20160715</alpn.api.version>
|
||||
<jsp.version>8.5.9.1</jsp.version>
|
||||
<servlet.api.version>4.0.0-b07</servlet.api.version>
|
||||
<!-- default values are unsupported, but required to be defined for reactor sanity reasons -->
|
||||
<alpn.version>undefined</alpn.version>
|
||||
</properties>
|
||||
|
Loading…
x
Reference in New Issue
Block a user