Merge branch 'jetty-9.2.x' into 'jetty-9.3.x'
This commit is contained in:
commit
f54938178e
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
|
||||
|
@ -38,7 +39,7 @@ public class PathParamServerEndpointConfig extends BasicServerEndpointConfig imp
|
|||
super(containerScope, config);
|
||||
|
||||
Map<String, String> pathMap = pathSpec.getPathParams(requestPath);
|
||||
pathParamMap = new HashMap<String, String>();
|
||||
pathParamMap = new HashMap<>();
|
||||
if (pathMap != null)
|
||||
{
|
||||
pathParamMap.putAll(pathMap);
|
||||
|
|
|
@ -40,28 +40,25 @@ import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory;
|
|||
import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
|
||||
import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
|
||||
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.server.NativeWebSocketConfiguration;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
|
||||
public class ServerContainer extends ClientContainer implements javax.websocket.server.ServerContainer
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ServerContainer.class);
|
||||
|
||||
private final MappedWebSocketCreator mappedCreator;
|
||||
private final WebSocketServerFactory webSocketServerFactory;
|
||||
private final NativeWebSocketConfiguration configuration;
|
||||
private List<Class<?>> deferredEndpointClasses;
|
||||
private List<ServerEndpointConfig> deferredEndpointConfigs;
|
||||
|
||||
public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor)
|
||||
public ServerContainer(NativeWebSocketConfiguration configuration, Executor executor)
|
||||
{
|
||||
super(factory);
|
||||
this.mappedCreator = creator;
|
||||
this.webSocketServerFactory = factory;
|
||||
EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
|
||||
super(configuration.getFactory());
|
||||
this.configuration = configuration;
|
||||
EventDriverFactory eventDriverFactory = this.configuration.getFactory().getEventDriverFactory();
|
||||
eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
|
||||
eventDriverFactory.addImplementation(new JsrServerExtendsEndpointImpl());
|
||||
this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this));
|
||||
addBean(webSocketServerFactory);
|
||||
this.configuration.getFactory().addSessionFactory(new JsrSessionFactory(this));
|
||||
}
|
||||
|
||||
public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path)
|
||||
|
@ -102,8 +99,8 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
|||
|
||||
private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException
|
||||
{
|
||||
JsrCreator creator = new JsrCreator(this,metadata,webSocketServerFactory.getExtensionFactory());
|
||||
mappedCreator.addMapping(new UriTemplatePathSpec(metadata.getPath()),creator);
|
||||
JsrCreator creator = new JsrCreator(this,metadata,this.configuration.getFactory().getExtensionFactory());
|
||||
this.configuration.addMapping(new UriTemplatePathSpec(metadata.getPath()),creator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,13 +151,6 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
mappedCreator.getMappings().reset();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
|
||||
{
|
||||
ServerEndpointMetadata metadata = null;
|
||||
|
@ -193,36 +183,41 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
|||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getDefaultAsyncSendTimeout()
|
||||
{
|
||||
return webSocketServerFactory.getPolicy().getAsyncWriteTimeout();
|
||||
return this.configuration.getPolicy().getAsyncWriteTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultMaxBinaryMessageBufferSize()
|
||||
{
|
||||
return webSocketServerFactory.getPolicy().getMaxBinaryMessageSize();
|
||||
return this.configuration.getPolicy().getMaxBinaryMessageSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDefaultMaxSessionIdleTimeout()
|
||||
{
|
||||
return webSocketServerFactory.getPolicy().getIdleTimeout();
|
||||
return this.configuration.getPolicy().getIdleTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultMaxTextMessageBufferSize()
|
||||
{
|
||||
return webSocketServerFactory.getPolicy().getMaxTextMessageSize();
|
||||
return this.configuration.getPolicy().getMaxTextMessageSize();
|
||||
}
|
||||
|
||||
public WebSocketServerFactory getWebSocketServerFactory()
|
||||
{
|
||||
return this.configuration.getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsyncSendTimeout(long ms)
|
||||
{
|
||||
super.setAsyncSendTimeout(ms);
|
||||
webSocketServerFactory.getPolicy().setAsyncWriteTimeout(ms);
|
||||
this.configuration.getPolicy().setAsyncWriteTimeout(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -230,16 +225,16 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
|||
{
|
||||
super.setDefaultMaxBinaryMessageBufferSize(max);
|
||||
// overall message limit (used in non-streaming)
|
||||
webSocketServerFactory.getPolicy().setMaxBinaryMessageSize(max);
|
||||
this.configuration.getPolicy().setMaxBinaryMessageSize(max);
|
||||
// incoming streaming buffer size
|
||||
webSocketServerFactory.getPolicy().setMaxBinaryMessageBufferSize(max);
|
||||
this.configuration.getPolicy().setMaxBinaryMessageBufferSize(max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultMaxSessionIdleTimeout(long ms)
|
||||
{
|
||||
super.setDefaultMaxSessionIdleTimeout(ms);
|
||||
webSocketServerFactory.getPolicy().setIdleTimeout(ms);
|
||||
this.configuration.getPolicy().setIdleTimeout(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -247,26 +242,26 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
|||
{
|
||||
super.setDefaultMaxTextMessageBufferSize(max);
|
||||
// overall message limit (used in non-streaming)
|
||||
webSocketServerFactory.getPolicy().setMaxTextMessageSize(max);
|
||||
this.configuration.getPolicy().setMaxTextMessageSize(max);
|
||||
// incoming streaming buffer size
|
||||
webSocketServerFactory.getPolicy().setMaxTextMessageBufferSize(max);
|
||||
this.configuration.getPolicy().setMaxTextMessageBufferSize(max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionClosed(WebSocketSession session)
|
||||
{
|
||||
webSocketServerFactory.onSessionClosed(session);
|
||||
getWebSocketServerFactory().onSessionClosed(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionOpened(WebSocketSession session)
|
||||
{
|
||||
webSocketServerFactory.onSessionOpened(session);
|
||||
getWebSocketServerFactory().onSessionOpened(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Session> getOpenSessions()
|
||||
{
|
||||
return new HashSet<>(webSocketServerFactory.getBeans(Session.class));
|
||||
return new HashSet<>(getWebSocketServerFactory().getBeans(Session.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,18 +33,14 @@ import javax.websocket.server.ServerApplicationConfig;
|
|||
import javax.websocket.server.ServerEndpoint;
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
|
||||
import org.eclipse.jetty.websocket.server.DefaultMappedWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
import org.eclipse.jetty.websocket.server.NativeWebSocketConfiguration;
|
||||
import org.eclipse.jetty.websocket.server.NativeWebSocketServletContainerInitializer;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
|
||||
|
||||
@HandlesTypes(
|
||||
|
@ -137,18 +133,12 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
|||
public static ServerContainer configureContext(ServletContextHandler context) throws ServletException
|
||||
{
|
||||
// Create Basic components
|
||||
WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
||||
ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
MappedWebSocketCreator creator = new DefaultMappedWebSocketCreator();
|
||||
WebSocketServerFactory factory = new WebSocketServerFactory(policy, bufferPool);
|
||||
|
||||
NativeWebSocketConfiguration nativeWebSocketConfiguration = NativeWebSocketServletContainerInitializer.getDefaultFrom(context.getServletContext());
|
||||
|
||||
// Create the Jetty ServerContainer implementation
|
||||
ServerContainer jettyContainer = new ServerContainer(creator,factory,context.getServer().getThreadPool());
|
||||
ServerContainer jettyContainer = new ServerContainer(nativeWebSocketConfiguration, context.getServer().getThreadPool());
|
||||
context.addBean(jettyContainer);
|
||||
|
||||
context.setAttribute(WebSocketUpgradeFilter.CREATOR_KEY, creator);
|
||||
context.setAttribute(WebSocketUpgradeFilter.FACTORY_KEY, factory);
|
||||
|
||||
// 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);
|
||||
|
||||
|
@ -156,6 +146,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
|||
if(isEnabledViaContext(context.getServletContext(), ADD_DYNAMIC_FILTER_KEY, true))
|
||||
{
|
||||
WebSocketUpgradeFilter.configureContext(context);
|
||||
NativeWebSocketServletContainerInitializer.getDefaultFrom(context.getServletContext());
|
||||
}
|
||||
|
||||
return jettyContainer;
|
||||
|
|
|
@ -18,21 +18,27 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.jsr356.server;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.PathMappings;
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
public class DummyCreator implements MappedWebSocketCreator
|
||||
{
|
||||
@Override
|
||||
public void addMapping(org.eclipse.jetty.websocket.server.pathmap.PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMapping(PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PathMappings<WebSocketCreator> getMappings()
|
||||
public MappedResource<WebSocketCreator> getMapping(String target)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.eclipse.jetty.websocket.jsr356.JsrExtension;
|
|||
import org.eclipse.jetty.websocket.jsr356.JsrSession;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.echo.BasicEchoEndpoint;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.websocket.server.NativeWebSocketConfiguration;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
|
@ -88,8 +88,9 @@ public class ExtensionStackProcessingTest
|
|||
|
||||
private void assumeDeflateFrameAvailable()
|
||||
{
|
||||
WebSocketUpgradeFilter filter = (WebSocketUpgradeFilter)servletContextHandler.getAttribute(WebSocketUpgradeFilter.class.getName());
|
||||
ExtensionFactory serverExtensionFactory = filter.getFactory().getExtensionFactory();
|
||||
NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) servletContextHandler
|
||||
.getServletContext().getAttribute(NativeWebSocketConfiguration.class.getName());
|
||||
ExtensionFactory serverExtensionFactory = configuration.getFactory().getExtensionFactory();
|
||||
Assume.assumeTrue("Server has permessage-deflate extension registered",serverExtensionFactory.isAvailable("permessage-deflate"));
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,18 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.server;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.PathMappings;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.websocket.server.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,32 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
|||
*/
|
||||
public interface MappedWebSocketCreator
|
||||
{
|
||||
public void addMapping(PathSpec spec, WebSocketCreator creator);
|
||||
|
||||
public PathMappings<WebSocketCreator> getMappings();
|
||||
/**
|
||||
* Add a mapping.
|
||||
*
|
||||
* @param spec the path spec to use
|
||||
* @param creator the creator for the mapping
|
||||
* @deprecated use {@link #addMapping(org.eclipse.jetty.http.pathmap.PathSpec, WebSocketCreator)} instead.
|
||||
* (support classes moved to generic jetty-http project)
|
||||
*/
|
||||
@Deprecated
|
||||
void addMapping(PathSpec spec, WebSocketCreator creator);
|
||||
|
||||
/**
|
||||
* Add a mapping.
|
||||
*
|
||||
* @param spec the path spec to use
|
||||
* @param creator the creator for the mapping
|
||||
* @since 9.2.20
|
||||
*/
|
||||
void addMapping(org.eclipse.jetty.http.pathmap.PathSpec spec, WebSocketCreator creator);
|
||||
|
||||
/**
|
||||
* Get specific MappedResource for associated target.
|
||||
*
|
||||
* @param target the target to get mapping for
|
||||
* @return the MappedResource for the target, or null if no match.
|
||||
* @since 9.2.20
|
||||
*/
|
||||
MappedResource<WebSocketCreator> getMapping(String target);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.http.pathmap.PathMappings;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.RegexPathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
/**
|
||||
* Interface for Configuring Jetty Server Native WebSockets
|
||||
* <p>
|
||||
* Only applicable if using {@link WebSocketUpgradeFilter}
|
||||
* </p>
|
||||
*/
|
||||
public class NativeWebSocketConfiguration extends ContainerLifeCycle implements Dumpable
|
||||
{
|
||||
private final WebSocketServerFactory factory;
|
||||
private final PathMappings<WebSocketCreator> mappings = new PathMappings<>();
|
||||
|
||||
public NativeWebSocketConfiguration()
|
||||
{
|
||||
this(new WebSocketServerFactory());
|
||||
}
|
||||
|
||||
public NativeWebSocketConfiguration(WebSocketServerFactory webSocketServerFactory)
|
||||
{
|
||||
this.factory = webSocketServerFactory;
|
||||
addBean(this.factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStop() throws Exception
|
||||
{
|
||||
mappings.reset();
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
return ContainerLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
// TODO: show factory/mappings ?
|
||||
mappings.dump(out, indent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get WebSocketServerFactory being used.
|
||||
*
|
||||
* @return the WebSocketServerFactory being used.
|
||||
*/
|
||||
public WebSocketServerFactory getFactory()
|
||||
{
|
||||
return this.factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matching {@link MappedResource} for the provided target.
|
||||
*
|
||||
* @param target the target path
|
||||
* @return the matching resource, or null if no match.
|
||||
*/
|
||||
public MappedResource<WebSocketCreator> getMatch(String target)
|
||||
{
|
||||
return this.mappings.getMatch(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to configure the Default {@link WebSocketPolicy} used by all endpoints that
|
||||
* don't redeclare the values.
|
||||
*
|
||||
* @return the default policy for all WebSockets
|
||||
*/
|
||||
public WebSocketPolicy getPolicy()
|
||||
{
|
||||
return this.factory.getPolicy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually add a WebSocket mapping.
|
||||
*
|
||||
* @param pathSpec the pathspec to respond on
|
||||
* @param creator the websocket creator to activate on the provided mapping.
|
||||
*/
|
||||
public void addMapping(PathSpec pathSpec, WebSocketCreator creator)
|
||||
{
|
||||
mappings.put(pathSpec, creator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually add a WebSocket mapping.
|
||||
*
|
||||
* @param spec the pathspec to respond on
|
||||
* @param creator the websocket creator to activate on the provided mapping
|
||||
* @deprecated use {@link #addMapping(PathSpec, Class)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public void addMapping(org.eclipse.jetty.websocket.server.pathmap.PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
if (spec instanceof org.eclipse.jetty.websocket.server.pathmap.ServletPathSpec)
|
||||
{
|
||||
addMapping(new ServletPathSpec(spec.getSpec()), creator);
|
||||
}
|
||||
else if (spec instanceof org.eclipse.jetty.websocket.server.pathmap.RegexPathSpec)
|
||||
{
|
||||
addMapping(new RegexPathSpec(spec.getSpec()), creator);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Unsupported (Deprecated) PathSpec implementation type: " + spec.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually add a WebSocket mapping.
|
||||
*
|
||||
* @param pathSpec the pathspec to respond on
|
||||
* @param endpointClass the endpoint class to use for new upgrade requests on the provided
|
||||
* pathspec (can be an {@link org.eclipse.jetty.websocket.api.annotations.WebSocket} annotated
|
||||
* POJO, or implementing {@link org.eclipse.jetty.websocket.api.WebSocketListener})
|
||||
*/
|
||||
public void addMapping(PathSpec pathSpec, final Class<?> endpointClass)
|
||||
{
|
||||
mappings.put(pathSpec, new WebSocketCreator()
|
||||
{
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
try
|
||||
{
|
||||
return endpointClass.newInstance();
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to create instance of " + endpointClass.getName(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
public class NativeWebSocketServletContainerInitializer implements ServletContainerInitializer
|
||||
{
|
||||
public static NativeWebSocketConfiguration getDefaultFrom(ServletContext context)
|
||||
{
|
||||
final String KEY = NativeWebSocketConfiguration.class.getName();
|
||||
|
||||
NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) context.getAttribute(KEY);
|
||||
if (configuration == null)
|
||||
{
|
||||
configuration = new NativeWebSocketConfiguration();
|
||||
context.setAttribute(KEY, configuration);
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
|
||||
{
|
||||
// initialize
|
||||
getDefaultFrom(ctx);
|
||||
}
|
||||
}
|
|
@ -33,12 +33,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.http.pathmap.PathMappings;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.RegexPathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
|
@ -51,6 +47,7 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||
|
||||
/**
|
||||
* Inline Servlet Filter to capture WebSocket upgrade requests and perform path mappings to {@link WebSocketCreator} objects.
|
||||
|
@ -59,6 +56,7 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
|||
public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter, MappedWebSocketCreator, Dumpable
|
||||
{
|
||||
public static final String CONTEXT_ATTRIBUTE_KEY = "contextAttributeKey";
|
||||
public static final String CONFIG_ATTRIBUTE_KEY = "configAttributeKey";
|
||||
private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class);
|
||||
private boolean localMapper;
|
||||
private boolean localFactory;
|
||||
|
@ -73,7 +71,8 @@ public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter,
|
|||
}
|
||||
|
||||
// Dynamically add filter
|
||||
filter = new WebSocketUpgradeFilter();
|
||||
NativeWebSocketConfiguration configuration = NativeWebSocketServletContainerInitializer.getDefaultFrom(context.getServletContext());
|
||||
filter = new WebSocketUpgradeFilter(configuration);
|
||||
filter.setToAttribute(context, WebSocketUpgradeFilter.class.getName());
|
||||
|
||||
String name = "Jetty_WebSocketUpgradeFilter";
|
||||
|
@ -115,69 +114,67 @@ public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter,
|
|||
return configureContext((ServletContextHandler) handler);
|
||||
}
|
||||
|
||||
public static final String CREATOR_KEY = "org.eclipse.jetty.websocket.server.creator";
|
||||
public static final String FACTORY_KEY = "org.eclipse.jetty.websocket.server.factory";
|
||||
|
||||
private final WebSocketPolicy policy;
|
||||
private final ByteBufferPool bufferPool;
|
||||
private WebSocketServerFactory factory;
|
||||
private MappedWebSocketCreator mappedWebSocketCreator;
|
||||
private String fname;
|
||||
private NativeWebSocketConfiguration configuration;
|
||||
private boolean alreadySetToAttribute = false;
|
||||
|
||||
public WebSocketUpgradeFilter()
|
||||
{
|
||||
this(WebSocketPolicy.newServerPolicy(), new MappedByteBufferPool());
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public WebSocketUpgradeFilter(WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||
{
|
||||
this.policy = policy;
|
||||
this.bufferPool = bufferPool;
|
||||
this(new NativeWebSocketConfiguration(new WebSocketServerFactory(policy, bufferPool)));
|
||||
}
|
||||
|
||||
public WebSocketUpgradeFilter(NativeWebSocketConfiguration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMapping(PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
mappedWebSocketCreator.addMapping(spec, creator);
|
||||
configuration.addMapping(spec, creator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use new {@link #addMapping(org.eclipse.jetty.http.pathmap.PathSpec, WebSocketCreator)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void addMapping(org.eclipse.jetty.websocket.server.pathmap.PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
if (spec instanceof org.eclipse.jetty.websocket.server.pathmap.ServletPathSpec)
|
||||
{
|
||||
addMapping(new ServletPathSpec(spec.getSpec()), creator);
|
||||
}
|
||||
else if (spec instanceof org.eclipse.jetty.websocket.server.pathmap.RegexPathSpec)
|
||||
{
|
||||
addMapping(new RegexPathSpec(spec.getSpec()), creator);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Unsupported (Deprecated) PathSpec implementation: " + spec.getClass().getName());
|
||||
}
|
||||
configuration.addMapping(spec, creator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if (localFactory)
|
||||
try
|
||||
{
|
||||
factory.cleanup();
|
||||
alreadySetToAttribute = false;
|
||||
configuration.stop();
|
||||
}
|
||||
if (localMapper)
|
||||
catch (Exception e)
|
||||
{
|
||||
mappedWebSocketCreator.getMappings().reset();
|
||||
LOG.ignore(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
if (configuration == null)
|
||||
{
|
||||
// no configuration, cannot operate
|
||||
LOG.debug("WebSocketUpgradeFilter is not operational - missing " + NativeWebSocketConfiguration.class.getName());
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
WebSocketServletFactory factory = configuration.getFactory();
|
||||
|
||||
if (factory == null)
|
||||
{
|
||||
// no factory, cannot operate
|
||||
|
@ -206,14 +203,9 @@ public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter,
|
|||
target = target.substring(contextPath.length());
|
||||
}
|
||||
|
||||
MappedResource<WebSocketCreator> resource = mappedWebSocketCreator.getMappings().getMatch(target);
|
||||
MappedResource<WebSocketCreator> resource = configuration.getMatch(target);
|
||||
if (resource == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("WebSocket Upgrade on {} has no associated endpoint", target);
|
||||
LOG.debug("PathMappings: {}", mappedWebSocketCreator.getMappings().dump());
|
||||
}
|
||||
// no match.
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
|
@ -267,68 +259,85 @@ public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter,
|
|||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(indent).append(" +- pathmap=").append(mappedWebSocketCreator.toString()).append("\n");
|
||||
mappedWebSocketCreator.getMappings().dump(out, indent + " ");
|
||||
out.append(indent).append(" +- configuration=").append(configuration.toString()).append("\n");
|
||||
configuration.dump(out, indent);
|
||||
}
|
||||
|
||||
public WebSocketServerFactory getFactory()
|
||||
public WebSocketServletFactory getFactory()
|
||||
{
|
||||
return factory;
|
||||
return configuration.getFactory();
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "configuration", readonly = true)
|
||||
public NativeWebSocketConfiguration getConfiguration()
|
||||
{
|
||||
if (configuration == null)
|
||||
{
|
||||
throw new IllegalStateException(this.getClass().getName() + " not initialized yet");
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "mappings", readonly = true)
|
||||
@Override
|
||||
public PathMappings<WebSocketCreator> getMappings()
|
||||
public MappedResource<WebSocketCreator> getMapping(String target)
|
||||
{
|
||||
return mappedWebSocketCreator.getMappings();
|
||||
return getConfiguration().getMatch(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) throws ServletException
|
||||
{
|
||||
fname = config.getFilterName();
|
||||
|
||||
try
|
||||
{
|
||||
ServletContext context = config.getServletContext();
|
||||
|
||||
mappedWebSocketCreator = (MappedWebSocketCreator) context.getAttribute(CREATOR_KEY);
|
||||
if (mappedWebSocketCreator == null)
|
||||
String configurationKey = config.getInitParameter(CONFIG_ATTRIBUTE_KEY);
|
||||
if (configurationKey == null)
|
||||
{
|
||||
mappedWebSocketCreator = new DefaultMappedWebSocketCreator();
|
||||
localMapper = true;
|
||||
configurationKey = NativeWebSocketConfiguration.class.getName();
|
||||
}
|
||||
|
||||
factory = (WebSocketServerFactory) context.getAttribute(FACTORY_KEY);
|
||||
if (factory == null)
|
||||
if (configuration == null)
|
||||
{
|
||||
factory = new WebSocketServerFactory(policy, bufferPool);
|
||||
localFactory = true;
|
||||
this.configuration = (NativeWebSocketConfiguration) config.getServletContext().getAttribute(configurationKey);
|
||||
if (this.configuration == null)
|
||||
{
|
||||
// The NativeWebSocketConfiguration should have arrived from the NativeWebSocketServletContainerInitializer
|
||||
throw new ServletException("Unable to find required instance of " +
|
||||
NativeWebSocketConfiguration.class.getName() + " at ServletContext attribute '" + configurationKey + "'");
|
||||
}
|
||||
}
|
||||
factory.init(context);
|
||||
else
|
||||
{
|
||||
// We have a NativeWebSocketConfiguration already present, make sure it exists on the ServletContext
|
||||
if (config.getServletContext().getAttribute(configurationKey) == null)
|
||||
{
|
||||
config.getServletContext().setAttribute(configurationKey, this.configuration);
|
||||
}
|
||||
}
|
||||
|
||||
this.configuration.start();
|
||||
|
||||
String max = config.getInitParameter("maxIdleTime");
|
||||
if (max != null)
|
||||
{
|
||||
factory.getPolicy().setIdleTimeout(Long.parseLong(max));
|
||||
getFactory().getPolicy().setIdleTimeout(Long.parseLong(max));
|
||||
}
|
||||
|
||||
max = config.getInitParameter("maxTextMessageSize");
|
||||
if (max != null)
|
||||
{
|
||||
factory.getPolicy().setMaxTextMessageSize(Integer.parseInt(max));
|
||||
getFactory().getPolicy().setMaxTextMessageSize(Integer.parseInt(max));
|
||||
}
|
||||
|
||||
max = config.getInitParameter("maxBinaryMessageSize");
|
||||
if (max != null)
|
||||
{
|
||||
factory.getPolicy().setMaxBinaryMessageSize(Integer.parseInt(max));
|
||||
getFactory().getPolicy().setMaxBinaryMessageSize(Integer.parseInt(max));
|
||||
}
|
||||
|
||||
max = config.getInitParameter("inputBufferSize");
|
||||
if (max != null)
|
||||
{
|
||||
factory.getPolicy().setInputBufferSize(Integer.parseInt(max));
|
||||
getFactory().getPolicy().setInputBufferSize(Integer.parseInt(max));
|
||||
}
|
||||
|
||||
String key = config.getInitParameter(CONTEXT_ATTRIBUTE_KEY);
|
||||
|
@ -338,33 +347,22 @@ public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter,
|
|||
key = WebSocketUpgradeFilter.class.getName();
|
||||
}
|
||||
|
||||
setToAttribute(context, key);
|
||||
|
||||
factory.start();
|
||||
// Set instance of this filter to context attribute
|
||||
setToAttribute(config.getServletContext(), key);
|
||||
}
|
||||
catch (Exception x)
|
||||
catch (ServletException e)
|
||||
{
|
||||
throw new ServletException(x);
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new ServletException(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void setToAttribute(ServletContextHandler context, String key) throws ServletException
|
||||
{
|
||||
if (alreadySetToAttribute)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.getAttribute(key) != null)
|
||||
{
|
||||
throw new ServletException(WebSocketUpgradeFilter.class.getName() +
|
||||
" is defined twice for the same context attribute key '" + key
|
||||
+ "'. Make sure you have different init-param '" +
|
||||
CONTEXT_ATTRIBUTE_KEY + "' values set");
|
||||
}
|
||||
context.setAttribute(key, this);
|
||||
|
||||
alreadySetToAttribute = true;
|
||||
setToAttribute(context.getServletContext(), key);
|
||||
}
|
||||
|
||||
public void setToAttribute(ServletContext context, String key) throws ServletException
|
||||
|
@ -389,6 +387,6 @@ public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter,
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s[factory=%s,creator=%s]", this.getClass().getSimpleName(), factory, mappedWebSocketCreator);
|
||||
return String.format("%s[configuration=%s]", this.getClass().getSimpleName(), configuration);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.http.pathmap.PathMappings;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
|
@ -35,8 +34,7 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
|||
|
||||
public class WebSocketUpgradeHandlerWrapper extends HandlerWrapper implements MappedWebSocketCreator
|
||||
{
|
||||
private PathMappings<WebSocketCreator> pathmap = new PathMappings<>();
|
||||
private final WebSocketServerFactory factory;
|
||||
private NativeWebSocketConfiguration configuration;
|
||||
|
||||
public WebSocketUpgradeHandlerWrapper()
|
||||
{
|
||||
|
@ -45,27 +43,41 @@ public class WebSocketUpgradeHandlerWrapper extends HandlerWrapper implements Ma
|
|||
|
||||
public WebSocketUpgradeHandlerWrapper(ByteBufferPool bufferPool)
|
||||
{
|
||||
factory = new WebSocketServerFactory(bufferPool);
|
||||
this.configuration = new NativeWebSocketConfiguration(new WebSocketServerFactory(bufferPool));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addMapping(PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
pathmap.put(spec,creator);
|
||||
this.configuration.addMapping(spec, creator);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a mapping.
|
||||
*
|
||||
* @param spec the path spec to use
|
||||
* @param creator the creator for the mapping
|
||||
* @deprecated use {@link #addMapping(PathSpec, WebSocketCreator)} instead.
|
||||
*/
|
||||
@Override
|
||||
public PathMappings<WebSocketCreator> getMappings()
|
||||
@Deprecated
|
||||
public void addMapping(org.eclipse.jetty.websocket.server.pathmap.PathSpec spec, WebSocketCreator creator)
|
||||
{
|
||||
return pathmap;
|
||||
configuration.addMapping(spec, creator);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MappedResource<WebSocketCreator> getMapping(String target)
|
||||
{
|
||||
return this.configuration.getMatch(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
if (factory.isUpgradeRequest(request,response))
|
||||
if (configuration.getFactory().isUpgradeRequest(request,response))
|
||||
{
|
||||
MappedResource<WebSocketCreator> resource = pathmap.getMatch(target);
|
||||
MappedResource<WebSocketCreator> resource = configuration.getMatch(target);
|
||||
if (resource == null)
|
||||
{
|
||||
// no match.
|
||||
|
@ -79,7 +91,7 @@ public class WebSocketUpgradeHandlerWrapper extends HandlerWrapper implements Ma
|
|||
request.setAttribute(PathSpec.class.getName(),resource);
|
||||
|
||||
// We have an upgrade request
|
||||
if (factory.acceptWebSocket(creator,request,response))
|
||||
if (configuration.getFactory().acceptWebSocket(creator,request,response))
|
||||
{
|
||||
// We have a socket instance created
|
||||
return;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.jetty.websocket.server.NativeWebSocketServletContainerInitializer
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
public class InfoContextAttributeListener implements WebSocketCreator, ServletContextListener
|
||||
{
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) sce.getServletContext().getAttribute(NativeWebSocketConfiguration.class.getName());
|
||||
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
configuration.addMapping(new ServletPathSpec("/info/*"), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
return new InfoSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
public class InfoContextListener implements WebSocketCreator, ServletContextListener
|
||||
{
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration();
|
||||
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
configuration.addMapping(new ServletPathSpec("/info/*"), this);
|
||||
sce.getServletContext().setAttribute(NativeWebSocketConfiguration.class.getName(), configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
return new InfoSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
public class InfoServlet extends HttpServlet implements WebSocketCreator
|
||||
{
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
return new InfoSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException
|
||||
{
|
||||
ServletContext context = config.getServletContext();
|
||||
NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) context.getAttribute(NativeWebSocketConfiguration.class.getName());
|
||||
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
configuration.addMapping(new ServletPathSpec("/info/*"), this);
|
||||
}
|
||||
}
|
|
@ -18,23 +18,27 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.server;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.PathMappings;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
|
||||
public class DefaultMappedWebSocketCreator implements MappedWebSocketCreator
|
||||
@WebSocket
|
||||
public class InfoSocket
|
||||
{
|
||||
private final PathMappings<WebSocketCreator> mappings = new PathMappings<>();
|
||||
private Session session;
|
||||
|
||||
@Override
|
||||
public void addMapping(PathSpec spec, WebSocketCreator creator)
|
||||
@OnWebSocketConnect
|
||||
public void onConnect(Session session)
|
||||
{
|
||||
this.mappings.put(spec, creator);
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathMappings<WebSocketCreator> getMappings()
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(String msg)
|
||||
{
|
||||
return this.mappings;
|
||||
RemoteEndpoint remote = this.session.getRemote();
|
||||
remote.sendStringByFuture("session.maxTextMessageSize=" + session.getPolicy().getMaxTextMessageSize());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
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.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.OS;
|
||||
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.Resource;
|
||||
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.WebInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Utility to build out exploded directory WebApps, in the /target/tests/ directory, for testing out servers that use javax.websocket endpoints.
|
||||
* <p>
|
||||
* This is particularly useful when the WebSocket endpoints are discovered via the javax.websocket annotation scanning.
|
||||
*/
|
||||
public class WSServer
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WSServer.class);
|
||||
private final File contextDir;
|
||||
private final String contextPath;
|
||||
private Server server;
|
||||
private URI serverUri;
|
||||
private ContextHandlerCollection contexts;
|
||||
private File webinf;
|
||||
private File classesDir;
|
||||
|
||||
public WSServer(TestingDir testdir, String contextName)
|
||||
{
|
||||
this(testdir.getDir(),contextName);
|
||||
}
|
||||
|
||||
public WSServer(File testdir, String contextName)
|
||||
{
|
||||
this.contextDir = new File(testdir,contextName);
|
||||
this.contextPath = "/" + contextName;
|
||||
FS.ensureEmpty(contextDir);
|
||||
}
|
||||
|
||||
public void copyClass(Class<?> clazz) throws Exception
|
||||
{
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
String endpointPath = clazz.getName().replace('.','/') + ".class";
|
||||
URL classUrl = cl.getResource(endpointPath);
|
||||
Assert.assertThat("Class URL for: " + clazz,classUrl,notNullValue());
|
||||
File destFile = new File(classesDir,OS.separators(endpointPath));
|
||||
FS.ensureDirExists(destFile.getParentFile());
|
||||
File srcFile = new File(classUrl.toURI());
|
||||
IO.copy(srcFile,destFile);
|
||||
}
|
||||
|
||||
public void copyEndpoint(Class<?> endpointClass) throws Exception
|
||||
{
|
||||
copyClass(endpointClass);
|
||||
}
|
||||
|
||||
public void copyWebInf(String testResourceName) throws IOException
|
||||
{
|
||||
webinf = new File(contextDir,"WEB-INF");
|
||||
FS.ensureDirExists(webinf);
|
||||
classesDir = new File(webinf,"classes");
|
||||
FS.ensureDirExists(classesDir);
|
||||
File webxml = new File(webinf,"web.xml");
|
||||
File testWebXml = MavenTestingUtils.getTestResourceFile(testResourceName);
|
||||
IO.copy(testWebXml,webxml);
|
||||
}
|
||||
|
||||
public WebAppContext createWebAppContext() throws MalformedURLException, IOException
|
||||
{
|
||||
WebAppContext context = new WebAppContext();
|
||||
context.setContextPath(this.contextPath);
|
||||
context.setBaseResource(Resource.newResource(this.contextDir));
|
||||
context.setAttribute("org.eclipse.jetty.websocket.jsr356",Boolean.TRUE);
|
||||
|
||||
// @formatter:off
|
||||
context.setConfigurations(new Configuration[] {
|
||||
new AnnotationConfiguration(),
|
||||
new WebXmlConfiguration(),
|
||||
new WebInfConfiguration(),
|
||||
new PlusConfiguration(),
|
||||
new MetaInfConfiguration(),
|
||||
new FragmentConfiguration(),
|
||||
new EnvConfiguration()});
|
||||
// @formatter:on
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
public void createWebInf() throws IOException
|
||||
{
|
||||
copyWebInf("empty-web.xml");
|
||||
}
|
||||
|
||||
public void deployWebapp(WebAppContext webapp) throws Exception
|
||||
{
|
||||
contexts.addHandler(webapp);
|
||||
contexts.manage(webapp);
|
||||
webapp.start();
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
webapp.dump(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
public void dump()
|
||||
{
|
||||
server.dumpStdErr();
|
||||
}
|
||||
|
||||
public URI getServerBaseURI()
|
||||
{
|
||||
return serverUri;
|
||||
}
|
||||
|
||||
public Server getServer()
|
||||
{
|
||||
return server;
|
||||
}
|
||||
|
||||
public File getWebAppDir()
|
||||
{
|
||||
return this.contextDir;
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
contexts = new ContextHandlerCollection();
|
||||
handlers.addHandler(contexts);
|
||||
server.setHandler(handlers);
|
||||
|
||||
server.start();
|
||||
|
||||
String host = connector.getHost();
|
||||
if (host == null)
|
||||
{
|
||||
host = "localhost";
|
||||
}
|
||||
int port = connector.getLocalPort();
|
||||
serverUri = new URI(String.format("ws://%s:%d%s/",host,port,contextPath));
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Server started on {}",serverUri);
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
if (server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class WebSocketUpgradeFilterTest
|
||||
{
|
||||
interface ServerProvider
|
||||
{
|
||||
Server newServer() throws Exception;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
public static List<Object[]> data()
|
||||
{
|
||||
/**
|
||||
* Case A:
|
||||
* 1. embedded-jetty WSUF.configureContext() / app-ws configured at ...
|
||||
* a. during server construction / before server.start (might not be possible with current impl, native SCI not run (yet))
|
||||
* might require NativeSCI.getDefaultFrom() first
|
||||
* b. during server construction / after server.start
|
||||
* c. during server start / via CustomServlet.init()
|
||||
* 2. embedded-jetty WSUF addFilter / app-ws configured at server construction (before server.start)
|
||||
* Case B:
|
||||
* 1. web.xml WSUF / app-ws configured in CustomServlet.init() load-on-start
|
||||
* Case C:
|
||||
* 1. embedded-jetty WSUF.configureContext() / app-ws configured via ServletContextListener.contextInitialized
|
||||
* 2. embedded-jetty WSUF addFilter / app-ws configured via ServletContextListener.contextInitialized
|
||||
* Case D:
|
||||
* 1. web.xml WSUF / app-ws configured via ServletContextListener.contextInitialized
|
||||
*
|
||||
* Every "app-ws configured" means it should access/set ws policy and add ws mappings
|
||||
*/
|
||||
|
||||
final WebSocketCreator infoCreator = new WebSocketCreator()
|
||||
{
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
return new InfoSocket();
|
||||
}
|
||||
};
|
||||
|
||||
List<Object[]> cases = new ArrayList<>();
|
||||
|
||||
// Embedded WSUF.configureContext(), directly app-ws configuration
|
||||
|
||||
cases.add(new Object[]{"wsuf.configureContext/Direct configure", new ServerProvider()
|
||||
{
|
||||
@Override
|
||||
public Server newServer() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
|
||||
WebSocketUpgradeFilter wsuf = WebSocketUpgradeFilter.configureContext(context);
|
||||
|
||||
// direct configuration via WSUF
|
||||
wsuf.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
wsuf.addMapping(new ServletPathSpec("/info/*"), infoCreator);
|
||||
|
||||
server.start();
|
||||
return server;
|
||||
}
|
||||
}});
|
||||
|
||||
// Embedded WSUF.configureContext(), apply app-ws configuration via attribute
|
||||
|
||||
cases.add(new Object[]{"wsuf.configureContext/Attribute based configure", new ServerProvider()
|
||||
{
|
||||
@Override
|
||||
public Server newServer() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
|
||||
WebSocketUpgradeFilter.configureContext(context);
|
||||
|
||||
// configuration via attribute
|
||||
NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) context.getServletContext().getAttribute(NativeWebSocketConfiguration.class.getName());
|
||||
assertThat("NativeWebSocketConfiguration", configuration, notNullValue());
|
||||
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
configuration.addMapping(new ServletPathSpec("/info/*"), infoCreator);
|
||||
|
||||
server.start();
|
||||
|
||||
return server;
|
||||
}
|
||||
}});
|
||||
|
||||
// Embedded WSUF, added as filter, apply app-ws configuration via attribute
|
||||
|
||||
cases.add(new Object[]{"wsuf/addFilter/Attribute based configure", new ServerProvider()
|
||||
{
|
||||
@Override
|
||||
public Server newServer() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
context.addFilter(WebSocketUpgradeFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
|
||||
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration();
|
||||
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
configuration.addMapping(new ServletPathSpec("/info/*"), infoCreator);
|
||||
context.getServletContext().setAttribute(NativeWebSocketConfiguration.class.getName(), configuration);
|
||||
|
||||
server.start();
|
||||
|
||||
return server;
|
||||
}
|
||||
}});
|
||||
|
||||
// Embedded WSUF, added as filter, apply app-ws configuration via ServletContextListener
|
||||
|
||||
cases.add(new Object[]{"wsuf.configureContext/ServletContextListener configure", new ServerProvider()
|
||||
{
|
||||
@Override
|
||||
public Server newServer() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
context.addFilter(WebSocketUpgradeFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
context.addEventListener(new InfoContextListener());
|
||||
|
||||
server.start();
|
||||
|
||||
return server;
|
||||
}
|
||||
}});
|
||||
|
||||
// WSUF from web.xml, SCI active, apply app-ws configuration via ServletContextListener
|
||||
|
||||
cases.add(new Object[]{"wsuf/WebAppContext/web.xml/ServletContextListener", new ServerProvider()
|
||||
{
|
||||
@Override
|
||||
public Server newServer() throws Exception
|
||||
{
|
||||
File testDir = MavenTestingUtils.getTargetTestingDir("WSUF-webxml");
|
||||
|
||||
WSServer server = new WSServer(testDir, "/");
|
||||
|
||||
server.copyClass(InfoSocket.class);
|
||||
server.copyClass(InfoContextAttributeListener.class);
|
||||
server.copyWebInf("wsuf-config-via-listener.xml");
|
||||
server.start();
|
||||
|
||||
WebAppContext webapp = server.createWebAppContext();
|
||||
server.deployWebapp(webapp);
|
||||
|
||||
return server.getServer();
|
||||
}
|
||||
}});
|
||||
|
||||
// WSUF from web.xml, SCI active, apply app-ws configuration via Servlet.init
|
||||
|
||||
cases.add(new Object[]{"wsuf/WebAppContext/web.xml/Servlet.init", new ServerProvider()
|
||||
{
|
||||
@Override
|
||||
public Server newServer() throws Exception
|
||||
{
|
||||
File testDir = MavenTestingUtils.getTargetTestingDir("WSUF-webxml");
|
||||
|
||||
WSServer server = new WSServer(testDir, "/");
|
||||
|
||||
server.copyClass(InfoSocket.class);
|
||||
server.copyClass(InfoServlet.class);
|
||||
server.copyWebInf("wsuf-config-via-servlet-init.xml");
|
||||
server.start();
|
||||
|
||||
WebAppContext webapp = server.createWebAppContext();
|
||||
server.deployWebapp(webapp);
|
||||
|
||||
return server.getServer();
|
||||
}
|
||||
}});
|
||||
|
||||
return cases;
|
||||
}
|
||||
|
||||
private final Server server;
|
||||
private final URI serverUri;
|
||||
|
||||
public WebSocketUpgradeFilterTest(String testId, ServerProvider serverProvider) throws Exception
|
||||
{
|
||||
this.server = serverProvider.newServer();
|
||||
|
||||
ServerConnector connector = (ServerConnector) server.getConnectors()[0];
|
||||
|
||||
// Establish the Server URI
|
||||
String host = connector.getHost();
|
||||
if (host == null)
|
||||
{
|
||||
host = "localhost";
|
||||
}
|
||||
int port = connector.getLocalPort();
|
||||
|
||||
serverUri = new URI(String.format("ws://%s:%d/", host, port));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfiguration() throws Exception
|
||||
{
|
||||
URI destUri = serverUri.resolve("/info/");
|
||||
|
||||
try (BlockheadClient client = new BlockheadClient(destUri))
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
client.write(new TextFrame().setPayload("hello"));
|
||||
|
||||
EventQueue<WebSocketFrame> frames = client.readFrames(1, 1000, TimeUnit.MILLISECONDS);
|
||||
String payload = frames.poll().getPayloadAsUTF8();
|
||||
|
||||
// If we can connect and send a text message, we know that the endpoint was
|
||||
// added properly, and the response will help us verify the policy configuration too
|
||||
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
<listener>
|
||||
<listener-class>org.eclipse.jetty.websocket.server.InfoContextAttributeListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>wsuf</filter-name>
|
||||
<filter-class>org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>wsuf</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
</web-app>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
<servlet>
|
||||
<servlet-name>info-servlet</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.websocket.server.InfoServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<filter>
|
||||
<filter-name>wsuf</filter-name>
|
||||
<filter-class>org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>wsuf</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
</web-app>
|
Loading…
Reference in New Issue