Issue #10687 - WebSocket remembers mappings on restart (#10773)

* Clear websocket mappings on server stop
* Fix core WebSocketUpgradeHandler on restart
* Avoid usage of deprecated WebSocketUpgradeHandler.configure() method.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Co-authored-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Lachlan 2023-11-21 03:09:56 +11:00 committed by GitHub
parent da2c601cd7
commit ecb90e8d0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 473 additions and 262 deletions

View File

@ -173,11 +173,7 @@ public class WebSocketServerDocs
server.setHandler(contextHandler);
// Create a WebSocketUpgradeHandler that implicitly creates a ServerWebSocketContainer.
WebSocketUpgradeHandler webSocketHandler = WebSocketUpgradeHandler.from(server, contextHandler);
contextHandler.setHandler(webSocketHandler);
// Here you can access the ServerWebSocketContainer through the WebSocketUpgradeHandler APIs.
webSocketHandler.configure(container ->
WebSocketUpgradeHandler webSocketHandler = WebSocketUpgradeHandler.from(server, contextHandler, container ->
{
// Configure the ServerWebSocketContainer.
container.setMaxTextMessageSize(128 * 1024);
@ -194,6 +190,7 @@ public class WebSocketServerDocs
return null;
});
});
contextHandler.setHandler(webSocketHandler);
// Starting the Server will start the ContextHandler and the WebSocketUpgradeHandler,
// which would run the configuration of the ServerWebSocketContainer.
@ -285,11 +282,7 @@ public class WebSocketServerDocs
server.setHandler(contextHandler);
// Create a WebSocketUpgradeHandler.
WebSocketUpgradeHandler webSocketHandler = WebSocketUpgradeHandler.from(server, contextHandler);
contextHandler.setHandler(webSocketHandler);
// Here you can access the ServerWebSocketContainer through the WebSocketUpgradeHandler APIs.
webSocketHandler.configure(container ->
WebSocketUpgradeHandler webSocketHandler = WebSocketUpgradeHandler.from(server, contextHandler, container ->
{
container.addMapping("/ws/chat/{room}", (upgradeRequest, upgradeResponse, callback) ->
{
@ -305,6 +298,7 @@ public class WebSocketServerDocs
return new MyWebSocketRoomEndPoint(room);
});
});
contextHandler.setHandler(webSocketHandler);
// end::uriTemplatePathSpec[]
}

View File

@ -60,11 +60,13 @@ public class WebSocketMappings implements Dumpable, LifeCycle.Listener
public static WebSocketMappings ensureMappings(ContextHandler contextHandler)
{
WebSocketMappings mapping = getMappings(contextHandler);
if (mapping == null)
WebSocketMappings mappings = getMappings(contextHandler);
if (mappings == null)
{
mapping = new WebSocketMappings(WebSocketServerComponents.getWebSocketComponents(contextHandler));
contextHandler.setAttribute(WEBSOCKET_MAPPING_ATTRIBUTE, mapping);
mappings = new WebSocketMappings(WebSocketServerComponents.getWebSocketComponents(contextHandler));
contextHandler.setAttribute(WEBSOCKET_MAPPING_ATTRIBUTE, mappings);
contextHandler.addBean(mappings);
WebSocketMappings m = mappings;
contextHandler.addEventListener(new LifeCycle.Listener()
{
@Override
@ -72,11 +74,12 @@ public class WebSocketMappings implements Dumpable, LifeCycle.Listener
{
contextHandler.removeAttribute(WEBSOCKET_MAPPING_ATTRIBUTE);
contextHandler.removeEventListener(this);
contextHandler.removeBean(m);
}
});
}
return mapping;
return mappings;
}
/**
@ -143,15 +146,14 @@ public class WebSocketMappings implements Dumpable, LifeCycle.Listener
}
@Override
public void lifeCycleStopping(LifeCycle context)
public void lifeCycleStopping(LifeCycle event)
{
ContextHandler contextHandler = (ContextHandler)context;
WebSocketMappings mapping = contextHandler.getBean(WebSocketMappings.class);
if (mapping == this)
{
contextHandler.removeBean(mapping);
mappings.reset();
}
clear();
}
public void clear()
{
mappings.reset();
}
@Override

View File

@ -13,6 +13,8 @@
package org.eclipse.jetty.websocket.core.server;
import java.util.function.Consumer;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.server.Handler;
@ -24,17 +26,30 @@ import org.eclipse.jetty.websocket.core.WebSocketComponents;
public class WebSocketUpgradeHandler extends Handler.Wrapper
{
private final WebSocketMappings mappings;
private final Configuration.ConfigurationCustomizer customizer = new Configuration.ConfigurationCustomizer();
private final WebSocketMappings _mappings;
private final Configuration.ConfigurationCustomizer _customizer = new Configuration.ConfigurationCustomizer();
private final Consumer<WebSocketUpgradeHandler> _configurator;
public WebSocketUpgradeHandler()
{
this(new WebSocketComponents());
this(null, null);
}
public WebSocketUpgradeHandler(WebSocketComponents components)
{
this.mappings = new WebSocketMappings(components);
this(components, null);
}
public WebSocketUpgradeHandler(Consumer<WebSocketUpgradeHandler> configurator)
{
this(null, configurator);
}
public WebSocketUpgradeHandler(WebSocketComponents components, Consumer<WebSocketUpgradeHandler> configurator)
{
_mappings = new WebSocketMappings(components == null ? new WebSocketComponents() : components);
_configurator = configurator;
addBean(_mappings);
setHandler(new Handler.Abstract.NonBlocking()
{
@Override
@ -48,17 +63,25 @@ public class WebSocketUpgradeHandler extends Handler.Wrapper
public void addMapping(String pathSpec, WebSocketNegotiator negotiator)
{
mappings.addMapping(WebSocketMappings.parsePathSpec(pathSpec), negotiator);
_mappings.addMapping(WebSocketMappings.parsePathSpec(pathSpec), negotiator);
}
public void addMapping(PathSpec pathSpec, WebSocketNegotiator negotiator)
{
mappings.addMapping(pathSpec, negotiator);
_mappings.addMapping(pathSpec, negotiator);
}
@Override
protected void doStart() throws Exception
{
if (_configurator != null)
_configurator.accept(this);
super.doStart();
}
public Configuration getConfiguration()
{
return customizer;
return _customizer;
}
@Override
@ -66,7 +89,7 @@ public class WebSocketUpgradeHandler extends Handler.Wrapper
{
try
{
if (mappings.upgrade(request, response, callback, customizer))
if (_mappings.upgrade(request, response, callback, _customizer))
return true;
return super.handle(request, response, callback);
}

View File

@ -0,0 +1,86 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.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.core;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient;
import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RestartTest
{
private Server _server;
private ServerConnector _connector;
private WebSocketCoreClient _client;
private WebSocketUpgradeHandler _upgradeHandler;
@BeforeEach
public void before() throws Exception
{
_server = new Server();
_connector = new ServerConnector(_server);
_server.addConnector(_connector);
_upgradeHandler = new WebSocketUpgradeHandler(handler ->
handler.addMapping("/", (req, resp, cb) -> new EchoFrameHandler()));
_server.setHandler(_upgradeHandler);
_server.start();
_client = new WebSocketCoreClient();
_client.start();
}
@AfterEach
public void after() throws Exception
{
_client.stop();
_server.stop();
}
@Test
public void test() throws Exception
{
testEcho();
_server.stop();
assertThat(_upgradeHandler.dump(), containsString("PathMappings[size=0]"));
_server.start();
testEcho();
}
private void testEcho() throws Exception
{
TestMessageHandler clientEndpoint = new TestMessageHandler();
URI uri = URI.create("ws://localhost:" + _connector.getLocalPort());
_client.connect(clientEndpoint, uri);
assertTrue(clientEndpoint.openLatch.await(5, TimeUnit.SECONDS));
clientEndpoint.sendText("hello world");
String message = clientEndpoint.textMessages.poll(5, TimeUnit.SECONDS);
assertThat(message, equalTo("hello world"));
clientEndpoint.getCoreSession().close(Callback.NOOP);
assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS));
}
}

View File

@ -75,4 +75,12 @@ public class TestMessageHandler extends MessageHandler
binaryMessages.offer(message);
callback.succeeded();
}
public void sendText(String text)
{
if (LOG.isDebugEnabled())
LOG.debug("sendText {} ", text);
Frame frame = new Frame(OpCode.TEXT, text);
getCoreSession().sendFrame(frame, Callback.NOOP, false);
}
}

View File

@ -80,6 +80,7 @@ public class ServerWebSocketContainer extends ContainerLifeCycle implements WebS
WebSocketComponents components = WebSocketServerComponents.ensureWebSocketComponents(server, contextHandler);
WebSocketMappings mappings = new WebSocketMappings(components);
container = new ServerWebSocketContainer(mappings);
container.addBean(mappings);
context.setAttribute(WebSocketContainer.class.getName(), container);
}
return container;

View File

@ -80,40 +80,95 @@ public class WebSocketUpgradeHandler extends Handler.Wrapper
* @param server the {@link Server} object used to lookup common WebSocket components
* @param context the {@link ContextHandler} ancestor of the returned {@link WebSocketUpgradeHandler}
* @return a new {@link WebSocketUpgradeHandler}
* @see #configure(Consumer)
*/
public static WebSocketUpgradeHandler from(Server server, ContextHandler context)
{
return from(server, context, null);
}
/**
* <p>Creates a new {@link WebSocketUpgradeHandler}.</p>
* <p>The {@link WebSocketUpgradeHandler} is not yet linked to the given
* {@link ContextHandler}, therefore the caller code must ensure that
* the returned {@link WebSocketUpgradeHandler} is a descendant of the
* given {@link ContextHandler}.</p>
*
* @param server the {@link Server} object used to lookup common WebSocket components
* @param context the {@link ContextHandler} ancestor of the returned {@link WebSocketUpgradeHandler}
* @param configurator a {@link Consumer} that is called to allow the {@link ServerWebSocketContainer} to
* be configured during the starting phase of the {@link WebSocketUpgradeHandler}.
* @return a new {@link WebSocketUpgradeHandler}
*/
public static WebSocketUpgradeHandler from(Server server, ContextHandler context, Consumer<ServerWebSocketContainer> configurator)
{
WebSocketComponents components = WebSocketServerComponents.ensureWebSocketComponents(server, context);
WebSocketMappings mappings = new WebSocketMappings(components);
ServerWebSocketContainer container = new ServerWebSocketContainer(mappings);
container.addBean(mappings);
WebSocketUpgradeHandler wsHandler = new WebSocketUpgradeHandler(container);
WebSocketUpgradeHandler wsHandler = new WebSocketUpgradeHandler(container, configurator);
context.getContext().setAttribute(WebSocketContainer.class.getName(), wsHandler._container);
return wsHandler;
}
private final ServerWebSocketContainer _container;
private final Consumer<ServerWebSocketContainer> _configurator;
/**
* <p>Creates a new {@link WebSocketUpgradeHandler} with the given {@link ServerWebSocketContainer}.</p>
*
* @param container the {@link ServerWebSocketContainer} of this {@link WebSocketUpgradeHandler}
*/
public WebSocketUpgradeHandler(ServerWebSocketContainer container)
{
this(container, null);
}
/**
* <p>Creates a new {@link WebSocketUpgradeHandler} with the given {@link ServerWebSocketContainer}
* and the given configurator.</p>
* <p>The configurator is invoked every time this {@link WebSocketUpgradeHandler} is started,
* see {@link #from(Server, ContextHandler, Consumer)}.</p>
*
* @param container the {@link ServerWebSocketContainer} of this {@link WebSocketUpgradeHandler}
* @param configurator the code to configure the {@link ServerWebSocketContainer}
*/
public WebSocketUpgradeHandler(ServerWebSocketContainer container, Consumer<ServerWebSocketContainer> configurator)
{
_container = container;
addBean(container);
_configurator = configurator;
addManaged(container);
}
/**
* <p>Configures the {@link ServerWebSocketContainer} associated with this
* {@link WebSocketUpgradeHandler}.</p>
* <p>This configuration is applied immediately and lost after a server restart.</p>
*
* @param configurator the configuration code
* @return this {@link WebSocketUpgradeHandler}
* @deprecated use {@link #getServerWebSocketContainer()} or {@link #from(Server, ContextHandler, Consumer)}.
*/
@Deprecated
public WebSocketUpgradeHandler configure(Consumer<ServerWebSocketContainer> configurator)
{
configurator.accept(_container);
return this;
}
public ServerWebSocketContainer getServerWebSocketContainer()
{
return _container;
}
@Override
protected void doStart() throws Exception
{
if (_configurator != null)
_configurator.accept(_container);
super.doStart();
}
@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception
{

View File

@ -146,13 +146,12 @@ public class AnnotatedPartialListenerTest
ServerConnector connector = new ServerConnector(server);
server.addConnector(connector);
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setAutoFragment(false);
container.addMapping("/", (rq, rs, cb) -> new PartialEchoSocket());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();
serverUri = URI.create("ws://localhost:" + connector.getLocalPort() + "/");

View File

@ -56,10 +56,9 @@ public class ConcurrentConnectTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> new EchoSocket()));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -50,10 +50,9 @@ public class ConnectionHeaderTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/echo", (rq, rs, cb) -> new EchoSocket()));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -75,8 +75,7 @@ public class DemandWithBlockingStreamsTest
public void testBinaryStreamExplicitDemandThrows() throws Exception
{
StreamEndPoint serverEndPoint = new StreamEndPoint();
start(wsHandler -> wsHandler.configure(container ->
container.addMapping("/*", (rq, rs, cb) -> serverEndPoint)));
start(wsHandler -> wsHandler.getServerWebSocketContainer().addMapping("/*", (rq, rs, cb) -> serverEndPoint));
URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/");
EventSocket clientEndPoint = new EventSocket();
@ -95,8 +94,7 @@ public class DemandWithBlockingStreamsTest
public void testTextStreamExplicitDemandThrows() throws Exception
{
StreamEndPoint serverEndPoint = new StreamEndPoint();
start(wsHandler -> wsHandler.configure(container ->
container.addMapping("/*", (rq, rs, cb) -> serverEndPoint)));
start(wsHandler -> wsHandler.getServerWebSocketContainer().addMapping("/*", (rq, rs, cb) -> serverEndPoint));
URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/");
EventSocket clientEndPoint = new EventSocket();

View File

@ -61,9 +61,7 @@ public class ErrorCloseTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.addMapping("/", (rq, rs, cb) -> serverSocket);
container.addSessionListener(new WebSocketSessionListener()
@ -75,6 +73,7 @@ public class ErrorCloseTest
}
});
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -69,10 +69,9 @@ public class ExplicitDemandTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/suspend", (rq, rs, cb) -> serverSocket));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -48,10 +48,9 @@ public class GracefulCloseTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> serverEndpoint));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -97,10 +97,9 @@ public class JettyOnCloseTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> serverEndpoint));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -58,9 +58,7 @@ public class JettyWebSocketExtensionConfigTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) ->
{
assertEquals(rq.getExtensions().stream().filter(e -> e.getName().equals("permessage-deflate")).count(), 1);
@ -79,6 +77,7 @@ public class JettyWebSocketExtensionConfigTest
return new EchoSocket();
}));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -18,6 +18,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import org.eclipse.jetty.client.Request;
import org.eclipse.jetty.client.Response;
@ -31,9 +32,9 @@ import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.JettyUpgradeListener;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.server.ServerWebSocketContainer;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -46,10 +47,8 @@ public class JettyWebSocketNegotiationTest
private Server server;
private ServerConnector connector;
private WebSocketClient client;
private WebSocketUpgradeHandler wsHandler;
@BeforeEach
public void start() throws Exception
public void start(Consumer<ServerWebSocketContainer> configurator) throws Exception
{
server = new Server();
connector = new ServerConnector(server);
@ -57,7 +56,7 @@ public class JettyWebSocketNegotiationTest
ContextHandler context = new ContextHandler("/");
wsHandler = WebSocketUpgradeHandler.from(server, context);
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, configurator);
context.setHandler(wsHandler);
server.setHandler(context);
@ -77,8 +76,7 @@ public class JettyWebSocketNegotiationTest
@Test
public void testBadRequest() throws Exception
{
wsHandler.configure(container ->
container.addMapping("/", (rq, rs, cb) -> new EchoSocket()));
start(container -> container.addMapping("/", (rq, rs, cb) -> new EchoSocket()));
URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/filterPath");
EventSocket socket = new EventSocket();
@ -95,12 +93,11 @@ public class JettyWebSocketNegotiationTest
@Test
public void testServerError() throws Exception
{
wsHandler.configure(container ->
container.addMapping("/", (rq, rs, cb) ->
{
rs.setAcceptedSubProtocol("errorSubProtocol");
return new EchoSocket();
}));
start(container -> container.addMapping("/", (rq, rs, cb) ->
{
rs.setAcceptedSubProtocol("errorSubProtocol");
return new EchoSocket();
}));
URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/filterPath");
EventSocket socket = new EventSocket();
@ -117,19 +114,18 @@ public class JettyWebSocketNegotiationTest
@Test
public void testManualNegotiationInCreator() throws Exception
{
wsHandler.configure(container ->
container.addMapping("/", (rq, rs, cb) ->
{
long matchedExts = rq.getExtensions().stream()
.filter(ec -> "permessage-deflate".equals(ec.getName()))
.filter(ec -> ec.getParameters().containsKey("client_no_context_takeover"))
.count();
assertThat(matchedExts, is(1L));
start(container -> container.addMapping("/", (rq, rs, cb) ->
{
long matchedExts = rq.getExtensions().stream()
.filter(ec -> "permessage-deflate".equals(ec.getName()))
.filter(ec -> ec.getParameters().containsKey("client_no_context_takeover"))
.count();
assertThat(matchedExts, is(1L));
// Manually drop the param so it is not negotiated in the extension stack.
rs.getHeaders().put(HttpHeader.SEC_WEBSOCKET_EXTENSIONS.asString(), "permessage-deflate");
return new EchoSocket();
}));
// Manually drop the param so it is not negotiated in the extension stack.
rs.getHeaders().put(HttpHeader.SEC_WEBSOCKET_EXTENSIONS.asString(), "permessage-deflate");
return new EchoSocket();
}));
URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/filterPath");
EventSocket socket = new EventSocket();

View File

@ -53,15 +53,14 @@ public class LargeDeflateTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(_server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(_server, context, container ->
{
container.setIdleTimeout(Duration.ofDays(1));
container.setMaxFrameSize(Integer.MAX_VALUE);
container.setMaxBinaryMessageSize(Integer.MAX_VALUE);
container.addMapping("/", (rq, rs, cb) -> _serverSocket);
});
context.setHandler(wsHandler);
_server.setHandler(context);
_server.start();

View File

@ -63,14 +63,13 @@ public class MaxOutgoingFramesTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.addMapping("/", (rq, rs, cb) -> serverSocket);
WebSocketComponents components = WebSocketServerComponents.getWebSocketComponents(context);
components.getExtensionRegistry().register(BlockingOutgoingExtension.class.getName(), BlockingOutgoingExtension.class);
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -0,0 +1,89 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.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.tests;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.websocket.api.Callback;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RestartTest
{
private Server _server;
private ServerConnector _connector;
private WebSocketClient _client;
private WebSocketUpgradeHandler upgradeHandler;
@BeforeEach
public void before() throws Exception
{
_server = new Server();
_connector = new ServerConnector(_server);
_server.addConnector(_connector);
ContextHandler contextHandler = new ContextHandler("/");
upgradeHandler = WebSocketUpgradeHandler.from(_server, contextHandler,
container -> container.addMapping("/", (req, resp, cb) -> new EchoSocket()));
contextHandler.setHandler(upgradeHandler);
_server.setHandler(contextHandler);
_server.start();
_client = new WebSocketClient();
_client.start();
}
@AfterEach
public void after() throws Exception
{
_client.stop();
_server.stop();
}
@Test
public void test() throws Exception
{
testEcho();
_server.stop();
assertThat(upgradeHandler.getServerWebSocketContainer().dump(), containsString("PathMappings[size=0]"));
_server.start();
testEcho();
}
private void testEcho() throws Exception
{
EchoSocket clientEndpoint = new EchoSocket();
URI uri = URI.create("ws://localhost:" + _connector.getLocalPort());
_client.connect(clientEndpoint, uri);
assertTrue(clientEndpoint.openLatch.await(5, TimeUnit.SECONDS));
clientEndpoint.session.sendText("hello world", Callback.NOOP);
String message = clientEndpoint.textMessages.poll(5, TimeUnit.SECONDS);
assertThat(message, equalTo("hello world"));
clientEndpoint.session.close();
assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS));
}
}

View File

@ -48,13 +48,12 @@ public class SimpleEchoTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(_server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(_server, context, container ->
{
container.setIdleTimeout(Duration.ZERO);
container.addMapping("/", (rq, rs, cb) -> new EchoSocket());
});
context.setHandler(wsHandler);
_server.setHandler(context);
_server.start();

View File

@ -56,10 +56,9 @@ public class SingleOnMessageTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> serverSocket));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -52,10 +52,9 @@ public class UpgradeRequestResponseTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> serverSocket));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -76,13 +76,12 @@ public class WebSocketStatsTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setAutoFragment(false);
container.addMapping("/", (rq, rs, cb) -> new EchoSocket());
});
context.setHandler(wsHandler);
// Setup JMX.
MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());

View File

@ -53,10 +53,9 @@ public class WebSocketStopTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> serverSocket));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -66,10 +66,9 @@ public class JettyAutobahnServer
server.addConnector(connector);
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (request, response, callback) -> new JettyAutobahnSocket()));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -63,14 +63,13 @@ public class BadNetworkTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(10));
container.setMaxTextMessageSize(1024 * 1024 * 2);
container.addMapping("/ws", (upgradeRequest, upgradeResponse, callback) -> new ServerEndpoint());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -108,9 +108,7 @@ public class ClientCloseTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(10));
container.setMaxTextMessageSize(1024 * 1024 * 2);
@ -121,6 +119,7 @@ public class ClientCloseTest
return endpoint;
});
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -75,10 +75,9 @@ public class ClientConfigTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) -> serverSocket));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -115,9 +115,7 @@ public class ClientConnectTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(10));
container.addMapping("/echo", (upgradeRequest, upgradeResponse, callback) ->
@ -140,6 +138,7 @@ public class ClientConnectTest
return null;
});
});
context.setHandler(wsHandler);
PathMappingsHandler pathsHandler = new PathMappingsHandler();
wsHandler.setHandler(pathsHandler);

View File

@ -57,9 +57,7 @@ public class ClientSessionsTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(10));
container.setMaxTextMessageSize(1024 * 1024 * 2);
@ -70,6 +68,7 @@ public class ClientSessionsTest
return new EchoSocket();
});
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -54,9 +54,7 @@ public class ClientTimeoutTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
{
@ -71,6 +69,7 @@ public class ClientTimeoutTest
}
});
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -91,20 +91,19 @@ public class ConnectFutureTest
CountDownLatch enteredCreator = new CountDownLatch(1);
CountDownLatch exitCreator = new CountDownLatch(1);
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
{
try
{
try
{
enteredCreator.countDown();
exitCreator.await();
return new EchoSocket();
}
catch (InterruptedException e)
{
throw new IllegalStateException(e);
}
})));
enteredCreator.countDown();
exitCreator.await();
return new EchoSocket();
}
catch (InterruptedException e)
{
throw new IllegalStateException(e);
}
}));
CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint();
Future<Session> connect = client.connect(clientSocket, WSURI.toWebsocket(server.getURI()));
@ -127,8 +126,7 @@ public class ConnectFutureTest
public void testAbortSessionOnCreated() throws Exception
{
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket())));
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket()));
CountDownLatch enteredListener = new CountDownLatch(1);
CountDownLatch exitListener = new CountDownLatch(1);
@ -166,8 +164,7 @@ public class ConnectFutureTest
public void testAbortInHandshakeResponse() throws Exception
{
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket())));
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket()));
CountDownLatch enteredListener = new CountDownLatch(1);
CountDownLatch exitListener = new CountDownLatch(1);
@ -192,7 +189,7 @@ public class ConnectFutureTest
ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest();
Future<Session> connect = client.connect(clientSocket, WSURI.toWebsocket(server.getURI()), upgradeRequest, upgradeListener);
// Abort after after handshake response, this is during the connection upgrade.
// Abort after handshake response, this is during the connection upgrade.
assertTrue(enteredListener.await(5, TimeUnit.SECONDS));
assertTrue(connect.cancel(true));
assertThrows(CancellationException.class, () -> connect.get(5, TimeUnit.SECONDS));
@ -206,8 +203,7 @@ public class ConnectFutureTest
public void testAbortOnOpened() throws Exception
{
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket())));
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket()));
CountDownLatch exitOnConnect = new CountDownLatch(1);
CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint()
@ -242,8 +238,7 @@ public class ConnectFutureTest
public void testAbortAfterCompletion() throws Exception
{
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket())));
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket()));
CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint();
Future<Session> connect = client.connect(clientSocket, WSURI.toWebsocket(server.getURI()));
@ -272,19 +267,18 @@ public class ConnectFutureTest
{
CountDownLatch exitCreator = new CountDownLatch(1);
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
{
try
{
try
{
exitCreator.await();
return new EchoSocket();
}
catch (InterruptedException e)
{
throw new IllegalStateException(e);
}
})));
exitCreator.await();
return new EchoSocket();
}
catch (InterruptedException e)
{
throw new IllegalStateException(e);
}
}));
CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint();
Future<Session> connect = client.connect(clientSocket, WSURI.toWebsocket(server.getURI()));
@ -303,19 +297,18 @@ public class ConnectFutureTest
{
CountDownLatch exitCreator = new CountDownLatch(1);
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) ->
{
try
{
try
{
exitCreator.await();
return new EchoSocket();
}
catch (InterruptedException e)
{
throw new IllegalStateException(e);
}
})));
exitCreator.await();
return new EchoSocket();
}
catch (InterruptedException e)
{
throw new IllegalStateException(e);
}
}));
// Complete the CompletableFuture with an exception the during the call to onOpened.
CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint();
@ -344,8 +337,7 @@ public class ConnectFutureTest
public void testAbortWithExceptionAfterUpgrade() throws Exception
{
start(wsHandler ->
wsHandler.configure(container ->
container.addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket())));
wsHandler.getServerWebSocketContainer().addMapping("/", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket()));
CountDownLatch exitOnConnect = new CountDownLatch(1);
CloseTrackingEndpoint clientSocket = new CloseTrackingEndpoint()

View File

@ -62,10 +62,9 @@ public class SlowClientTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/ws", (upgradeRequest, upgradeResponse, callback) -> new EchoSocket()));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -90,9 +90,7 @@ public class WebSocketClientTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(10));
container.addMapping("/echo", (upgradeRequest, upgradeResponse, callback) ->
@ -105,6 +103,7 @@ public class WebSocketClientTest
container.addMapping("/connect-msg", (rq, rs, cb) -> new ConnectMessageEndpoint());
container.addMapping("/get-params", (rq, rs, cb) -> new ParamsEndpoint());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -60,9 +60,7 @@ public class WebSocketListenerTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.addMapping("/echo", (rq, rs, cb) -> new EchoSocket());
for (Class<?> c : getClassListFromArguments(TextListeners.getTextListeners()))
@ -74,6 +72,7 @@ public class WebSocketListenerTest
container.addMapping("/binary/" + c.getSimpleName(), (rq, rs, cb) -> construct(c));
}
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -69,9 +69,7 @@ public class WebSocketProxyTest
ContextHandler context = new ContextHandler();
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.addMapping("/proxy", (rq, rs, cb) -> webSocketProxy.getSessionListener());
serverSocket = new EchoSocket();
@ -82,6 +80,7 @@ public class WebSocketProxyTest
return serverSocket;
});
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -63,13 +63,12 @@ public class FrameAnnotationTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(2));
container.addMapping("/ws", (rq, rs, cb) -> serverEndpoint = new FrameEndpoint());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -58,13 +58,12 @@ public class FrameListenerTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(2));
container.addMapping("/ws", (rq, rs, cb) -> serverEndpoint = new FrameEndpoint());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -58,13 +58,12 @@ public class PartialListenerTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(2));
container.addMapping("/ws", (rq, rs, cb) -> serverEndpoint = new PartialEndpoint());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -63,13 +63,12 @@ public class ServerCloseTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofSeconds(2));
container.addMapping("/ws", serverEndpointCreator = new ServerCloseCreator());
});
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -71,11 +71,11 @@ public class ServerConfigTest
private EventSocket getServerEndpoint(String path)
{
return switch (path)
{
case "servletConfig", "containerConfig" -> standardEndpoint;
case "sessionConfig" -> sessionConfigEndpoint;
default -> throw new IllegalStateException();
};
{
case "servletConfig", "containerConfig" -> standardEndpoint;
case "sessionConfig" -> sessionConfigEndpoint;
default -> throw new IllegalStateException();
};
}
public static Stream<Arguments> data()
@ -101,15 +101,14 @@ public class ServerConfigTest
{
public static WebSocketUpgradeHandler from(Server server, ContextHandler context, Object wsEndPoint)
{
return WebSocketUpgradeHandler.from(server, context)
.configure(container ->
{
container.setIdleTimeout(Duration.ofMillis(IDLE_TIMEOUT));
container.setMaxTextMessageSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageSize(MAX_MESSAGE_SIZE);
container.setInputBufferSize(INPUT_BUFFER_SIZE);
container.addMapping("/", (rq, rs, cb) -> wsEndPoint);
});
return WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofMillis(IDLE_TIMEOUT));
container.setMaxTextMessageSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageSize(MAX_MESSAGE_SIZE);
container.setInputBufferSize(INPUT_BUFFER_SIZE);
container.addMapping("/", (rq, rs, cb) -> wsEndPoint);
});
}
}
@ -117,9 +116,8 @@ public class ServerConfigTest
{
public static WebSocketUpgradeHandler from(Server server, ContextHandler context, Object wsEndPoint)
{
return WebSocketUpgradeHandler.from(server, context)
.configure(container ->
container.addMapping("/", (rq, rs, cb) -> wsEndPoint));
return WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/", (rq, rs, cb) -> wsEndPoint));
}
}
@ -163,15 +161,14 @@ public class ServerConfigTest
context.setHandler(pathsHandler);
pathsHandler.addMapping(new ServletPathSpec("/servletConfig"), ConfigWebSocketUpgradeHandler.from(server, context, standardEndpoint));
pathsHandler.addMapping(new ServletPathSpec("/sessionConfig"), SessionConfigWebSocketUpgradeHandler.from(server, context, sessionConfigEndpoint));
pathsHandler.addMapping(new ServletPathSpec("/"), WebSocketUpgradeHandler.from(server, context)
.configure(container ->
{
container.setIdleTimeout(Duration.ofMillis(IDLE_TIMEOUT));
container.setMaxTextMessageSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageSize(MAX_MESSAGE_SIZE);
container.setInputBufferSize(INPUT_BUFFER_SIZE);
container.addMapping("/containerConfig", (rq, rs, cb) -> standardEndpoint);
}));
pathsHandler.addMapping(new ServletPathSpec("/"), WebSocketUpgradeHandler.from(server, context, container ->
{
container.setIdleTimeout(Duration.ofMillis(IDLE_TIMEOUT));
container.setMaxTextMessageSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageSize(MAX_MESSAGE_SIZE);
container.setInputBufferSize(INPUT_BUFFER_SIZE);
container.addMapping("/containerConfig", (rq, rs, cb) -> standardEndpoint);
}));
server.setHandler(context);
server.start();

View File

@ -61,10 +61,9 @@ public class SlowServerTest
ContextHandler context = new ContextHandler("/");
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context);
context.setHandler(wsHandler);
wsHandler.configure(container ->
WebSocketUpgradeHandler wsHandler = WebSocketUpgradeHandler.from(server, context, container ->
container.addMapping("/ws", (rq, rs, cb) -> new SlowServerEndpoint()));
context.setHandler(wsHandler);
server.setHandler(context);
server.start();

View File

@ -100,7 +100,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketServlet.class);
private final CustomizedWebSocketServletFactory customizer = new CustomizedWebSocketServletFactory();
private WebSocketMappings mapping;
private WebSocketMappings mappings;
private WebSocketComponents components;
/**
@ -133,7 +133,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
{
ServletContextHandler context = ServletContextHandler.getServletContextHandler(getServletContext());
components = WebSocketServerComponents.getWebSocketComponents(context);
mapping = new WebSocketMappings(components);
mappings = new WebSocketMappings(components);
String max = getInitParameter("idleTimeout");
if (max == null)
@ -179,6 +179,13 @@ public abstract class JettyWebSocketServlet extends HttpServlet
}
}
@Override
public void destroy()
{
mappings.clear();
super.destroy();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
@ -187,7 +194,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
ServletContextResponse response = request.getServletContextResponse();
// Do preliminary check before proceeding to attempt an upgrade.
if (mapping.getHandshaker().isWebSocketUpgradeRequest(request))
if (mappings.getHandshaker().isWebSocketUpgradeRequest(request))
{
// provide a null default customizer the customizer will be on the negotiator in the mapping
FutureCallback callback = new FutureCallback();
@ -198,7 +205,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
request.setAttribute(WebSocketConstants.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, req);
request.setAttribute(WebSocketConstants.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, resp);
if (mapping.upgrade(request, response, callback, null))
if (mappings.upgrade(request, response, callback, null))
{
callback.block();
return;
@ -226,7 +233,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
@Override
public void addMapping(String pathSpec, JettyWebSocketCreator creator)
{
mapping.addMapping(WebSocketMappings.parsePathSpec(pathSpec), new WrappedJettyCreator(creator), getFactory(), this);
mappings.addMapping(WebSocketMappings.parsePathSpec(pathSpec), new WrappedJettyCreator(creator), getFactory(), this);
}
@Override
@ -250,7 +257,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
}
catch (Throwable t)
{
t.printStackTrace();
LOG.warn("Failed to construct new Endpoint", t);
return null;
}
};
@ -267,7 +274,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
@Override
public JettyWebSocketCreator getMapping(String pathSpec)
{
WebSocketCreator creator = mapping.getWebSocketCreator(WebSocketMappings.parsePathSpec(pathSpec));
WebSocketCreator creator = mappings.getWebSocketCreator(WebSocketMappings.parsePathSpec(pathSpec));
if (creator instanceof WrappedJettyCreator)
return ((WrappedJettyCreator)creator).getJettyWebSocketCreator();
return null;
@ -276,18 +283,12 @@ public abstract class JettyWebSocketServlet extends HttpServlet
@Override
public boolean removeMapping(String pathSpec)
{
return mapping.removeMapping(WebSocketMappings.parsePathSpec(pathSpec));
return mappings.removeMapping(WebSocketMappings.parsePathSpec(pathSpec));
}
}
private static class WrappedJettyCreator implements WebSocketCreator
private record WrappedJettyCreator(JettyWebSocketCreator creator) implements WebSocketCreator
{
private final JettyWebSocketCreator creator;
private WrappedJettyCreator(JettyWebSocketCreator creator)
{
this.creator = creator;
}
private JettyWebSocketCreator getJettyWebSocketCreator()
{

View File

@ -101,7 +101,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
private static final Logger LOG = LoggerFactory.getLogger(JettyWebSocketServlet.class);
private final CustomizedWebSocketServletFactory customizer = new CustomizedWebSocketServletFactory();
private WebSocketMappings mapping;
private WebSocketMappings mappings;
private WebSocketComponents components;
/**
@ -135,7 +135,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
ServletContext servletContext = getServletContext();
ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext));
components = WebSocketServerComponents.getWebSocketComponents(contextHandler.getCoreContextHandler());
mapping = new WebSocketMappings(components);
mappings = new WebSocketMappings(components);
String max = getInitParameter("idleTimeout");
if (max == null)
@ -181,6 +181,13 @@ public abstract class JettyWebSocketServlet extends HttpServlet
}
}
@Override
public void destroy()
{
mappings.clear();
super.destroy();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
@ -191,7 +198,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
Response response = httpChannel.getCoreResponse();
// Do preliminary check before proceeding to attempt an upgrade.
if (mapping.getHandshaker().isWebSocketUpgradeRequest(request))
if (mappings.getHandshaker().isWebSocketUpgradeRequest(request))
{
// provide a null default customizer the customizer will be on the negotiator in the mapping
FutureCallback callback = new FutureCallback();
@ -202,7 +209,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
request.setAttribute(WebSocketConstants.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, req);
request.setAttribute(WebSocketConstants.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, resp);
if (mapping.upgrade(request, response, callback, null))
if (mappings.upgrade(request, response, callback, null))
{
callback.block();
return;
@ -215,7 +222,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
}
}
// If we reach this point, it means we had an incoming request to upgrade
// 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())
@ -236,7 +243,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
@Override
public void addMapping(String pathSpec, JettyWebSocketCreator creator)
{
mapping.addMapping(WebSocketMappings.parsePathSpec(pathSpec), new WrappedJettyCreator(creator), getFactory(), this);
mappings.addMapping(WebSocketMappings.parsePathSpec(pathSpec), new WrappedJettyCreator(creator), getFactory(), this);
}
@Override
@ -260,7 +267,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
}
catch (Throwable t)
{
t.printStackTrace();
LOG.warn("Failed to construct new Endpoint", t);
return null;
}
};
@ -277,7 +284,7 @@ public abstract class JettyWebSocketServlet extends HttpServlet
@Override
public JettyWebSocketCreator getMapping(String pathSpec)
{
WebSocketCreator creator = mapping.getWebSocketCreator(WebSocketMappings.parsePathSpec(pathSpec));
WebSocketCreator creator = mappings.getWebSocketCreator(WebSocketMappings.parsePathSpec(pathSpec));
if (creator instanceof WrappedJettyCreator)
return ((WrappedJettyCreator)creator).getJettyWebSocketCreator();
return null;
@ -286,19 +293,12 @@ public abstract class JettyWebSocketServlet extends HttpServlet
@Override
public boolean removeMapping(String pathSpec)
{
return mapping.removeMapping(WebSocketMappings.parsePathSpec(pathSpec));
return mappings.removeMapping(WebSocketMappings.parsePathSpec(pathSpec));
}
}
private static class WrappedJettyCreator implements WebSocketCreator
private record WrappedJettyCreator(JettyWebSocketCreator creator) implements WebSocketCreator
{
private final JettyWebSocketCreator creator;
private WrappedJettyCreator(JettyWebSocketCreator creator)
{
this.creator = creator;
}
private JettyWebSocketCreator getJettyWebSocketCreator()
{
return creator;