Merge pull request #4723 from eclipse/jetty-10.0.x-WebSocketServlet

Issue #4722 - remove websocket-servlet
This commit is contained in:
Lachlan 2020-05-07 22:45:04 +10:00 committed by GitHub
commit 2e1c01ac8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 400 additions and 739 deletions

View File

@ -178,7 +178,7 @@
<!-- websocket support -->
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>

View File

@ -107,7 +107,7 @@
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>

View File

@ -66,7 +66,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>

View File

@ -376,7 +376,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>10.0.0-SNAPSHOT</version>
</dependency>
<dependency>

View File

@ -69,7 +69,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

View File

@ -663,7 +663,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>

View File

@ -323,7 +323,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>

View File

@ -196,8 +196,8 @@ public class TestOSGiUtil
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-plus").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-annotations").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-core").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-servlet").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-util-server").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-api").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-server").versionAsInProject().start());
res.add(mavenBundle().groupId("org.eclipse.jetty.websocket").artifactId("websocket-jetty-client").versionAsInProject().start());

View File

@ -15,8 +15,8 @@
<modules>
<module>websocket-core</module>
<module>websocket-servlet</module>
<module>websocket-util</module>
<module>websocket-util-server</module>
<!-- Jetty WebSocket Implementation -->
<module>websocket-jetty-api</module>
<module>websocket-jetty-common</module>

View File

@ -31,7 +31,7 @@ import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.websocket.core.CoreSession;
import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.eclipse.jetty.websocket.util.TextUtil;
import org.eclipse.jetty.websocket.util.TextUtils;
import org.eclipse.jetty.websocket.util.messages.MessageOutputStream;
import org.eclipse.jetty.websocket.util.messages.MessageWriter;
import org.slf4j.Logger;
@ -184,7 +184,7 @@ public class JavaxWebSocketAsyncRemote extends JavaxWebSocketRemoteEndpoint impl
assertMessageNotNull(text);
if (LOG.isDebugEnabled())
{
LOG.debug("sendText({})", TextUtil.hint(text));
LOG.debug("sendText({})", TextUtils.hint(text));
}
FutureCallback future = new FutureCallback();
sendFrame(new Frame(OpCode.TEXT).setPayload(text), future, batch);
@ -198,7 +198,7 @@ public class JavaxWebSocketAsyncRemote extends JavaxWebSocketRemoteEndpoint impl
assertSendHandlerNotNull(handler);
if (LOG.isDebugEnabled())
{
LOG.debug("sendText({},{})", TextUtil.hint(text), handler);
LOG.debug("sendText({},{})", TextUtils.hint(text), handler);
}
sendFrame(new Frame(OpCode.TEXT).setPayload(text), new SendHandlerCallback(handler), batch);
}

View File

@ -31,7 +31,7 @@ import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.websocket.core.CoreSession;
import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.eclipse.jetty.websocket.util.TextUtil;
import org.eclipse.jetty.websocket.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -118,7 +118,7 @@ public class JavaxWebSocketBasicRemote extends JavaxWebSocketRemoteEndpoint impl
assertMessageNotNull(text);
if (LOG.isDebugEnabled())
{
LOG.debug("sendText({})", TextUtil.hint(text));
LOG.debug("sendText({})", TextUtils.hint(text));
}
FutureCallback b = new FutureCallback();
@ -132,7 +132,7 @@ public class JavaxWebSocketBasicRemote extends JavaxWebSocketRemoteEndpoint impl
assertMessageNotNull(partialMessage);
if (LOG.isDebugEnabled())
{
LOG.debug("sendText({},{})", TextUtil.hint(partialMessage), isLast);
LOG.debug("sendText({},{})", TextUtils.hint(partialMessage), isLast);
}
Frame frame;

View File

@ -22,7 +22,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>

View File

@ -12,8 +12,8 @@ annotations
[lib]
lib/websocket/websocket-core-${jetty.version}.jar
lib/websocket/websocket-servlet-${jetty.version}.jar
lib/websocket/websocket-util-${jetty.version}.jar
lib/websocket/websocket-util-server-${jetty.version}.jar
lib/websocket/jetty-javax-websocket-api-1.1.2.jar
lib/websocket/websocket-javax-client-${jetty.version}.jar
lib/websocket/websocket-javax-common-${jetty.version}.jar

View File

@ -31,7 +31,7 @@ module org.eclipse.jetty.websocket.javax.server
requires transitive org.eclipse.jetty.webapp;
requires transitive org.eclipse.jetty.websocket.javax.client;
requires org.eclipse.jetty.websocket.javax.common;
requires org.eclipse.jetty.websocket.servlet;
requires org.eclipse.jetty.websocket.util.server;
requires org.slf4j;
provides ServletContainerInitializer with JavaxWebSocketServletContainerInitializer;

View File

@ -37,7 +37,7 @@ public class JavaxWebSocketConfiguration extends AbstractConfiguration
{
addDependencies(WebXmlConfiguration.class, MetaInfConfiguration.class, WebInfConfiguration.class, FragmentConfiguration.class);
addDependents("org.eclipse.jetty.annotations.AnnotationConfiguration", WebAppConfiguration.class.getName());
protectAndExpose("org.eclipse.jetty.websocket.servlet."); // For WebSocketUpgradeFilter
protectAndExpose("org.eclipse.jetty.websocket.util.server."); // For WebSocketUpgradeFilter
protectAndExpose("org.eclipse.jetty.websocket.javax.server.config.");
protectAndExpose("org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainerProvider");
hide("org.eclipse.jetty.websocket.javax.server.internal");

View File

@ -38,8 +38,8 @@ import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.thread.ThreadClassLoaderScope;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer;
import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -22,7 +22,7 @@ import java.net.URI;
import java.security.Principal;
import org.eclipse.jetty.websocket.javax.common.UpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
public class JavaxServerUpgradeRequest implements UpgradeRequest
{

View File

@ -37,9 +37,9 @@ import org.eclipse.jetty.websocket.javax.common.ConfiguredEndpoint;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketExtension;
import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper;
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.util.server.internal.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketCreator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -39,7 +39,7 @@ import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient;
import org.eclipse.jetty.websocket.core.exception.WebSocketException;
import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer;
import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -27,9 +27,9 @@ import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientFrameHandlerFactory;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerMetadata;
import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.FrameHandlerFactory;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketClientFrameHandlerFactory implements FrameHandlerFactory
{

View File

@ -25,7 +25,7 @@ import java.util.Map;
import javax.websocket.server.HandshakeRequest;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
public class JsrHandshakeRequest implements HandshakeRequest
{

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import javax.websocket.HandshakeResponse;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
public class JsrHandshakeResponse implements HandshakeResponse
{

View File

@ -27,7 +27,6 @@ import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.Handler;
@ -50,11 +49,6 @@ import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSessionListener;
import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerContainer;
import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketServerFrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -259,28 +253,6 @@ public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provi
servletContextHandler.addServlet(holder, urlPattern);
}
public void registerWebSocket(String urlPattern, WebSocketCreator creator)
{
ServletHolder holder = new ServletHolder(new WebSocketServlet()
{
JavaxWebSocketServerFrameHandlerFactory factory = new JavaxWebSocketServerFrameHandlerFactory(JavaxWebSocketServerContainer.ensureContainer(getServletContext()));
@Override
public void configure(WebSocketServletFactory factory)
{
PathSpec pathSpec = factory.parsePathSpec("/");
factory.addMapping(pathSpec, creator);
}
@Override
protected FrameHandlerFactory getFactory()
{
return factory;
}
});
servletContextHandler.addServlet(holder, urlPattern);
}
public JavaxWebSocketServerContainer getServerContainer()
{
if (!servletContextHandler.isRunning())

View File

@ -47,7 +47,7 @@ import org.eclipse.jetty.websocket.core.OpCode;
import org.eclipse.jetty.websocket.core.server.Negotiation;
import org.eclipse.jetty.websocket.javax.tests.CoreServer;
import org.eclipse.jetty.websocket.javax.tests.DataUtils;
import org.eclipse.jetty.websocket.util.TextUtil;
import org.eclipse.jetty.websocket.util.TextUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
@ -328,7 +328,7 @@ public class MessageReceivingTest
{
if (LOG.isDebugEnabled())
{
LOG.debug("{}.onWholeText({})", EchoWholeMessageFrameHandler.class.getSimpleName(), TextUtil.hint(wholeMessage));
LOG.debug("{}.onWholeText({})", EchoWholeMessageFrameHandler.class.getSimpleName(), TextUtils.hint(wholeMessage));
}
sendText(wholeMessage, callback, false);

View File

@ -30,6 +30,7 @@ import org.eclipse.jetty.websocket.core.OpCode;
import org.eclipse.jetty.websocket.javax.tests.Fuzzer;
import org.eclipse.jetty.websocket.javax.tests.WSServer;
import org.eclipse.jetty.websocket.javax.tests.server.sockets.echo.BasicEchoSocket;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -38,7 +39,7 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
/**
* Testing the use of an alternate {@link org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter}
* Testing the use of an alternate {@link WebSocketUpgradeFilter}
* defined in the WEB-INF/web.xml
*/
@ExtendWith(WorkDirExtension.class)

View File

@ -13,7 +13,7 @@
<filter>
<filter-name>wsuf-test</filter-name>
<filter-class>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-class>
<filter-class>org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter</filter-class>
</filter>
<filter-mapping>

View File

@ -12,7 +12,7 @@
<filter>
<filter-name>wsuf-alt</filter-name>
<filter-class>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-class>
<filter-class>org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter</filter-class>
<init-param>
<param-name>configAttributeKey</param-name>
<param-value>alt.config</param-value>

View File

@ -16,7 +16,7 @@
<filter>
<filter-name>wsuf</filter-name>
<filter-class>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-class>
<filter-class>org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter</filter-class>
</filter>
<filter-mapping>

View File

@ -18,7 +18,7 @@
<filter>
<filter-name>wsuf</filter-name>
<filter-class>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-class>
<filter-class>org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter</filter-class>
</filter>
<filter-mapping>

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.core.CloseStatus;
import org.eclipse.jetty.websocket.util.TextUtil;
import org.eclipse.jetty.websocket.util.TextUtils;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
@ -62,7 +62,7 @@ public class EndPoints
@Override
public void onWebSocketClose(int statusCode, String reason)
{
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason));
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtils.quote(reason));
}
@Override
@ -74,13 +74,13 @@ public class EndPoints
@Override
public void onWebSocketError(Throwable cause)
{
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage()));
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtils.quote(cause.getMessage()));
}
@Override
public void onWebSocketText(String message)
{
events.add("onWebSocketText(%s)", TextUtil.quote(message));
events.add("onWebSocketText(%s)", TextUtils.quote(message));
}
}
@ -91,7 +91,7 @@ public class EndPoints
@Override
public void onWebSocketClose(int statusCode, String reason)
{
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason));
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtils.quote(reason));
}
@Override
@ -103,7 +103,7 @@ public class EndPoints
@Override
public void onWebSocketError(Throwable cause)
{
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage()));
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtils.quote(cause.getMessage()));
}
@Override
@ -120,7 +120,7 @@ public class EndPoints
@Override
public void onWebSocketClose(int statusCode, String reason)
{
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason));
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtils.quote(reason));
}
@Override
@ -132,13 +132,13 @@ public class EndPoints
@Override
public void onWebSocketError(Throwable cause)
{
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage()));
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtils.quote(cause.getMessage()));
}
@Override
public void onWebSocketPartialText(String payload, boolean fin)
{
events.add("onWebSocketPartialText(%s, %b)", TextUtil.quote(payload), fin);
events.add("onWebSocketPartialText(%s, %b)", TextUtils.quote(payload), fin);
}
@Override
@ -155,7 +155,7 @@ public class EndPoints
@Override
public void onWebSocketClose(int statusCode, String reason)
{
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtil.quote(reason));
events.add("onWebSocketClose(%s, %s)", CloseStatus.codeString(statusCode), TextUtils.quote(reason));
}
@Override
@ -167,7 +167,7 @@ public class EndPoints
@Override
public void onWebSocketError(Throwable cause)
{
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtil.quote(cause.getMessage()));
events.add("onWebSocketError((%s) %s)", cause.getClass().getSimpleName(), TextUtils.quote(cause.getMessage()));
}
@Override
@ -228,7 +228,7 @@ public class EndPoints
@OnWebSocketClose
public void onClose(int statusCode, String reason)
{
events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason));
events.add("onClose(%d, %s)", statusCode, TextUtils.quote(reason));
}
@OnWebSocketConnect
@ -253,7 +253,7 @@ public class EndPoints
@OnWebSocketClose
public void onClose(int statusCode, String reason)
{
events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason));
events.add("onClose(%d, %s)", statusCode, TextUtils.quote(reason));
}
@OnWebSocketConnect
@ -271,7 +271,7 @@ public class EndPoints
@OnWebSocketClose
public void onClose(int statusCode, String reason)
{
events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason));
events.add("onClose(%d, %s)", statusCode, TextUtils.quote(reason));
}
@OnWebSocketConnect
@ -289,7 +289,7 @@ public class EndPoints
@OnWebSocketMessage
public void onText(String message)
{
events.add("onText(%s)", TextUtil.quote(message));
events.add("onText(%s)", TextUtils.quote(message));
}
}
@ -301,7 +301,7 @@ public class EndPoints
@OnWebSocketClose
public void onClose(int statusCode, String reason)
{
events.add("onClose(%d, %s)", statusCode, TextUtil.quote(reason));
events.add("onClose(%d, %s)", statusCode, TextUtils.quote(reason));
}
@OnWebSocketConnect

View File

@ -48,7 +48,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<artifactId>websocket-util-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>

View File

@ -12,8 +12,8 @@ annotations
[lib]
lib/websocket/websocket-core-${jetty.version}.jar
lib/websocket/websocket-servlet-${jetty.version}.jar
lib/websocket/websocket-util-${jetty.version}.jar
lib/websocket/websocket-util-server-${jetty.version}.jar
lib/websocket/websocket-jetty-api-${jetty.version}.jar
lib/websocket/websocket-jetty-common-${jetty.version}.jar
lib/websocket/websocket-jetty-server-${jetty.version}.jar

View File

@ -29,10 +29,10 @@ module org.eclipse.jetty.websocket.jetty.server
requires jetty.servlet.api;
requires org.eclipse.jetty.websocket.jetty.common;
requires org.eclipse.jetty.websocket.util.server;
requires org.slf4j;
requires transitive org.eclipse.jetty.webapp;
requires transitive org.eclipse.jetty.websocket.jetty.api;
requires transitive org.eclipse.jetty.websocket.servlet;
requires org.slf4j;
// Only required if using JMX.
requires static org.eclipse.jetty.jmx;

View File

@ -36,7 +36,7 @@ import javax.servlet.http.HttpSession;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.websocket.core.server.Negotiation;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
public class JettyServerUpgradeRequest
{

View File

@ -26,7 +26,7 @@ import java.util.stream.Collectors;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
public class JettyServerUpgradeResponse
{

View File

@ -41,8 +41,8 @@ import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.exception.WebSocketException;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.server.internal.JettyServerFrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
import org.eclipse.jetty.websocket.util.server.internal.FrameHandlerFactory;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -18,23 +18,101 @@
package org.eclipse.jetty.websocket.server;
import org.eclipse.jetty.websocket.server.internal.JettyServerFrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.time.Duration;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class JettyWebSocketServlet extends WebSocketServlet
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.websocket.core.Configuration;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.server.internal.JettyServerFrameHandlerFactory;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.util.server.internal.FrameHandlerFactory;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketCreator;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract Servlet used to bridge the Servlet API to the WebSocket API.
* <p>
* To use this servlet, you will be required to register your websockets with the {@link WebSocketMapping} so that it can create your websockets under the
* appropriate conditions.
* </p>
* <p>The most basic implementation would be as follows:</p>
* <pre>
* package my.example;
*
* import JettyWebSocketServlet;
* import JettyWebSocketServletFactory;
*
* public class MyEchoServlet extends JettyWebSocketServlet
* {
* &#064;Override
* public void configure(JettyWebSocketServletFactory factory)
* {
* factory.setDefaultMaxFrameSize(4096);
* factory.addMapping(factory.parsePathSpec("/"), (req,res)-&gt;new EchoSocket());
* }
* }
* </pre>
* <p>
* Only request that conforms to a "WebSocket: Upgrade" handshake request will trigger the {@link WebSocketMapping} handling of creating
* WebSockets. All other requests are treated as normal servlet requests. The configuration defined by this servlet init parameters will
* be used as the customizer for any mappings created by {@link JettyWebSocketServletFactory#addMapping(String, JettyWebSocketCreator)} during
* {@link #configure(JettyWebSocketServletFactory)} calls. The request upgrade may be peformed by this servlet, or is may be performed by a
* {@link WebSocketUpgradeFilter} instance that will share the same {@link WebSocketMapping} instance. If the filter is used, then the
* filter configuraton is used as the default configuration prior to this servlets configuration being applied.
* </p>
* <p>
* <b>Configuration / Init-Parameters:</b>
* </p>
* <dl>
* <dt>idleTimeout</dt>
* <dd>set the time in ms that a websocket may be idle before closing<br>
* <dt>maxTextMessageSize</dt>
* <dd>set the size in UTF-8 bytes that a websocket may be accept as a Text Message before closing<br>
* <dt>maxBinaryMessageSize</dt>
* <dd>set the size in bytes that a websocket may be accept as a Binary Message before closing<br>
* <dt>inputBufferSize</dt>
* <dd>set the size in bytes of the buffer used to read raw bytes from the network layer<br> * <dt>outputBufferSize</dt>
* <dd>set the size in bytes of the buffer used to write bytes to the network layer<br>
* <dt>maxFrameSize</dt>
* <dd>The maximum frame size sent or received.<br>
* <dt>autoFragment</dt>
* <dd>If true, frames are automatically fragmented to respect the maximum frame size.<br>
* </dl>
*/
public abstract class JettyWebSocketServlet extends HttpServlet
{
private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketServlet.class);
private final CustomizedWebSocketServletFactory customizer = new CustomizedWebSocketServletFactory();
private WebSocketMapping mapping;
private WebSocketComponents components;
/**
* Configure the JettyWebSocketServletFactory for this servlet instance by setting default
* configuration (which may be overriden by annotations) and mapping {@link JettyWebSocketCreator}s.
* This method assumes a single {@link FrameHandlerFactory} will be available as a bean on the
* {@link ContextHandler}, which in practise will mostly the the Jetty WebSocket API factory.
*
* @param factory the JettyWebSocketServletFactory
*/
protected abstract void configure(JettyWebSocketServletFactory factory);
@Override
protected final void configure(WebSocketServletFactory factory)
{
configure(new JettyWebSocketServletFactory(factory));
}
@Override
protected FrameHandlerFactory getFactory()
/**
* @return the instance of {@link FrameHandlerFactory} to be used to create the FrameHandler
*/
private FrameHandlerFactory getFactory()
{
JettyServerFrameHandlerFactory frameHandlerFactory = JettyServerFrameHandlerFactory.getFactory(getServletContext());
@ -43,4 +121,163 @@ public abstract class JettyWebSocketServlet extends WebSocketServlet
return frameHandlerFactory;
}
@Override
public void init() throws ServletException
{
try
{
ServletContext servletContext = getServletContext();
components = WebSocketComponents.ensureWebSocketComponents(servletContext);
mapping = new WebSocketMapping(components);
String max = getInitParameter("idleTimeout");
if (max == null)
{
max = getInitParameter("maxIdleTime");
if (max != null)
LOG.warn("'maxIdleTime' init param is deprecated, use 'idleTimeout' instead");
}
if (max != null)
customizer.setIdleTimeout(Duration.ofMillis(Long.parseLong(max)));
max = getInitParameter("maxTextMessageSize");
if (max != null)
customizer.setMaxTextMessageSize(Long.parseLong(max));
max = getInitParameter("maxBinaryMessageSize");
if (max != null)
customizer.setMaxBinaryMessageSize(Long.parseLong(max));
max = getInitParameter("inputBufferSize");
if (max != null)
customizer.setInputBufferSize(Integer.parseInt(max));
max = getInitParameter("outputBufferSize");
if (max != null)
customizer.setOutputBufferSize(Integer.parseInt(max));
max = getInitParameter("maxFrameSize");
if (max == null)
max = getInitParameter("maxAllowedFrameSize");
if (max != null)
customizer.setMaxFrameSize(Long.parseLong(max));
String autoFragment = getInitParameter("autoFragment");
if (autoFragment != null)
customizer.setAutoFragment(Boolean.parseBoolean(autoFragment));
configure(customizer); // Let user modify customizer prior after init params
}
catch (Throwable x)
{
throw new ServletException(x);
}
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// provide a null default customizer the customizer will be on the negotiator in the mapping
if (mapping.upgrade(req, resp, null))
return;
// If we reach this point, it means we had an incoming request to upgrade
// but it was either not a proper websocket upgrade, or it was possibly rejected
// due to incoming request constraints (controlled by WebSocketCreator)
if (resp.isCommitted())
return;
// Handle normally
super.service(req, resp);
}
private class CustomizedWebSocketServletFactory extends Configuration.ConfigurationCustomizer implements JettyWebSocketServletFactory
{
@Override
public Set<String> getAvailableExtensionNames()
{
return components.getExtensionRegistry().getAvailableExtensionNames();
}
@Override
public void addMapping(String pathSpec, JettyWebSocketCreator creator)
{
mapping.addMapping(WebSocketMapping.parsePathSpec(pathSpec), new WrappedJettyCreator(creator), getFactory(), this);
}
@Override
public void register(Class<?> endpointClass)
{
Constructor<?> constructor;
try
{
constructor = endpointClass.getDeclaredConstructor();
}
catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
JettyWebSocketCreator creator = (req, resp) ->
{
try
{
return constructor.newInstance();
}
catch (Throwable t)
{
t.printStackTrace();
return null;
}
};
addMapping("/", creator);
}
@Override
public void setCreator(JettyWebSocketCreator creator)
{
addMapping("/", creator);
}
@Override
public JettyWebSocketCreator getMapping(String pathSpec)
{
WebSocketCreator creator = mapping.getMapping(WebSocketMapping.parsePathSpec(pathSpec));
if (creator instanceof WrappedJettyCreator)
return ((WrappedJettyCreator)creator).getJettyWebSocketCreator();
return null;
}
@Override
public boolean removeMapping(String pathSpec)
{
return mapping.removeMapping(WebSocketMapping.parsePathSpec(pathSpec));
}
}
private static class WrappedJettyCreator implements WebSocketCreator
{
private JettyWebSocketCreator creator;
private WrappedJettyCreator(JettyWebSocketCreator creator)
{
this.creator = creator;
}
private JettyWebSocketCreator getJettyWebSocketCreator()
{
return creator;
}
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
return creator.createWebSocket(new JettyServerUpgradeRequest(req), new JettyServerUpgradeResponse(resp));
}
}
}

View File

@ -18,123 +18,15 @@
package org.eclipse.jetty.websocket.server;
import java.time.Duration;
import java.util.Set;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
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;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
public class JettyWebSocketServletFactory implements WebSocketPolicy
public interface JettyWebSocketServletFactory extends WebSocketPolicy
{
private WebSocketServletFactory factory;
JettyWebSocketServletFactory(WebSocketServletFactory factory)
{
this.factory = factory;
}
public Set<String> getAvailableExtensionNames()
{
return factory.getExtensionRegistry().getAvailableExtensionNames();
}
@Override
public WebSocketBehavior getBehavior()
{
return WebSocketBehavior.SERVER;
}
@Override
public boolean isAutoFragment()
{
return factory.isAutoFragment();
}
@Override
public void setAutoFragment(boolean autoFragment)
{
factory.setAutoFragment(autoFragment);
}
@Override
public long getMaxFrameSize()
{
return factory.getMaxFrameSize();
}
@Override
public void setMaxFrameSize(long maxFrameSize)
{
factory.setMaxFrameSize(maxFrameSize);
}
@Override
public Duration getIdleTimeout()
{
return factory.getIdleTimeout();
}
@Override
public void setIdleTimeout(Duration duration)
{
factory.setIdleTimeout(duration);
}
@Override
public int getInputBufferSize()
{
return factory.getInputBufferSize();
}
@Override
public void setInputBufferSize(int bufferSize)
{
factory.setInputBufferSize(bufferSize);
}
@Override
public long getMaxBinaryMessageSize()
{
return factory.getMaxBinaryMessageSize();
}
@Override
public void setMaxBinaryMessageSize(long bufferSize)
{
factory.setMaxBinaryMessageSize(bufferSize);
}
@Override
public long getMaxTextMessageSize()
{
return factory.getMaxTextMessageSize();
}
@Override
public void setMaxTextMessageSize(long bufferSize)
{
factory.setMaxTextMessageSize(bufferSize);
}
@Override
public int getOutputBufferSize()
{
return factory.getOutputBufferSize();
}
@Override
public void setOutputBufferSize(int bufferSize)
{
factory.setOutputBufferSize(bufferSize);
}
/**
* add a WebSocket mapping to a provided {@link JettyWebSocketCreator}.
* Add a WebSocket mapping to a provided {@link JettyWebSocketCreator}.
* <p>
* If mapping is added before this configuration is started, then it is persisted through
* stop/start of this configuration's lifecycle. Otherwise it will be removed when
@ -145,30 +37,21 @@ public class JettyWebSocketServletFactory implements WebSocketPolicy
* @param creator the WebSocketCreator to use
* @since 10.0
*/
public void addMapping(String pathSpec, JettyWebSocketCreator creator)
{
factory.addMapping(pathSpec, new WrappedCreator(creator));
}
void addMapping(String pathSpec, JettyWebSocketCreator creator);
/**
* Add a WebSocket mapping at PathSpec "/" for a creator which creates the endpointClass
*
* @param endpointClass the WebSocket class to use
*/
public void register(Class<?> endpointClass)
{
factory.register(endpointClass);
}
void register(Class<?> endpointClass);
/**
* Add a WebSocket mapping at PathSpec "/" for a creator
*
* @param creator the WebSocketCreator to use
*/
public void setCreator(JettyWebSocketCreator creator)
{
factory.setCreator(new WrappedCreator(creator));
}
void setCreator(JettyWebSocketCreator creator);
/**
* Returns the creator for the given path spec.
@ -176,14 +59,7 @@ public class JettyWebSocketServletFactory implements WebSocketPolicy
* @param pathSpec the pathspec to respond on
* @return the websocket creator if path spec exists, or null
*/
public JettyWebSocketCreator getMapping(String pathSpec)
{
WebSocketCreator creator = factory.getMapping(parsePathSpec(pathSpec));
if (creator instanceof WrappedCreator)
return ((WrappedCreator)creator).getCreator();
return null;
}
JettyWebSocketCreator getMapping(String pathSpec);
/**
* Removes the mapping based on the given path spec.
@ -191,40 +67,17 @@ public class JettyWebSocketServletFactory implements WebSocketPolicy
* @param pathSpec the pathspec to respond on
* @return true if underlying mapping were altered, false otherwise
*/
public boolean removeMapping(String pathSpec)
{
return factory.removeMapping(parsePathSpec(pathSpec));
}
boolean removeMapping(String pathSpec);
/**
* Parse a PathSpec string into a PathSpec instance.
*
* @param rawSpec the raw path spec as String to parse.
* @return the {@link PathSpec} implementation for the rawSpec
* Get the names of all available WebSocket Extensions.
* @return a set the available extension names.
*/
private PathSpec parsePathSpec(String rawSpec)
Set<String> getAvailableExtensionNames();
@Override
default WebSocketBehavior getBehavior()
{
return factory.parsePathSpec(rawSpec);
}
private static class WrappedCreator implements WebSocketCreator
{
private JettyWebSocketCreator creator;
private WrappedCreator(JettyWebSocketCreator creator)
{
this.creator = creator;
}
public JettyWebSocketCreator getCreator()
{
return creator;
}
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
return creator.createWebSocket(new JettyServerUpgradeRequest(req), new JettyServerUpgradeResponse(resp));
}
return WebSocketBehavior.SERVER;
}
}

View File

@ -58,7 +58,8 @@ public class JettyWebSocketConfiguration extends AbstractConfiguration
protectAndExpose(
"org.eclipse.jetty.websocket.api.",
"org.eclipse.jetty.websocket.server.");
"org.eclipse.jetty.websocket.server.",
"org.eclipse.jetty.websocket.util.server."); // For WebSocketUpgradeFilter
hide("org.eclipse.jetty.server.internal.",
"org.eclipse.jetty.server.config.");

View File

@ -27,8 +27,8 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.listener.ContainerInitializer;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
import org.eclipse.jetty.websocket.servlet.WebSocketMapping;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -27,9 +27,9 @@ import org.eclipse.jetty.websocket.api.WebSocketContainer;
import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler;
import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.servlet.FrameHandlerFactory;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.FrameHandlerFactory;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
public class JettyServerFrameHandlerFactory
extends JettyWebSocketFrameHandlerFactory

View File

@ -28,7 +28,7 @@ import java.util.stream.Collectors;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeRequest;
public class UpgradeRequestAdapter implements UpgradeRequest
{

View File

@ -27,7 +27,7 @@ import java.util.stream.Collectors;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.util.server.internal.ServletUpgradeResponse;
public class UpgradeResponseAdapter implements UpgradeResponse
{

View File

@ -39,7 +39,7 @@ import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.common.WebSocketSession;
import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@ -64,7 +64,7 @@ import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.server.JettyWebSocketServlet;
import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.servlet.internal.UpgradeHttpServletRequest;
import org.eclipse.jetty.websocket.util.server.internal.UpgradeHttpServletRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

View File

@ -45,11 +45,11 @@ import org.eclipse.jetty.websocket.api.util.WSURI;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint;
import org.eclipse.jetty.websocket.tests.EchoSocket;
import org.eclipse.jetty.websocket.tests.GetAuthHeaderEndpoint;
import org.eclipse.jetty.websocket.tests.SimpleStatusServlet;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.hamcrest.Matcher;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;

View File

@ -44,13 +44,13 @@ import org.eclipse.jetty.websocket.api.util.WSURI;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.tests.AnnoMaxMessageEndpoint;
import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint;
import org.eclipse.jetty.websocket.tests.ConnectMessageEndpoint;
import org.eclipse.jetty.websocket.tests.EchoSocket;
import org.eclipse.jetty.websocket.tests.ParamsEndpoint;
import org.eclipse.jetty.websocket.tests.util.FutureWriteCallback;
import org.eclipse.jetty.websocket.util.server.WebSocketUpgradeFilter;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;

View File

@ -47,7 +47,7 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServlet;
import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.tests.CloseTrackingEndpoint;
import org.eclipse.jetty.websocket.util.TextUtil;
import org.eclipse.jetty.websocket.util.TextUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -293,7 +293,7 @@ public class PartialListenerTest
@Override
public void onWebSocketPartialText(String payload, boolean fin)
{
partialEvents.offer(String.format("TEXT[payload=%s, fin=%b]", TextUtil.maxStringLength(30, payload), fin));
partialEvents.offer(String.format("TEXT[payload=%s, fin=%b]", TextUtils.maxStringLength(30, payload), fin));
}
}
}

View File

@ -1,263 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.time.Duration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.websocket.core.Configuration;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract Servlet used to bridge the Servlet API to the WebSocket API.
* <p>
* To use this servlet, you will be required to register your websockets with the {@link WebSocketMapping} so that it can create your websockets under the
* appropriate conditions.
* </p>
* <p>The most basic implementation would be as follows:</p>
* <pre>
* package my.example;
*
* import WebSocketServlet;
* import WebSocketServletFactory;
*
* public class MyEchoServlet extends WebSocketServlet
* {
* &#064;Override
* public void configure(WebSocketServletFactory factory)
* {
* factory.setDefaultMaxFrameSize(4096);
* factory.addMapping(factory.parsePathSpec("/"), (req,res)-&gt;new EchoSocket());
* }
* }
* </pre>
* <p>
* Only request that conforms to a "WebSocket: Upgrade" handshake request will trigger the {@link WebSocketMapping} handling of creating
* WebSockets. All other requests are treated as normal servlet requests. The configuration defined by this servlet init parameters will
* be used as the customizer for any mappings created by {@link WebSocketServletFactory#addMapping(PathSpec, WebSocketCreator)} during
* {@link #configure(WebSocketServletFactory)} calls. The request upgrade may be peformed by this servlet, or is may be performed by a
* {@link WebSocketUpgradeFilter} instance that will share the same {@link WebSocketMapping} instance. If the filter is used, then the
* filter configuraton is used as the default configuration prior to this servlets configuration being applied.
* </p>
* <p>
* <b>Configuration / Init-Parameters:</b>
* </p>
* <dl>
* <dt>idleTimeout</dt>
* <dd>set the time in ms that a websocket may be idle before closing<br>
* <dt>maxTextMessageSize</dt>
* <dd>set the size in UTF-8 bytes that a websocket may be accept as a Text Message before closing<br>
* <dt>maxBinaryMessageSize</dt>
* <dd>set the size in bytes that a websocket may be accept as a Binary Message before closing<br>
* <dt>inputBufferSize</dt>
* <dd>set the size in bytes of the buffer used to read raw bytes from the network layer<br> * <dt>outputBufferSize</dt>
* <dd>set the size in bytes of the buffer used to write bytes to the network layer<br>
* <dt>maxFrameSize</dt>
* <dd>The maximum frame size sent or received.<br>
* <dt>autoFragment</dt>
* <dd>If true, frames are automatically fragmented to respect the maximum frame size.<br>
* </dl>
*/
@SuppressWarnings("serial")
public abstract class WebSocketServlet extends HttpServlet
{
private static final Logger LOG = LoggerFactory.getLogger(WebSocketServlet.class);
private final CustomizedWebSocketServletFactory customizer = new CustomizedWebSocketServletFactory();
private WebSocketMapping mapping;
private WebSocketComponents components;
/**
* Configure the WebSocketServletFactory for this servlet instance by setting default
* configuration (which may be overriden by annotations) and mapping {@link WebSocketCreator}s.
* This method assumes a single {@link FrameHandlerFactory} will be available as a bean on the
* {@link ContextHandler}, which in practise will mostly the the Jetty WebSocket API factory.
*
* @param factory the WebSocketServletFactory
*/
protected abstract void configure(WebSocketServletFactory factory);
/**
* @return the instance of {@link FrameHandlerFactory} to be used to create the FrameHandler
*/
protected abstract FrameHandlerFactory getFactory();
@Override
public void init() throws ServletException
{
try
{
ServletContext servletContext = getServletContext();
components = WebSocketComponents.ensureWebSocketComponents(servletContext);
mapping = new WebSocketMapping(components);
String max = getInitParameter("idleTimeout");
if (max == null)
{
max = getInitParameter("maxIdleTime");
if (max != null)
LOG.warn("'maxIdleTime' init param is deprecated, use 'idleTimeout' instead");
}
if (max != null)
customizer.setIdleTimeout(Duration.ofMillis(Long.parseLong(max)));
max = getInitParameter("maxTextMessageSize");
if (max != null)
customizer.setMaxTextMessageSize(Long.parseLong(max));
max = getInitParameter("maxBinaryMessageSize");
if (max != null)
customizer.setMaxBinaryMessageSize(Long.parseLong(max));
max = getInitParameter("inputBufferSize");
if (max != null)
customizer.setInputBufferSize(Integer.parseInt(max));
max = getInitParameter("outputBufferSize");
if (max != null)
customizer.setOutputBufferSize(Integer.parseInt(max));
max = getInitParameter("maxFrameSize");
if (max == null)
max = getInitParameter("maxAllowedFrameSize");
if (max != null)
customizer.setMaxFrameSize(Long.parseLong(max));
String autoFragment = getInitParameter("autoFragment");
if (autoFragment != null)
customizer.setAutoFragment(Boolean.parseBoolean(autoFragment));
configure(customizer); // Let user modify customizer prior after init params
}
catch (Throwable x)
{
throw new ServletException(x);
}
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// provide a null default customizer the customizer will be on the negotiator in the mapping
if (mapping.upgrade(req, resp, null))
return;
// If we reach this point, it means we had an incoming request to upgrade
// but it was either not a proper websocket upgrade, or it was possibly rejected
// due to incoming request constraints (controlled by WebSocketCreator)
if (resp.isCommitted())
return;
// Handle normally
super.service(req, resp);
}
private class CustomizedWebSocketServletFactory extends Configuration.ConfigurationCustomizer implements WebSocketServletFactory
{
@Override
public WebSocketExtensionRegistry getExtensionRegistry()
{
return components.getExtensionRegistry();
}
@Override
public void addMapping(String pathSpec, WebSocketCreator creator)
{
addMapping(WebSocketMapping.parsePathSpec(pathSpec), creator);
}
@Override
public void addMapping(PathSpec pathSpec, WebSocketCreator creator)
{
mapping.addMapping(pathSpec, creator, getFactory(), this);
}
@Override
public void register(Class<?> endpointClass)
{
Constructor<?> constructor;
try
{
constructor = endpointClass.getDeclaredConstructor();
}
catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
WebSocketCreator creator = (req, resp) ->
{
try
{
return constructor.newInstance();
}
catch (Throwable t)
{
t.printStackTrace();
return null;
}
};
addMapping("/", creator);
}
@Override
public void setCreator(WebSocketCreator creator)
{
addMapping("/", creator);
}
@Override
public WebSocketCreator getMapping(PathSpec pathSpec)
{
return mapping.getMapping(pathSpec);
}
@Override
public WebSocketCreator getMatch(String target)
{
throw new UnsupportedOperationException();
}
@Override
public boolean removeMapping(PathSpec pathSpec)
{
return mapping.removeMapping(pathSpec);
}
@Override
public PathSpec parsePathSpec(String pathSpec)
{
return WebSocketMapping.parsePathSpec(pathSpec);
}
}
}

View File

@ -1,101 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.websocket.core.Configuration;
import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
public interface WebSocketServletFactory extends Configuration
{
WebSocketExtensionRegistry getExtensionRegistry();
void addMapping(String pathSpec, WebSocketCreator creator);
/**
* add a WebSocket mapping to a provided {@link WebSocketCreator}.
* <p>
* If mapping is added before this configuration is started, then it is persisted through
* stop/start of this configuration's lifecycle. Otherwise it will be removed when
* this configuration is stopped.
* </p>
*
* @param pathSpec the pathspec to respond on
* @param creator the WebSocketCreator to use
* @since 10.0
*/
void addMapping(PathSpec pathSpec, WebSocketCreator creator);
/**
* Add a WebSocket mapping at PathSpec "/" for a creator which creates the endpointClass
*
* @param endpointClass the WebSocket class to use
*/
void register(Class<?> endpointClass);
/**
* Add a WebSocket mapping at PathSpec "/" for a creator
*
* @param creator the WebSocketCreator to use
*/
void setCreator(WebSocketCreator creator);
/**
* Returns the creator for the given path spec.
*
* @param pathSpec the pathspec to respond on
* @return the websocket creator if path spec exists, or null
*/
WebSocketCreator getMapping(PathSpec pathSpec);
/**
* Get the MappedResource for the given target path.
*
* @param target the target path
* @return the MappedResource if matched, or null if not matched.
*/
WebSocketCreator getMatch(String target);
/**
* Parse a PathSpec string into a PathSpec instance.
* <p>
* Recognized Path Spec syntaxes:
* </p>
* <dl>
* <dt>{@code /path/to} or {@code /} or {@code *.ext} or {@code servlet|{spec}}</dt>
* <dd>Servlet Syntax</dd>
* <dt>{@code ^{spec}} or {@code regex|{spec}}</dt>
* <dd>Regex Syntax</dd>
* <dt>{@code uri-template|{spec}}</dt>
* <dd>URI Template (see JSR356 and RFC6570 level 1)</dd>
* </dl>
*
* @param rawSpec the raw path spec as String to parse.
* @return the {@link PathSpec} implementation for the rawSpec
*/
PathSpec parsePathSpec(String rawSpec);
/**
* Removes the mapping based on the given path spec.
*
* @param pathSpec the pathspec to respond on
* @return true if underlying mapping were altered, false otherwise
*/
boolean removeMapping(PathSpec pathSpec);
}

View File

@ -7,80 +7,19 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>websocket-servlet</artifactId>
<name>Jetty :: Websocket :: Servlet</name>
<artifactId>websocket-util-server</artifactId>
<name>Jetty :: Websocket :: org.eclipse.jetty.websocket :: Util-Server</name>
<properties>
<bundle-symbolic-name>${project.groupId}.servlet</bundle-symbolic-name>
<bundle-symbolic-name>${project.groupId}.util.server</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-jetty-api</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>artifact-jars</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-ws-apis</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>org.eclipse.jetty.websocket:websocket-jetty-api</include>
<include>javax.websocket</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
<execution>
<id>ban-java-servlet-api</id>
<goals>
@ -109,15 +48,13 @@
<extensions>true</extensions>
<executions>
<execution>
<id>generate-manifest</id>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Bundle-Description>javax.websocket.servlet Implementation</Bundle-Description>
<Export-Package>
org.eclipse.jetty.websocket.servlet.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"
</Export-Package>
<Export-Package>*,org.eclipse.jetty.websocket.util.server.internal.*</Export-Package>
</instructions>
</configuration>
</execution>
@ -125,4 +62,32 @@
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -16,11 +16,12 @@
// ========================================================================
//
module org.eclipse.jetty.websocket.servlet
module org.eclipse.jetty.websocket.util.server
{
exports org.eclipse.jetty.websocket.servlet;
exports org.eclipse.jetty.websocket.util.server;
exports org.eclipse.jetty.websocket.util.server.internal to org.eclipse.jetty.websocket.jetty.server, org.eclipse.jetty.websocket.javax.server;
requires org.slf4j;
requires transitive org.eclipse.jetty.servlet;
requires transitive org.eclipse.jetty.websocket.core;
requires org.slf4j;
}

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
package org.eclipse.jetty.websocket.util.server;
import java.io.IOException;
import java.time.Duration;
@ -35,11 +35,11 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.websocket.core.Configuration;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -123,7 +123,7 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
return holder;
}
public static final String MAPPING_ATTRIBUTE_INIT_PARAM = "org.eclipse.jetty.websocket.servlet.WebSocketMapping.key";
public static final String MAPPING_ATTRIBUTE_INIT_PARAM = "org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping.key";
private final Configuration.ConfigurationCustomizer defaultCustomizer = new Configuration.ConfigurationCustomizer();
private WebSocketMapping mapping;
@ -159,12 +159,6 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
Dumpable.dumpObjects(out, indent, this, mapping);
}
@ManagedAttribute(value = "factory", readonly = true)
public WebSocketMapping getMapping()
{
return mapping;
}
@Override
public void init(FilterConfig config) throws ServletException
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
package org.eclipse.jetty.websocket.util.server.internal;
import org.eclipse.jetty.websocket.core.FrameHandler;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
package org.eclipse.jetty.websocket.util.server.internal;
import java.net.HttpCookie;
import java.net.InetSocketAddress;
@ -42,7 +42,6 @@ import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.websocket.core.ExtensionConfig;
import org.eclipse.jetty.websocket.core.WebSocketConstants;
import org.eclipse.jetty.websocket.core.server.Negotiation;
import org.eclipse.jetty.websocket.servlet.internal.UpgradeHttpServletRequest;
/**
* Holder of request data for a WebSocket upgrade request.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
package org.eclipse.jetty.websocket.util.server.internal;
import java.io.IOException;
import java.util.ArrayList;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet.internal;
package org.eclipse.jetty.websocket.util.server.internal;
import java.io.BufferedReader;
import java.net.InetSocketAddress;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
package org.eclipse.jetty.websocket.util.server.internal;
/**
* Abstract WebSocket creator interface.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.servlet;
package org.eclipse.jetty.websocket.util.server.internal;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
@ -45,8 +45,6 @@ import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
/**
* Mapping of pathSpec to a tupple of {@link WebSocketCreator}, {@link FrameHandlerFactory} and
* {@link Configuration.Customizer}.
@ -136,7 +134,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
throw new IllegalArgumentException("Unrecognized path spec syntax [" + rawSpec + "]");
}
public static final String DEFAULT_KEY = "org.eclipse.jetty.websocket.servlet.WebSocketMapping";
public static final String DEFAULT_KEY = "org.eclipse.jetty.websocket.util.server.internal.WebSocketMapping";
private final PathMappings<Negotiator> mappings = new PathMappings<>();
private final WebSocketComponents components;
@ -281,7 +279,7 @@ public class WebSocketMapping implements Dumpable, LifeCycle.Listener
if (websocketPojo == null)
{
// no creation, sorry
upgradeResponse.sendError(SC_SERVICE_UNAVAILABLE, "WebSocket Endpoint Creation Refused");
upgradeResponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "WebSocket Endpoint Creation Refused");
return null;
}

View File

@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.util;
/**
* Collection of utility methods for Text content
*/
public final class TextUtil
public final class TextUtils
{
/**
* Create a hint of what the text is like.

View File

@ -67,7 +67,7 @@ public class PartialStringMessageSinkTest
List<String> message = Objects.requireNonNull(endpoint.messages.poll(5, TimeUnit.SECONDS));
assertThat(message.size(), is(1));
assertThat(message.get(0), is("\uD800\uDF48"));
assertThat(message.get(0), is("\uD800\uDF48")); // UTF-8 encoded payload.
}
@Test
@ -87,7 +87,7 @@ public class PartialStringMessageSinkTest
List<String> message = Objects.requireNonNull(endpoint.messages.poll(5, TimeUnit.SECONDS));
assertThat(message.size(), is(2));
assertThat(message.get(0), is(""));
assertThat(message.get(1), is("\uD800\uDF48"));
assertThat(message.get(1), is("\uD800\uDF48")); // UTF-8 encoded payload.
}
@Test

View File

@ -72,7 +72,7 @@ public class StringMessageSinkTest
messageSink.accept(new Frame(OpCode.TEXT, utf8Payload).setFin(true), callback);
callback.block(5, TimeUnit.SECONDS);
assertThat(endpoint.messages.poll(5, TimeUnit.SECONDS), is("\uD800\uDF48"));
assertThat(endpoint.messages.poll(5, TimeUnit.SECONDS), is("\uD800\uDF48")); // UTF-8 encoded payload.
}
@Test
@ -90,7 +90,7 @@ public class StringMessageSinkTest
messageSink.accept(new Frame(OpCode.TEXT, continuationUtf8Payload).setFin(true), callback);
callback.block(5, TimeUnit.SECONDS);
assertThat(endpoint.messages.poll(5, TimeUnit.SECONDS), is("\uD800\uDF48"));
assertThat(endpoint.messages.poll(5, TimeUnit.SECONDS), is("\uD800\uDF48")); // UTF-8 encoded payload.
}
@Test

View File

@ -17,11 +17,13 @@
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-javax-websocket-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-javax-common</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>

View File

@ -25,11 +25,13 @@
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-javax-websocket-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-javax-common</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>