Merged branch 'jetty-9.2.x' into 'jetty-9.3.x'.

This commit is contained in:
Simone Bordet 2017-01-20 12:20:21 +01:00
commit 9ae93c19ca
17 changed files with 216 additions and 132 deletions

View File

@ -33,10 +33,12 @@ public class RegexPathSpec extends PathSpec
public RegexPathSpec(String regex)
{
super.pathSpec = regex;
boolean inGrouping = false;
if (regex.startsWith("regex|"))
super.pathSpec = regex.substring("regex|".length());
this.pathDepth = 0;
this.specLength = pathSpec.length();
// build up a simple signature we can use to identify the grouping
boolean inGrouping = false;
StringBuilder signature = new StringBuilder();
for (char c : pathSpec.toCharArray())
{

View File

@ -40,11 +40,12 @@ public class ServletPathSpec extends PathSpec
public ServletPathSpec(String servletPathSpec)
{
super();
if (servletPathSpec.startsWith("servlet|"))
servletPathSpec = servletPathSpec.substring("servlet|".length());
assertValidServletPathSpec(servletPathSpec);
// The Root Path Spec
if ((servletPathSpec == null) || (servletPathSpec.length() == 0))
if (servletPathSpec.length() == 0)
{
super.pathSpec = "";
super.pathDepth = -1; // force this to be at the end of the sort order

View File

@ -30,7 +30,6 @@ import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
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.common.WebSocketSession;
@ -101,7 +100,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException
{
JsrCreator creator = new JsrCreator(this,metadata,this.configuration.getFactory().getExtensionFactory());
this.configuration.addMapping(new UriTemplatePathSpec(metadata.getPath()),creator);
this.configuration.addMapping("uri-template|" + metadata.getPath(), creator);
}
@Override

View File

@ -109,7 +109,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
}
// Next, try attribute on context
Object enable = context.getAttribute(ENABLE_KEY);
Object enable = context.getAttribute(keyName);
if(enable != null)
{
@ -145,6 +145,8 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
// Create Filter
if(isEnabledViaContext(context.getServletContext(), ADD_DYNAMIC_FILTER_KEY, true))
{
if (LOG.isDebugEnabled())
LOG.debug("Dynamic filter add to support JSR356/javax.websocket.server: {}", WebSocketUpgradeFilter.class.getName());
WebSocketUpgradeFilter.configureContext(context);
}
@ -165,6 +167,7 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
{
if(!isEnabledViaContext(context, ENABLE_KEY, true))
{
LOG.info("JSR-356 is disabled by configuration");
return;
}

View File

@ -1,45 +0,0 @@
//
// ========================================================================
// 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.jsr356.server;
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 MappedResource<WebSocketCreator> getMapping(String target)
{
return null;
}
}

View File

@ -18,8 +18,6 @@
package org.eclipse.jetty.websocket.server;
import org.eclipse.jetty.http.pathmap.MappedResource;
import org.eclipse.jetty.websocket.server.pathmap.PathSpec;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
/**
@ -27,6 +25,25 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
*/
public interface MappedWebSocketCreator
{
/**
* Add a mapping, of a pathspec to a WebSocketCreator.
* <p>
* Recognized Path Spec syntaxes
* </p>
* <dl>
* <dt><code>/path/to</code> or <code>/</code> or <code>*.ext</code> or <code>servlet|{spec}</code></dt>
* <dd>Servlet Syntax</dd>
* <dt><code>^{spec}</code> or <code>regex|{spec}</code></dt>
* <dd>Regex Syntax</dd>
* <dt><code>uri-template|{spec}</code></dt>
* <dd>URI Template (see JSR356 and RFC6570 level 1)</dd>
* </dl>
*
* @param spec the path spec to use.
* @param creator the websocket creator for this specific mapping
*/
void addMapping(String spec, WebSocketCreator creator);
/**
* Add a mapping.
*
@ -36,7 +53,7 @@ public interface MappedWebSocketCreator
* (support classes moved to generic jetty-http project)
*/
@Deprecated
void addMapping(PathSpec spec, WebSocketCreator creator);
void addMapping(org.eclipse.jetty.websocket.server.pathmap.PathSpec spec, WebSocketCreator creator);
/**
* Add a mapping.
@ -48,11 +65,19 @@ public interface MappedWebSocketCreator
void addMapping(org.eclipse.jetty.http.pathmap.PathSpec spec, WebSocketCreator creator);
/**
* Get specific MappedResource for associated target.
/**
* Returns the creator for the given path spec.
*
* @param target the target to get mapping for
* @return the MappedResource for the target, or null if no match.
* @since 9.2.20
* @param spec @param spec the spec to test for (using the same spec syntax as seen in {@link #addMapping(String, WebSocketCreator)})
* @return the websocket creator if path spec exists, or null
*/
MappedResource<WebSocketCreator> getMapping(String target);
WebSocketCreator getMapping(String spec);
/**
* Removes the mapping based on the given path spec.
*
* @param spec the path spec to remove (using the same spec syntax as seen in {@link #addMapping(String, WebSocketCreator)})
* @return true if underlying mapping were altered, false otherwise
*/
boolean removeMapping(String spec);
}

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.websocket.server;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.ServletContext;
@ -27,6 +28,7 @@ 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.http.pathmap.UriTemplatePathSpec;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.websocket.api.WebSocketException;
@ -41,7 +43,7 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
* Only applicable if using {@link WebSocketUpgradeFilter}
* </p>
*/
public class NativeWebSocketConfiguration extends ContainerLifeCycle implements Dumpable
public class NativeWebSocketConfiguration extends ContainerLifeCycle implements MappedWebSocketCreator, Dumpable
{
private final WebSocketServerFactory factory;
private final PathMappings<WebSocketCreator> mappings = new PathMappings<>();
@ -135,7 +137,7 @@ public class NativeWebSocketConfiguration extends ContainerLifeCycle implements
*
* @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 use {@link #addMapping(PathSpec, WebSocketCreator)} instead.
*/
@Deprecated
public void addMapping(org.eclipse.jetty.websocket.server.pathmap.PathSpec spec, WebSocketCreator creator)
@ -164,23 +166,92 @@ public class NativeWebSocketConfiguration extends ContainerLifeCycle implements
*/
public void addMapping(PathSpec pathSpec, final Class<?> endpointClass)
{
mappings.put(pathSpec, new WebSocketCreator()
mappings.put(pathSpec, (req, resp) ->
{
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
try
{
try
{
return endpointClass.newInstance();
}
catch (InstantiationException | IllegalAccessException e)
{
throw new WebSocketException("Unable to create instance of " + endpointClass.getName(), e);
}
return endpointClass.newInstance();
}
catch (InstantiationException | IllegalAccessException e)
{
throw new WebSocketException("Unable to create instance of " + endpointClass.getName(), e);
}
});
}
@Override
public void addMapping(String rawspec, WebSocketCreator creator)
{
PathSpec spec = toPathSpec(rawspec);
addMapping(spec, creator);
}
private PathSpec toPathSpec(String rawspec)
{
// Determine what kind of path spec we are working with
if (rawspec.charAt(0) == '/' || rawspec.startsWith("*.") || rawspec.startsWith("servlet|"))
{
return new ServletPathSpec(rawspec);
}
else if (rawspec.charAt(0) == '^' || rawspec.startsWith("regex|"))
{
return new RegexPathSpec(rawspec);
}
else if (rawspec.startsWith("uri-template|"))
{
return new UriTemplatePathSpec(rawspec.substring("uri-template|".length()));
}
// TODO: add ability to load arbitrary jetty-http PathSpec implementation
// TODO: perhaps via "fully.qualified.class.name|spec" style syntax
throw new IllegalArgumentException("Unrecognized path spec syntax [" + rawspec + "]");
}
@Override
public WebSocketCreator getMapping(String rawspec)
{
PathSpec pathSpec = toPathSpec(rawspec);
for (MappedResource<WebSocketCreator> mapping : mappings)
{
if (mapping.getPathSpec().equals(pathSpec))
return mapping.getResource();
}
return null;
}
@Override
public boolean removeMapping(String rawspec)
{
PathSpec pathSpec = toPathSpec(rawspec);
boolean removed = false;
for (Iterator<MappedResource<WebSocketCreator>> iterator = mappings.iterator(); iterator.hasNext(); )
{
MappedResource<WebSocketCreator> mapping = iterator.next();
if (mapping.getPathSpec().equals(pathSpec))
{
iterator.remove();
removed = true;
}
}
return removed;
}
/**
* Manually add a WebSocket mapping.
*
* @param rawspec the pathspec to map to (see {@link MappedWebSocketCreator#addMapping(String, WebSocketCreator)} for syntax details)
* @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(String rawspec, final Class<?> endpointClass)
{
PathSpec pathSpec = toPathSpec(rawspec);
addMapping(pathSpec, endpointClass);
}
private class PersistedWebSocketCreator implements WebSocketCreator
{
private final WebSocketCreator delegate;

View File

@ -144,6 +144,18 @@ public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, D
configuration.addMapping(spec, creator);
}
@Override
public void addMapping(String spec, WebSocketCreator creator)
{
configuration.addMapping(spec, creator);
}
@Override
public boolean removeMapping(String spec)
{
return configuration.removeMapping(spec);
}
@Override
public void destroy()
{
@ -278,9 +290,9 @@ public class WebSocketUpgradeFilter implements Filter, MappedWebSocketCreator, D
}
@Override
public MappedResource<WebSocketCreator> getMapping(String target)
public WebSocketCreator getMapping(String target)
{
return getConfiguration().getMatch(target);
return getConfiguration().getMapping(target);
}
@Override

View File

@ -66,11 +66,23 @@ public class WebSocketUpgradeHandlerWrapper extends HandlerWrapper implements Ma
{
configuration.addMapping(spec, creator);
}
@Override
public MappedResource<WebSocketCreator> getMapping(String target)
public void addMapping(String spec, WebSocketCreator creator)
{
return this.configuration.getMatch(target);
configuration.addMapping(spec, creator);
}
@Override
public boolean removeMapping(String spec)
{
return configuration.removeMapping(spec);
}
@Override
public WebSocketCreator getMapping(String target)
{
return configuration.getMapping(target);
}
@Override

View File

@ -21,7 +21,6 @@ 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;
@ -35,7 +34,7 @@ public class InfoContextAltAttributeListener implements WebSocketCreator, Servle
{
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(sce.getServletContext());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), this);
configuration.addMapping("/info/*", this);
sce.getServletContext().setAttribute(ATTR, configuration);
}

View File

@ -21,7 +21,6 @@ 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;
@ -33,7 +32,7 @@ public class InfoContextAttributeListener implements WebSocketCreator, ServletCo
{
NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) sce.getServletContext().getAttribute(NativeWebSocketConfiguration.class.getName());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), this);
configuration.addMapping("/info/*", this);
}
@Override

View File

@ -21,7 +21,6 @@ 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;
@ -33,7 +32,7 @@ public class InfoContextListener implements WebSocketCreator, ServletContextList
{
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(sce.getServletContext());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), this);
configuration.addMapping("/info/*", this);
sce.getServletContext().setAttribute(NativeWebSocketConfiguration.class.getName(), configuration);
}

View File

@ -23,7 +23,6 @@ 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;
@ -42,6 +41,6 @@ public class InfoServlet extends HttpServlet implements WebSocketCreator
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);
configuration.addMapping("/info/*", this);
}
}

View File

@ -223,13 +223,13 @@ public class WebSocketCloseTest
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
{
client.setProtocols("fastclose");
client.setTimeout(1,TimeUnit.SECONDS);
client.setTimeout(5,TimeUnit.SECONDS);
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
// Verify that client got close frame
EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
EventQueue<WebSocketFrame> frames = client.readFrames(1,5,TimeUnit.SECONDS);
WebSocketFrame frame = frames.poll();
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
CloseInfo close = new CloseInfo(frame);
@ -239,7 +239,7 @@ public class WebSocketCloseTest
client.write(close.asFrame()); // respond with close
// ensure server socket got close event
assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
assertThat("Fast Close Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true));
assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL));
}
}
@ -256,14 +256,14 @@ public class WebSocketCloseTest
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
{
client.setProtocols("fastfail");
client.setTimeout(1,TimeUnit.SECONDS);
client.setTimeout(5,TimeUnit.SECONDS);
try (StacklessLogging scope = new StacklessLogging(FastFailSocket.class, WebSocketSession.class))
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
EventQueue<WebSocketFrame> frames = client.readFrames(1,5,TimeUnit.SECONDS);
WebSocketFrame frame = frames.poll();
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
CloseInfo close = new CloseInfo(frame);
@ -272,7 +272,7 @@ public class WebSocketCloseTest
client.write(close.asFrame()); // respond with close
// ensure server socket got close event
assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true));
assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR));
assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1));
}

View File

@ -60,7 +60,7 @@ public class WebSocketUpgradeFilterTest
@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))
@ -110,7 +110,7 @@ public class WebSocketUpgradeFilterTest
// direct configuration via WSUF
wsuf.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
wsuf.addMapping(new ServletPathSpec("/info/*"), infoCreator);
wsuf.addMapping("/info/*", infoCreator);
server.start();
return server;
@ -139,7 +139,7 @@ public class WebSocketUpgradeFilterTest
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);
configuration.addMapping("/info/*", infoCreator);
server.start();
@ -166,7 +166,7 @@ public class WebSocketUpgradeFilterTest
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(context.getServletContext());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), infoCreator);
configuration.addMapping("/info/*", infoCreator);
context.setAttribute(NativeWebSocketConfiguration.class.getName(), configuration);
server.start();
@ -193,7 +193,7 @@ public class WebSocketUpgradeFilterTest
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(context.getServletContext());
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
configuration.addMapping(new ServletPathSpec("/info/*"), infoCreator);
configuration.addMapping("/info/*", infoCreator);
context.addBean(configuration, true);
FilterHolder wsufHolder = new FilterHolder(new WebSocketUpgradeFilter(configuration));

View File

@ -1,22 +1,26 @@
<?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">
<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>
<!-- disable JSR-356 -->
<context-param>
<param-name>org.eclipse.jetty.websocket.jsr356</param-name>
<param-value>false</param-value>
</context-param>
<filter>
<filter-name>wsuf</filter-name>
<filter-class>org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter</filter-class>
</filter>
<listener>
<listener-class>org.eclipse.jetty.websocket.server.InfoContextAttributeListener</listener-class>
</listener>
<filter-mapping>
<filter-name>wsuf</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>

View File

@ -1,24 +1,28 @@
<?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">
<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>
<!-- disable JSR-356 -->
<context-param>
<param-name>org.eclipse.jetty.websocket.jsr356</param-name>
<param-value>false</param-value>
</context-param>
<filter>
<filter-name>wsuf</filter-name>
<filter-class>org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter</filter-class>
</filter>
<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-mapping>
<filter-name>wsuf</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>