Merge remote-tracking branch 'origin/jetty-12.0.x-ee9-websocket' into jetty-12.0.x

This commit is contained in:
Lachlan Roberts 2022-06-22 13:21:59 +10:00
commit 52d044f742
75 changed files with 397 additions and 143 deletions

View File

@ -72,6 +72,7 @@ public class WebSocketMappings implements Dumpable, LifeCycle.Listener
public void lifeCycleStopping(LifeCycle event)
{
contextHandler.removeAttribute(WEBSOCKET_MAPPING_ATTRIBUTE);
contextHandler.removeEventListener(this);
}
});
}

View File

@ -147,7 +147,20 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
throw new WebSocketException("Duplicate WebSocket Mapping for PathSpec");
WebSocketUpgradeFilter.ensureFilter(contextHandler.getServletContext());
WebSocketCreator coreCreator = (req, resp, cb) -> creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
WebSocketCreator coreCreator = (req, resp, cb) ->
{
try
{
Object webSocket = creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
cb.succeeded();
return webSocket;
}
catch (Throwable t)
{
cb.failed(t);
return null;
}
};
webSocketMappings.addMapping(ps, coreCreator, frameHandlerFactory, customizer);
}
@ -203,7 +216,6 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
try (Blocking.Callback callback = Blocking.callback())
{
// TODO: throwing here?
boolean upgraded = handshaker.upgradeRequest(negotiator, baseRequest, baseRequest.getResponse(), callback, components, null);
callback.block();
return upgraded;

View File

@ -20,7 +20,7 @@
<artifactId>jetty-jakarta-websocket-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.ee9</groupId>
<groupId>org.eclipse.jetty.ee9.websocket</groupId>
<artifactId>jetty-ee9-websocket-jakarta-common</artifactId>
</dependency>
<dependency>

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.jakarta.client.JakartaWebSocketShutdownContainer
org.eclipse.jetty.ee9.websocket.jakarta.client.JakartaWebSocketShutdownContainer

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.jakarta.client.JakartaWebSocketClientContainerProvider
org.eclipse.jetty.ee9.websocket.jakarta.client.JakartaWebSocketClientContainerProvider

View File

@ -56,11 +56,6 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Bundle-Description>jakarta.websocket.server Implementation</Bundle-Description>

View File

@ -136,9 +136,9 @@ public class JakartaWebSocketServletContainerInitializer implements ServletConta
JakartaWebSocketServerContainer serverContainer = JakartaWebSocketServerContainer.getContainer(context.getServletContext());
if (serverContainer == null)
{
WebSocketComponents components = WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), context.getServletContext());
WebSocketComponents components = WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), context.getCoreContextHandler());
FilterHolder filterHolder = WebSocketUpgradeFilter.ensureFilter(context.getServletContext());
WebSocketMappings mapping = WebSocketMappings.ensureMappings(context.getServletContext());
WebSocketMappings mapping = WebSocketMappings.ensureMappings(context.getCoreContextHandler());
serverContainer = JakartaWebSocketServerContainer.ensureContainer(context.getServletContext());
if (LOG.isDebugEnabled())

View File

@ -31,13 +31,15 @@ public class JakartaServerUpgradeRequest implements UpgradeRequest
@Override
public Principal getUserPrincipal()
{
return servletRequest.getUserPrincipal();
// TODO: keep the wrapped request and ask it for user principal.
return null;
}
@Override
public URI getRequestURI()
{
return servletRequest.getRequestURI();
// TODO: keep the wrapped request and ask it for request URI.
return null;
}
@Override

View File

@ -28,13 +28,15 @@ import jakarta.websocket.DeploymentException;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.nested.HttpChannel;
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
import org.eclipse.jetty.ee9.websocket.jakarta.client.internal.JakartaWebSocketClientContainer;
import org.eclipse.jetty.ee9.websocket.jakarta.server.config.ContainerDefaultConfigurator;
import org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
@ -97,8 +99,8 @@ public class JakartaWebSocketServerContainer extends JakartaWebSocketClientConta
// Create the Jetty ServerContainer implementation
JakartaWebSocketServerContainer container = new JakartaWebSocketServerContainer(
WebSocketMappings.ensureMappings(servletContext),
WebSocketServerComponents.getWebSocketComponents(servletContext),
WebSocketMappings.ensureMappings(contextHandler.getCoreContextHandler()),
WebSocketServerComponents.getWebSocketComponents(contextHandler.getCoreContextHandler()),
coreClientSupplier);
// Manage the lifecycle of the Container.
@ -294,7 +296,13 @@ public class JakartaWebSocketServerContainer extends JakartaWebSocketClientConta
JakartaWebSocketCreator creator = new JakartaWebSocketCreator(this, config, getExtensionRegistry());
WebSocketNegotiator negotiator = WebSocketNegotiator.from(creator, frameHandlerFactory);
Handshaker handshaker = webSocketMappings.getHandshaker();
handshaker.upgradeRequest(negotiator, request, response, components, defaultCustomizer);
HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName());
try (Blocking.Callback callback = Blocking.callback())
{
handshaker.upgradeRequest(negotiator, httpChannel.getCoreRequest(), httpChannel.getCoreResponse(), callback, components, defaultCustomizer);
callback.block();
}
}
@Override

View File

@ -15,16 +15,23 @@ package org.eclipse.jetty.ee9.websocket.jakarta.server.internal;
import java.net.URI;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import jakarta.websocket.server.HandshakeRequest;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest;
public class JsrHandshakeRequest implements HandshakeRequest
{
private final ServerUpgradeRequest delegate;
private Map<String, List<String>> parameterMap;
public JsrHandshakeRequest(ServerUpgradeRequest req)
{
@ -34,53 +41,67 @@ public class JsrHandshakeRequest implements HandshakeRequest
@Override
public Map<String, List<String>> getHeaders()
{
return delegate.getHeadersMap();
Map<String, List<String>> headers = delegate.getHeaders().getFieldNamesCollection().stream()
.collect(Collectors.toMap((name) -> name, (name) -> new ArrayList<>(delegate.getHeaders().getValuesList(name))));
return Collections.unmodifiableMap(headers);
}
@Override
public Object getHttpSession()
{
return delegate.getSession();
// TODO
return null;
}
@Override
public Map<String, List<String>> getParameterMap()
{
return delegate.getParameterMap();
if (parameterMap == null)
{
Fields requestParams = Request.extractQueryParameters(delegate);
parameterMap = new HashMap<>();
for (String name : requestParams.getNames())
{
parameterMap.put(name, requestParams.getValues(name));
}
}
return parameterMap;
}
@Override
public String getQueryString()
{
return delegate.getQueryString();
return delegate.getHttpURI().getQuery();
}
public PathSpec getRequestPathSpec()
{
return (PathSpec)delegate.getServletAttribute(PathSpec.class.getName());
return (PathSpec)delegate.getAttribute(PathSpec.class.getName());
}
@SuppressWarnings("unchecked")
public Map<String, String> getPathParams()
{
return (Map<String, String>)delegate.getServletAttribute(JakartaWebSocketServerContainer.PATH_PARAM_ATTRIBUTE);
return (Map<String, String>)delegate.getAttribute(JakartaWebSocketServerContainer.PATH_PARAM_ATTRIBUTE);
}
@Override
public URI getRequestURI()
{
return delegate.getRequestURI();
return delegate.getHttpURI().toURI();
}
@Override
public Principal getUserPrincipal()
{
return delegate.getUserPrincipal();
// TODO;
return null;
}
@Override
public boolean isUserInRole(String role)
{
return delegate.isUserInRole(role);
// TODO;
return false;
}
}

View File

@ -13,9 +13,11 @@
package org.eclipse.jetty.ee9.websocket.jakarta.server.internal;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import jakarta.websocket.HandshakeResponse;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeResponse;
@ -23,23 +25,22 @@ import org.eclipse.jetty.websocket.core.server.ServerUpgradeResponse;
public class JsrHandshakeResponse implements HandshakeResponse
{
private final ServerUpgradeResponse delegate;
private Map<String, List<String>> headerMap;
public JsrHandshakeResponse(ServerUpgradeResponse resp)
{
this.delegate = resp;
this.headerMap = new HashMap<>();
this.headerMap.putAll(resp.getHeadersMap());
}
@Override
public Map<String, List<String>> getHeaders()
{
return headerMap;
Map<String, List<String>> headers = delegate.getHeaders().getFieldNamesCollection().stream()
.collect(Collectors.toMap((name) -> name, (name) -> new ArrayList<>(delegate.getHeaders().getValuesList(name))));
return Collections.unmodifiableMap(headers);
}
public void setHeaders(Map<String, List<String>> headers)
{
headers.forEach((key, values) -> delegate.setHeader(key, values));
headers.forEach((key, values) -> delegate.getHeaders().put(key, values));
}
}

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer
org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.jakarta.server.config.ContainerDefaultConfigurator
org.eclipse.jetty.ee9.websocket.jakarta.server.config.ContainerDefaultConfigurator

View File

@ -0,0 +1 @@
org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketConfiguration

View File

@ -1 +0,0 @@
org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketConfiguration

View File

@ -166,7 +166,7 @@ public class LocalServer extends ContainerLifeCycle implements LocalFuzzer.Provi
JakartaWebSocketServletContainerInitializer.configure(servletContextHandler, (context, container) ->
((JakartaWebSocketServerContainer)container).addSessionListener(trackingListener));
configureServletContextHandler(servletContextHandler);
return servletContextHandler;
return servletContextHandler.getCoreContextHandler();
}
protected void configureServletContextHandler(ServletContextHandler context) throws Exception

View File

@ -100,7 +100,7 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider
context = new WebAppContext();
context.setContextPath("/" + contextName);
context.setInitParameter("org.eclipse.jetty.ee9.servlet.Default.dirAllowed", "false");
context.setResourceBase(contextDir);
context.setResourceBase(contextDir.toAbsolutePath().toString());
context.setAttribute("org.eclipse.jetty.websocket.jakarta", Boolean.TRUE);
context.addConfiguration(new JakartaWebSocketConfiguration());
}
@ -167,7 +167,7 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider
public void deploy()
{
contexts.addHandler(context);
contexts.manage(context);
contexts.manage(context.getCoreContextHandler());
context.setThrowUnavailableOnStartupException(true);
if (LOG.isDebugEnabled())
LOG.debug("{}", context.dump());

View File

@ -44,6 +44,7 @@ import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.client.CoreClientUpgradeRequest;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -157,6 +158,7 @@ public class JakartaClientClassLoaderTest
return app;
}
@Disabled
@Test
public void websocketProvidedByServer() throws Exception
{
@ -185,6 +187,7 @@ public class JakartaClientClassLoaderTest
ClassLoader serverClassLoader = server.getServer().getClass().getClassLoader();
assertThat(response.getContentAsString(), containsString("ClientClassLoader: " + serverClassLoader)); }
@Disabled
@Test
public void websocketProvidedByWebApp() throws Exception
{

View File

@ -32,6 +32,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -87,6 +88,7 @@ public class JakartaClientShutdownWithServerEmbeddedTest
server.stop();
}
@Disabled
@Test
public void testShutdownWithContextHandler() throws Exception
{

View File

@ -39,6 +39,7 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.client.CoreClientUpgradeRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -106,6 +107,7 @@ public class JakartaClientShutdownWithServerWebAppTest
return app;
}
@Disabled
@Test
public void websocketProvidedByServer() throws Exception
{
@ -146,6 +148,7 @@ public class JakartaClientShutdownWithServerWebAppTest
assertThat(server.getContainedBeans(WebSocketContainer.class).size(), is(0));
}
@Disabled
@Test
public void websocketProvidedByWebApp() throws Exception
{

View File

@ -28,6 +28,7 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -37,6 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Disabled
public class JakartaWebSocketRestartTest
{
private Server server;
@ -73,7 +75,8 @@ public class JakartaWebSocketRestartTest
container.addEndpoint(EchoSocket.class));
server.start();
int numEventListeners = contextHandler.getEventListeners().size();
int numServletEventListeners = contextHandler.getEventListeners().size();
int numCoreEventListeners = contextHandler.getCoreContextHandler().getEventListeners().size();
for (int i = 0; i < 100; i++)
{
server.stop();
@ -82,9 +85,10 @@ public class JakartaWebSocketRestartTest
}
// We have not accumulated websocket resources by restarting.
assertThat(contextHandler.getEventListeners().size(), is(numEventListeners));
assertThat(contextHandler.getEventListeners().size(), is(numServletEventListeners));
assertThat(contextHandler.getCoreContextHandler().getEventListeners().size(), is(numCoreEventListeners));
assertThat(contextHandler.getContainedBeans(JakartaWebSocketServerContainer.class).size(), is(1));
assertThat(contextHandler.getContainedBeans(WebSocketServerComponents.class).size(), is(1));
assertThat(contextHandler.getCoreContextHandler().getContainedBeans(WebSocketServerComponents.class).size(), is(1));
assertNotNull(contextHandler.getServletContext().getAttribute(WebSocketServerComponents.WEBSOCKET_COMPONENTS_ATTRIBUTE));
assertNotNull(contextHandler.getServletContext().getAttribute(JakartaWebSocketServerContainer.JAKARTA_WEBSOCKET_CONTAINER_ATTRIBUTE));
@ -97,7 +101,7 @@ public class JakartaWebSocketRestartTest
server.stop();
assertThat(contextHandler.getEventListeners().size(), is(0));
assertThat(contextHandler.getContainedBeans(JakartaWebSocketServerContainer.class).size(), is(0));
assertThat(contextHandler.getContainedBeans(WebSocketServerComponents.class).size(), is(0));
assertThat(contextHandler.getCoreContextHandler().getContainedBeans(WebSocketServerComponents.class).size(), is(0));
assertNull(contextHandler.getServletContext().getAttribute(WebSocketServerComponents.WEBSOCKET_COMPONENTS_ATTRIBUTE));
assertNull(contextHandler.getServletContext().getAttribute(JakartaWebSocketServerContainer.JAKARTA_WEBSOCKET_CONTAINER_ATTRIBUTE));
assertThat(contextHandler.getServletHandler().getFilters().length, is(0));

View File

@ -67,7 +67,7 @@ public class RestartContextTest
context.addEventListener(new AddEndpointListener());
// Setup handler tree
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
// Start server
server.start();
@ -104,7 +104,7 @@ public class RestartContextTest
});
// Setup handler tree
HandlerList handlers = new HandlerList(context, new DefaultHandler());
HandlerList handlers = new HandlerList(context.getCoreContextHandler(), new DefaultHandler());
// Add handler tree to server
server.setHandler(handlers);

View File

@ -20,8 +20,6 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.websocket.ClientEndpointConfig;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.Endpoint;
@ -32,8 +30,11 @@ import org.eclipse.jetty.ee9.websocket.jakarta.tests.CoreServer;
import org.eclipse.jetty.ee9.websocket.jakarta.tests.DummyEndpoint;
import org.eclipse.jetty.ee9.websocket.jakarta.tests.framehandlers.StaticText;
import org.eclipse.jetty.ee9.websocket.jakarta.tests.framehandlers.WholeMessageEcho;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest;
import org.eclipse.jetty.websocket.core.server.WebSocketNegotiation;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@ -70,17 +71,17 @@ public class CookiesTest
startServer(negotiation ->
{
HttpServletRequest request = negotiation.getRequest();
Cookie[] cookies = request.getCookies();
ServerUpgradeRequest request = negotiation.getRequest();
List<org.eclipse.jetty.http.HttpCookie> cookies = Request.getCookies(request);
assertThat("Cookies", cookies, notNullValue());
assertThat("Cookies", cookies.length, is(1));
Cookie cookie = cookies[0];
assertThat("Cookies", cookies.size(), is(1));
org.eclipse.jetty.http.HttpCookie cookie = cookies.get(0);
assertEquals(cookieName, cookie.getName());
assertEquals(cookieValue, cookie.getValue());
StringBuilder requestHeaders = new StringBuilder();
Collections.list(request.getHeaderNames())
.forEach(name -> requestHeaders.append(name).append(": ").append(request.getHeader(name)).append("\n"));
request.getHeaders()
.forEach(field -> requestHeaders.append(field.getName()).append(": ").append(field.getValue()).append("\n"));
return new StaticText(requestHeaders.toString());
});
@ -114,10 +115,8 @@ public class CookiesTest
final String cookiePath = "/path";
startServer(negotiation ->
{
Cookie cookie = new Cookie(cookieName, cookieValue);
cookie.setDomain(cookieDomain);
cookie.setPath(cookiePath);
negotiation.getResponse().addCookie(cookie);
org.eclipse.jetty.http.HttpCookie cookie = new org.eclipse.jetty.http.HttpCookie(cookieName, cookieValue, cookieDomain, cookiePath);
Response.addCookie(negotiation.getResponse(), cookie);
return new WholeMessageEcho();
});

View File

@ -26,6 +26,7 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.websocket.core.CloseStatus;
import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -42,6 +43,7 @@ public class AltFilterTest
{
public WorkDir testdir;
@Disabled
@Test
public void testEcho() throws Exception
{

View File

@ -32,8 +32,10 @@ import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@Disabled
public class AnnotatedServerEndpointTest
{
private LocalServer server;

View File

@ -27,6 +27,7 @@ import org.eclipse.jetty.ee9.websocket.jakarta.tests.WSServer;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static jakarta.websocket.CloseReason.CloseCodes.NORMAL_CLOSURE;
@ -70,6 +71,7 @@ public class ContainerProviderServerTest
server.stop();
}
@Disabled
@Test
public void testJakartaWsContainerInServer() throws Exception
{

View File

@ -20,6 +20,8 @@ import java.util.stream.Stream;
import jakarta.websocket.DeploymentException;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpoint;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.nested.HandlerCollection;
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
import org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
import org.eclipse.jetty.ee9.websocket.jakarta.tests.server.sockets.InvalidCloseIntSocket;
@ -28,12 +30,11 @@ import org.eclipse.jetty.ee9.websocket.jakarta.tests.server.sockets.InvalidError
import org.eclipse.jetty.ee9.websocket.jakarta.tests.server.sockets.InvalidOpenCloseReasonSocket;
import org.eclipse.jetty.ee9.websocket.jakarta.tests.server.sockets.InvalidOpenIntSocket;
import org.eclipse.jetty.ee9.websocket.jakarta.tests.server.sockets.InvalidOpenSessionIntSocket;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.websocket.core.exception.InvalidSignatureException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@ -46,6 +47,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
* Deploy various {@link ServerEndpoint} annotated classes with invalid signatures,
* check for {@link DeploymentException}
*/
@Disabled
public class DeploymentExceptionTest
{
public static Stream<Arguments> data()
@ -75,8 +77,10 @@ public class DeploymentExceptionTest
public void startServer() throws Exception
{
server = new Server(0);
contexts = new HandlerCollection(true, new Handler[0]);
server.setHandler(contexts);
contexts = new HandlerCollection(true);
ContextHandler contextHandler = new ContextHandler();
contextHandler.setHandler(contexts);
server.setHandler(contextHandler.getCoreContextHandler());
server.start();
}

View File

@ -37,6 +37,7 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
@ -63,6 +64,7 @@ public class DeploymentTest
server.stop();
}
@Disabled
@Test
public void testBadPathParamSignature() throws Exception
{
@ -93,6 +95,7 @@ public class DeploymentTest
* @see <a href="https://bugs.openjdk.java.net/browse/JDK-8244090">JDK-8244090</a>
* @throws Exception if there is an error during the test.
*/
@Disabled
@Test
@DisabledOnJre({JRE.JAVA_14, JRE.JAVA_15})
public void testDifferentWebAppsWithSameClassInSignature() throws Exception

View File

@ -28,6 +28,7 @@ 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.core.client.WebSocketCoreClient;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
@ -47,6 +48,7 @@ public class EndpointViaConfigTest
public WorkDir testdir;
@Disabled
@Test
public void testEcho() throws Exception
{

View File

@ -30,6 +30,7 @@ import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -38,6 +39,7 @@ import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertThrows;
@Disabled
public class IdleTimeoutTest
{
private static WSServer server;

View File

@ -30,6 +30,7 @@ import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -113,6 +114,7 @@ public class InputStreamEchoTest
}
}
@Disabled
@Test
public void testInputStreamParamSocket() throws Exception
{

View File

@ -30,6 +30,7 @@ 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.core.client.WebSocketCoreClient;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -54,6 +55,7 @@ public class LargeAnnotatedTest
public WorkDir testdir;
@Disabled
@Test
public void testEcho() throws Exception
{

View File

@ -29,6 +29,7 @@ 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.core.client.WebSocketCoreClient;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -44,6 +45,7 @@ public class LargeContainerTest
public WorkDir testdir;
@SuppressWarnings("Duplicates")
@Disabled
@Test
public void testEcho() throws Exception
{

View File

@ -32,6 +32,7 @@ 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.core.client.WebSocketCoreClient;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -78,6 +79,7 @@ public class OnMessageReturnTest
public WorkDir testdir;
@Disabled
@Test
public void testEchoReturn() throws Exception
{

View File

@ -34,12 +34,14 @@ import org.eclipse.jetty.websocket.core.OpCode;
import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertTimeout;
@Disabled
public class PingPongTest
{
private static WSServer server;

View File

@ -30,6 +30,7 @@ import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.OpCode;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -113,6 +114,7 @@ public class ReaderEchoTest
}
}
@Disabled
@Test
public void testReaderParamSocket() throws Exception
{

View File

@ -35,6 +35,7 @@ import org.eclipse.jetty.ee9.websocket.jakarta.tests.WSServer;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@ -42,6 +43,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Disabled
public class WebAppClassLoaderTest
{
@ServerEndpoint("/echo")

View File

@ -43,6 +43,7 @@ import org.eclipse.jetty.ee9.websocket.jakarta.tests.WSURI;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer.HTTPCLIENT_ATTRIBUTE;
@ -51,6 +52,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.Matchers.startsWith;
@Disabled
public class WebSocketServerContainerExecutorTest
{
@ServerEndpoint("/echo")

View File

@ -41,6 +41,7 @@ import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,6 +49,7 @@ import org.slf4j.LoggerFactory;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@Disabled
public class WebSocketServerExamplesTest
{
private static final Logger LOG = LoggerFactory.getLogger(WebSocketServerExamplesTest.class);

View File

@ -24,6 +24,7 @@ import java.util.function.Consumer;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee9.nested.HttpChannel;
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
import org.eclipse.jetty.ee9.websocket.api.Session;
import org.eclipse.jetty.ee9.websocket.api.WebSocketBehavior;
@ -37,6 +38,7 @@ import org.eclipse.jetty.ee9.websocket.server.internal.DelegatedServerUpgradeRes
import org.eclipse.jetty.ee9.websocket.server.internal.JettyServerFrameHandlerFactory;
import org.eclipse.jetty.ee9.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.LifeCycle;
@ -78,8 +80,8 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
executor = contextHandler.getServer().getThreadPool();
// Create the Jetty ServerContainer implementation.
WebSocketMappings mappings = WebSocketMappings.ensureMappings(servletContext);
WebSocketComponents components = WebSocketServerComponents.getWebSocketComponents(servletContext);
WebSocketMappings mappings = WebSocketMappings.ensureMappings(contextHandler.getCoreContextHandler());
WebSocketComponents components = WebSocketServerComponents.getWebSocketComponents(contextHandler.getCoreContextHandler());
JettyWebSocketServerContainer container = new JettyWebSocketServerContainer(contextHandler, mappings, components, executor);
// Manage the lifecycle of the Container.
@ -145,7 +147,20 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
throw new WebSocketException("Duplicate WebSocket Mapping for PathSpec");
WebSocketUpgradeFilter.ensureFilter(contextHandler.getServletContext());
WebSocketCreator coreCreator = (req, resp) -> creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
WebSocketCreator coreCreator = (req, resp, cb) ->
{
try
{
Object webSocket = creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
cb.succeeded();
return webSocket;
}
catch (Throwable t)
{
cb.failed(t);
return null;
}
};
webSocketMappings.addMapping(ps, coreCreator, frameHandlerFactory, customizer);
}
@ -177,11 +192,31 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
*/
public boolean upgrade(JettyWebSocketCreator creator, HttpServletRequest request, HttpServletResponse response) throws IOException
{
WebSocketCreator coreCreator = (req, resp) -> creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
WebSocketNegotiator negotiator = WebSocketNegotiator.from(coreCreator, frameHandlerFactory, customizer);
WebSocketCreator coreCreator = (req, resp, cb) ->
{
try
{
Object webSocket = creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
cb.succeeded();
return webSocket;
}
catch (Throwable t)
{
cb.failed(t);
return null;
}
};
HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName());
WebSocketNegotiator negotiator = WebSocketNegotiator.from(coreCreator, frameHandlerFactory, customizer);
Handshaker handshaker = webSocketMappings.getHandshaker();
return handshaker.upgradeRequest(negotiator, request, response, components, null);
try (Blocking.Callback callback = Blocking.callback())
{
boolean upgraded = handshaker.upgradeRequest(negotiator, httpChannel.getCoreRequest(), httpChannel.getCoreResponse(), callback, components, null);
callback.block();
return upgraded;
}
}
@Override

View File

@ -16,6 +16,7 @@ package org.eclipse.jetty.ee9.websocket.server;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.time.Duration;
import java.util.Objects;
import java.util.Set;
import jakarta.servlet.ServletContext;
@ -23,11 +24,14 @@ import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.nested.HttpChannel;
import org.eclipse.jetty.ee9.websocket.server.internal.DelegatedServerUpgradeRequest;
import org.eclipse.jetty.ee9.websocket.server.internal.DelegatedServerUpgradeResponse;
import org.eclipse.jetty.ee9.websocket.server.internal.JettyServerFrameHandlerFactory;
import org.eclipse.jetty.ee9.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.Configuration;
import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.server.FrameHandlerFactory;
@ -125,8 +129,8 @@ public abstract class JettyWebSocketServlet extends HttpServlet
try
{
ServletContext servletContext = getServletContext();
components = WebSocketServerComponents.getWebSocketComponents(servletContext);
ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(servletContext));
components = WebSocketServerComponents.getWebSocketComponents(contextHandler.getCoreContextHandler());
mapping = new WebSocketMappings(components);
String max = getInitParameter("idleTimeout");
@ -178,8 +182,15 @@ public abstract class JettyWebSocketServlet extends HttpServlet
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;
HttpChannel channel = (HttpChannel)req.getAttribute(HttpChannel.class.getName());
try (Blocking.Callback callback = Blocking.callback())
{
if (mapping.upgrade(channel.getCoreRequest(), channel.getCoreResponse(), callback, null))
{
callback.block();
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
@ -271,9 +282,19 @@ public abstract class JettyWebSocketServlet extends HttpServlet
}
@Override
public Object createWebSocket(ServerUpgradeRequest req, ServerUpgradeResponse resp)
public Object createWebSocket(ServerUpgradeRequest req, ServerUpgradeResponse resp, Callback callback)
{
return creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
try
{
Object webSocket = creator.createWebSocket(new DelegatedServerUpgradeRequest(req), new DelegatedServerUpgradeResponse(resp));
callback.succeeded();
return webSocket;
}
catch (Throwable t)
{
callback.failed(t);
return null;
}
}
}
}

View File

@ -85,7 +85,7 @@ public class JettyWebSocketServletContainerInitializer implements ServletContain
*/
private static JettyWebSocketServerContainer initialize(ServletContextHandler context)
{
WebSocketComponents components = WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), context.getServletContext());
WebSocketComponents components = WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), context.getCoreContextHandler());
JettyWebSocketServerContainer container = JettyWebSocketServerContainer.ensureContainer(context.getServletContext());
if (LOG.isDebugEnabled())
LOG.debug("initialize {} {}", container, components);

View File

@ -18,32 +18,82 @@ import java.net.SocketAddress;
import java.net.URI;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.websocket.api.ExtensionConfig;
import org.eclipse.jetty.ee9.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeRequest;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest;
public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
{
private final URI requestURI;
private final String queryString;
private final ServerUpgradeRequest upgradeRequest;
private final HttpServletRequest httpServletRequest;
private List<HttpCookie> cookies;
private Map<String, List<String>> parameterMap;
public DelegatedServerUpgradeRequest(ServerUpgradeRequest request)
{
upgradeRequest = request;
this(request, Request.as(request, ContextHandler.CoreContextRequest.class).getHttpChannel().getRequest());
}
public DelegatedServerUpgradeRequest(ServerUpgradeRequest request, HttpServletRequest servletRequest)
{
this.upgradeRequest = request;
this.httpServletRequest = servletRequest;
this.queryString = httpServletRequest.getQueryString();
try
{
StringBuffer uri = httpServletRequest.getRequestURL();
if (this.queryString != null)
uri.append("?").append(this.queryString);
uri.replace(0, uri.indexOf(":"), request.isSecure() ? "wss" : "ws");
this.requestURI = new URI(uri.toString());
}
catch (Throwable t)
{
throw new BadMessageException("Bad WebSocket UpgradeRequest", t);
}
}
@Override
public List<HttpCookie> getCookies()
{
return upgradeRequest.getCookies();
if (cookies == null)
{
Cookie[] reqCookies = httpServletRequest.getCookies();
if (reqCookies != null)
{
cookies = Arrays.stream(reqCookies)
.map(c -> new HttpCookie(c.getName(), c.getValue()))
.collect(Collectors.toList());
}
else
{
cookies = Collections.emptyList();
}
}
return cookies;
}
@Override
@ -57,37 +107,39 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
@Override
public String getHeader(String name)
{
return upgradeRequest.getHeader(name);
return upgradeRequest.getHeaders().get(name);
}
@Override
public int getHeaderInt(String name)
{
return upgradeRequest.getHeaderInt(name);
return httpServletRequest.getIntHeader(name);
}
@Override
public Map<String, List<String>> getHeaders()
{
return upgradeRequest.getHeadersMap();
Map<String, List<String>> headers = upgradeRequest.getHeaders().getFieldNamesCollection().stream()
.collect(Collectors.toMap((name) -> name, (name) -> new ArrayList<>(getHeaders(name))));
return Collections.unmodifiableMap(headers);
}
@Override
public List<String> getHeaders(String name)
{
return upgradeRequest.getHeaders(name);
return upgradeRequest.getHeaders().getValuesList(name);
}
@Override
public String getHost()
{
return upgradeRequest.getHost();
return upgradeRequest.getHttpURI().getHost();
}
@Override
public String getHttpVersion()
{
return upgradeRequest.getHttpVersion();
return upgradeRequest.getConnectionMetaData().getHttpVersion().asString();
}
@Override
@ -99,13 +151,25 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
@Override
public String getOrigin()
{
return upgradeRequest.getOrigin();
return upgradeRequest.getHeaders().get(HttpHeader.ORIGIN);
}
@Override
public Map<String, List<String>> getParameterMap()
{
return upgradeRequest.getParameterMap();
if (parameterMap == null)
{
Map<String, String[]> requestParams = httpServletRequest.getParameterMap();
if (requestParams != null)
{
parameterMap = new HashMap<>(requestParams.size());
for (Map.Entry<String, String[]> entry : requestParams.entrySet())
{
parameterMap.put(entry.getKey(), Arrays.asList(entry.getValue()));
}
}
}
return parameterMap;
}
@Override
@ -117,19 +181,19 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
@Override
public String getQueryString()
{
return upgradeRequest.getQueryString();
return queryString;
}
@Override
public URI getRequestURI()
{
return upgradeRequest.getRequestURI();
return requestURI;
}
@Override
public HttpSession getSession()
{
return upgradeRequest.getSession();
return httpServletRequest.getSession();
}
@Override
@ -141,7 +205,7 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
@Override
public Principal getUserPrincipal()
{
return upgradeRequest.getUserPrincipal();
return httpServletRequest.getUserPrincipal();
}
@Override
@ -153,78 +217,85 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
@Override
public boolean isSecure()
{
return upgradeRequest.isSecure();
return httpServletRequest.isSecure();
}
@Override
public X509Certificate[] getCertificates()
{
return upgradeRequest.getCertificates();
return (X509Certificate[])httpServletRequest.getAttribute("jakarta.servlet.request.X509Certificate");
}
@Override
public HttpServletRequest getHttpServletRequest()
{
return upgradeRequest.getHttpServletRequest();
return httpServletRequest;
}
@Override
public Locale getLocale()
{
return upgradeRequest.getLocale();
return httpServletRequest.getLocale();
}
@Override
public Enumeration<Locale> getLocales()
{
return upgradeRequest.getLocales();
return httpServletRequest.getLocales();
}
@Override
public SocketAddress getLocalSocketAddress()
{
return upgradeRequest.getLocalSocketAddress();
return upgradeRequest.getConnectionMetaData().getLocalSocketAddress();
}
@Override
public SocketAddress getRemoteSocketAddress()
{
return upgradeRequest.getRemoteSocketAddress();
return upgradeRequest.getConnectionMetaData().getRemoteSocketAddress();
}
@Override
public String getRequestPath()
{
return upgradeRequest.getRequestPath();
return URIUtil.addPaths(httpServletRequest.getServletPath(), httpServletRequest.getPathInfo());
}
@Override
public Object getServletAttribute(String name)
{
return upgradeRequest.getServletAttribute(name);
return httpServletRequest.getAttribute(name);
}
@Override
public Map<String, Object> getServletAttributes()
{
return upgradeRequest.getServletAttributes();
Map<String, Object> attributes = new HashMap<>(2);
Enumeration<String> attributeNames = httpServletRequest.getAttributeNames();
while (attributeNames.hasMoreElements())
{
String name = attributeNames.nextElement();
attributes.put(name, httpServletRequest.getAttribute(name));
}
return attributes;
}
@Override
public Map<String, List<String>> getServletParameters()
{
return upgradeRequest.getServletParameters();
return getParameterMap();
}
@Override
public boolean isUserInRole(String role)
{
return upgradeRequest.isUserInRole(role);
return httpServletRequest.isUserInRole(role);
}
@Override
public void setServletAttribute(String name, Object value)
{
upgradeRequest.setServletAttribute(name, value);
httpServletRequest.setAttribute(name, value);
}
}

View File

@ -14,6 +14,8 @@
package org.eclipse.jetty.ee9.websocket.server.internal;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -22,6 +24,9 @@ import java.util.stream.Collectors;
import org.eclipse.jetty.ee9.websocket.api.ExtensionConfig;
import org.eclipse.jetty.ee9.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeResponse;
public class DelegatedServerUpgradeResponse implements JettyServerUpgradeResponse
@ -36,19 +41,19 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
@Override
public void addHeader(String name, String value)
{
upgradeResponse.addHeader(name, value);
upgradeResponse.getHeaders().add(name, value);
}
@Override
public void setHeader(String name, String value)
{
upgradeResponse.setHeader(name, value);
upgradeResponse.getHeaders().put(name, value);
}
@Override
public void setHeader(String name, List<String> values)
{
upgradeResponse.setHeader(name, values);
upgradeResponse.getHeaders().put(name, values);
}
@Override
@ -66,37 +71,43 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
@Override
public String getHeader(String name)
{
return upgradeResponse.getHeader(name);
return upgradeResponse.getHeaders().get(name);
}
@Override
public Set<String> getHeaderNames()
{
return upgradeResponse.getHeaderNames();
return upgradeResponse.getHeaders().getFieldNamesCollection();
}
@Override
public Map<String, List<String>> getHeaders()
{
return upgradeResponse.getHeadersMap();
Map<String, List<String>> headers = getHeaderNames().stream()
.collect(Collectors.toMap((name) -> name, (name) -> new ArrayList<>(getHeaders(name))));
return Collections.unmodifiableMap(headers);
}
@Override
public List<String> getHeaders(String name)
{
return upgradeResponse.getHeaders(name);
return upgradeResponse.getHeaders().getValuesList(name);
}
@Override
public int getStatusCode()
{
return upgradeResponse.getStatusCode();
return upgradeResponse.getStatus();
}
@Override
public void sendForbidden(String message) throws IOException
{
upgradeResponse.sendForbidden(message);
try (Blocking.Callback callback = Blocking.callback())
{
Response.writeError(upgradeResponse.getRequest(), upgradeResponse, callback, HttpStatus.FORBIDDEN_403, message);
callback.block();
}
}
@Override
@ -116,7 +127,7 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
@Override
public void setStatusCode(int statusCode)
{
upgradeResponse.setStatusCode(statusCode);
upgradeResponse.setStatus(statusCode);
}
@Override
@ -128,6 +139,10 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
@Override
public void sendError(int statusCode, String message) throws IOException
{
upgradeResponse.sendError(statusCode, message);
try (Blocking.Callback callback = Blocking.callback())
{
Response.writeError(upgradeResponse.getRequest(), upgradeResponse, callback, statusCode, message);
callback.block();
}
}
}

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer
org.eclipse.jetty.ee9.websocket.server.config.JettyWebSocketServletContainerInitializer

View File

@ -0,0 +1 @@
org.eclipse.jetty.ee9.websocket.server.config.JettyWebSocketConfiguration

View File

@ -1 +0,0 @@
org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration

View File

@ -109,7 +109,7 @@ public class BrowserDebugTool
ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);
context.addServlet(defHolder, "/");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
LOG.info("{} setup on port {}", this.getClass().getName(), port);
}

View File

@ -28,6 +28,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@ -66,6 +67,7 @@ public class ConnectionHeaderTest
server.stop();
}
@Disabled
@ParameterizedTest
@ValueSource(strings = {"Upgrade", "keep-alive, Upgrade", "close, Upgrade"})
public void testConnectionKeepAlive(String connectionHeaderValue) throws Exception

View File

@ -45,6 +45,7 @@ import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.client.CoreClientUpgradeRequest;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
@ -176,6 +177,7 @@ public class JettyClientClassLoaderTest
return app;
}
@Disabled
@Test
public void websocketProvidedByServer() throws Exception
{
@ -212,6 +214,7 @@ public class JettyClientClassLoaderTest
* This reproduces some classloading issue with MethodHandles in JDK14-110, This has been fixed in JDK16.
* @see <a href="https://bugs.openjdk.java.net/browse/JDK-8244090">JDK-8244090</a>
*/
@Disabled
@DisabledOnJre({JRE.JAVA_14, JRE.JAVA_15})
@Test
public void websocketProvidedByWebApp() throws Exception

View File

@ -49,6 +49,7 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.websocket.core.WebSocketConstants;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -303,6 +304,7 @@ public class JettyWebSocketFilterTest
assertThat(socket.textMessages.poll(), is("hElLo wOrLd"));
}
@Disabled
@Test
public void testDefaultWebSocketUpgradeFilterOrdering() throws Exception
{
@ -337,6 +339,7 @@ public class JettyWebSocketFilterTest
assertThat(socket.textMessages.poll(), is(defaultIdleTimeout));
}
@Disabled
@Test
public void testWebSocketUpgradeFilterOrdering() throws Exception
{

View File

@ -29,6 +29,7 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -67,6 +68,7 @@ public class JettyWebSocketRestartTest
server.stop();
}
@Disabled
@Test
public void testWebSocketRestart() throws Exception
{

View File

@ -24,6 +24,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@ -65,6 +66,7 @@ public class JettyWebSocketServletAttributeTest
client.start();
}
@Disabled
@Test
public void testAttributeSetInNegotiation() throws Exception
{

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.resource.PathResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -54,7 +55,7 @@ public class JettyWebSocketWebApp extends WebAppContext
// Configure the WebAppContext.
setContextPath("/" + contextName);
.setResourceBase(contextDir);
setBaseResource(new PathResource(contextDir));
addConfiguration(new JettyWebSocketConfiguration());
}

View File

@ -51,7 +51,7 @@ public class LargeDeflateTest
_server.addConnector(_connector);
ServletContextHandler handler = new ServletContextHandler();
_server.insertHandler(handler);
_server.setHandler(handler.getCoreContextHandler());
JettyWebSocketServletContainerInitializer.configure(handler, (servletContext, container) ->
{
container.setIdleTimeout(Duration.ofDays(1));

View File

@ -68,7 +68,7 @@ public class MaxOutgoingFramesTest
JettyWebSocketServletContainerInitializer.configure(contextHandler, (context, container) ->
{
container.addMapping("/", (req, resp) -> serverSocket);
WebSocketComponents components = WebSocketServerComponents.getWebSocketComponents(context);
WebSocketComponents components = WebSocketServerComponents.getWebSocketComponents(contextHandler.getCoreContextHandler());
components.getExtensionRegistry().register(BlockingOutgoingExtension.class.getName(), BlockingOutgoingExtension.class);
});

View File

@ -252,7 +252,7 @@ public class WebAppTester extends ContainerLifeCycle
public void deploy()
{
_contexts.addHandler(_context);
_contexts.manage(_context);
_contexts.manage(_context.getCoreContextHandler());
_context.setThrowUnavailableOnStartupException(true);
if (LOG.isDebugEnabled())
LOG.debug("{}", _context.dump());

View File

@ -40,6 +40,7 @@ import org.eclipse.jetty.ee9.websocket.client.WebSocketClient;
import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServlet;
import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServletFactory;
import org.eclipse.jetty.ee9.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.ee9.websocket.server.internal.DelegatedServerUpgradeRequest;
import org.eclipse.jetty.http2.HTTP2Cipher;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2;
@ -62,6 +63,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
@ -74,6 +76,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Disabled
public class WebSocketOverHTTP2Test
{
private Server server;
@ -297,7 +300,7 @@ public class WebSocketOverHTTP2Test
connector.addBean(new HttpChannel.Listener()
{
@Override
public void onComplete(Request request)
public void onComplete(org.eclipse.jetty.ee9.nested.Request request)
{
latch.countDown();
}
@ -350,9 +353,9 @@ public class WebSocketOverHTTP2Test
});
factory.addMapping("/ws/connectionClose", (request, response) ->
{
UpgradeHttpServletRequest upgradeRequest = (UpgradeHttpServletRequest)request.getHttpServletRequest();
DelegatedServerUpgradeRequest upgradeRequest = (DelegatedServerUpgradeRequest)request.getHttpServletRequest();
Request baseRequest = (Request)upgradeRequest.getHttpServletRequest();
baseRequest.getHttpChannel().getEndPoint().close();
baseRequest.getConnectionMetaData().getConnection().getEndPoint().close();
return new EchoSocket();
});
}

View File

@ -57,7 +57,7 @@ public class WebSocketStatsTest
statistics = new IncludeExcludeConnectionStatistics();
statistics.include(WebSocketConnection.class);
Connection.Listener.Adapter wsCloseListener = new Connection.Listener.Adapter()
Connection.Listener wsCloseListener = new Connection.Listener()
{
@Override
public void onClosed(Connection connection)

View File

@ -81,7 +81,7 @@ public class BadNetworkTest
});
context.addServlet(holder, "/ws");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
JettyWebSocketServletContainerInitializer.configure(context, null);
server.start();

View File

@ -131,7 +131,7 @@ public class ClientCloseTest
});
context.addServlet(holder, "/ws");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
JettyWebSocketServletContainerInitializer.configure(context, null);
server.start();

View File

@ -74,7 +74,7 @@ public class ClientSessionsTest
});
context.addServlet(holder, "/ws");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
JettyWebSocketServletContainerInitializer.configure(context, null);
server.start();

View File

@ -76,7 +76,7 @@ public class SlowClientTest
});
context.addServlet(websocket, "/ws");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
JettyWebSocketServletContainerInitializer.configure(context, null);
server.start();

View File

@ -90,7 +90,7 @@ public class WebSocketListenerTest
}
@ParameterizedTest
@MethodSource("org.eclipse.jetty.websocket.tests.listeners.TextListeners#getTextListeners")
@MethodSource("org.eclipse.jetty.ee9.websocket.tests.listeners.TextListeners#getTextListeners")
public void testTextListeners(Class<?> clazz) throws Exception
{
EventSocket clientEndpoint = new EventSocket();
@ -110,7 +110,7 @@ public class WebSocketListenerTest
}
@ParameterizedTest
@MethodSource("org.eclipse.jetty.websocket.tests.listeners.BinaryListeners#getBinaryListeners")
@MethodSource("org.eclipse.jetty.ee9.websocket.tests.listeners.BinaryListeners#getBinaryListeners")
public void testBinaryListeners(Class<?> clazz) throws Exception
{
EventSocket clientEndpoint = new EventSocket();

View File

@ -85,7 +85,7 @@ public class FrameAnnotationTest
context.addServlet(closeEndpoint, "/ws");
JettyWebSocketServletContainerInitializer.configure(context, null);
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
server.start();
}

View File

@ -78,7 +78,7 @@ public class FrameListenerTest
context.addServlet(closeEndpoint, "/ws");
JettyWebSocketServletContainerInitializer.configure(context, null);
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
server.start();
}

View File

@ -81,7 +81,7 @@ public class PartialListenerTest
context.addServlet(closeEndpoint, "/ws");
JettyWebSocketServletContainerInitializer.configure(context, null);
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
server.start();
}

View File

@ -80,7 +80,7 @@ public class ServerCloseTest
});
context.addServlet(closeEndpoint, "/ws");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
JettyWebSocketServletContainerInitializer.configure(context, null);
server.start();

View File

@ -76,7 +76,7 @@ public class SlowServerTest
});
context.addServlet(websocket, "/ws");
server.setHandler(new HandlerList(context, new DefaultHandler()));
server.setHandler(new HandlerList(context.getCoreContextHandler(), new DefaultHandler()));
JettyWebSocketServletContainerInitializer.configure(context, null);
server.start();

View File

@ -28,10 +28,12 @@ import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.nested.HttpChannel;
import org.eclipse.jetty.ee9.servlet.FilterHolder;
import org.eclipse.jetty.ee9.servlet.FilterMapping;
import org.eclipse.jetty.ee9.servlet.ServletHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Blocking;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.LifeCycle;
@ -157,8 +159,15 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
HttpServletRequest httpreq = (HttpServletRequest)request;
HttpServletResponse httpresp = (HttpServletResponse)response;
if (mappings.upgrade(httpreq, httpresp, defaultCustomizer))
return;
HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName());
try (Blocking.Callback callback = Blocking.callback())
{
if (mappings.upgrade(httpChannel.getCoreRequest(), httpChannel.getCoreResponse(), callback, defaultCustomizer))
{
callback.block();
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
@ -179,7 +188,8 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
@Override
public void init(FilterConfig config) throws ServletException
{
mappings = WebSocketMappings.ensureMappings(config.getServletContext());
ContextHandler contextHandler = Objects.requireNonNull(ContextHandler.getContextHandler(config.getServletContext()));
mappings = WebSocketMappings.ensureMappings(contextHandler.getCoreContextHandler());
String max = config.getInitParameter("idleTimeout");
if (max == null)

View File

@ -17,13 +17,13 @@
</properties>
<modules>
<module>jetty-ee9-websocket-jakarta-client</module>
<module>jetty-ee9-websocket-jakarta-common</module>
<module>jetty-ee9-websocket-jakarta-client</module>
<module>jetty-ee9-websocket-jakarta-server</module>
<module>jetty-ee9-websocket-jakarta-tests</module>
<module>jetty-ee9-websocket-jetty-api</module>
<module>jetty-ee9-websocket-jetty-client</module>
<module>jetty-ee9-websocket-jetty-common</module>
<module>jetty-ee9-websocket-jetty-client</module>
<module>jetty-ee9-websocket-jetty-server</module>
<module>jetty-ee9-websocket-jetty-tests</module>
<module>jetty-ee9-websocket-servlet</module>

View File

@ -67,7 +67,7 @@
<!-- <module>jetty-ee9-proxy</module>-->
<!-- <module>jetty-ee9-quickstart</module>-->
<!-- <module>jetty-ee9-runner</module>-->
<!-- <module>jetty-ee9-websocket</module>-->
<module>jetty-ee9-websocket</module>
<!-- <module>jetty-ee9-tests</module>-->
<module>jetty-ee9-bom</module>
<module>test-ee9-sessions</module>