From 253eeb92b09b5cbaa65436bbd3006a056b6f104c Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 22 May 2024 11:38:13 +1000 Subject: [PATCH 1/2] add test for HttpSession.Accessor with WebSocket Signed-off-by: Lachlan Roberts --- .../ee11/websocket/tests/HttpSessionTest.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java diff --git a/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java b/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java new file mode 100644 index 000000000000..43c3d960fb17 --- /dev/null +++ b/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java @@ -0,0 +1,118 @@ +// +// ======================================================================== +// 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.ee11.websocket.tests; + +import java.net.URI; +import java.util.concurrent.TimeUnit; + +import jakarta.servlet.http.HttpSession; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.websocket.api.Callback; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketOpen; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.client.WebSocketClient; +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.equalTo; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class HttpSessionTest +{ + private Server _server; + private ServerConnector _connector; + private WebSocketClient _client; + + @WebSocket + public static class HttpSessionEndpoint + { + private final HttpSession.Accessor accessor; + + public HttpSessionEndpoint(HttpSession.Accessor accessor) + { + this.accessor = accessor; + } + + @OnWebSocketOpen + public void onOpen(Session session) + { + accessor.access(httpSession -> httpSession.setAttribute("session", "setByOnOpen")); + } + + @OnWebSocketMessage + public void onMessage(Session session, String message) + { + accessor.access(httpSession -> + { + String value = (String)httpSession.getAttribute("session"); + session.sendText(value, Callback.NOOP); + }); + } + } + + @BeforeEach + public void before() throws Exception + { + _server = new Server(); + _connector = new ServerConnector(_server); + _server.addConnector(_connector); + + ServletContextHandler contextHandler = new ServletContextHandler("/", true, false); + JettyWebSocketServletContainerInitializer.configure(contextHandler, ((servletContext, serverContainer) -> + { + serverContainer.addMapping("/", (req, resp) -> + { + HttpSession.Accessor accessor = req.getHttpServletRequest().getSession(true).getAccessor(); + return new HttpSessionEndpoint(accessor); + }); + })); + _server.setHandler(contextHandler); + _server.start(); + + _client = new WebSocketClient(); + _client.start(); + } + + @AfterEach + public void after() throws Exception + { + _client.stop(); + _server.stop(); + } + + @Test + public void testHttpSessionAfterWebSocketUpgrade() throws Exception + { + EventSocket clientEndpoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + _connector.getLocalPort()); + Session session = _client.connect(clientEndpoint, uri).get(); + + session.sendText("hello", Callback.NOOP); + String receivedMessage = clientEndpoint.textMessages.poll(5, TimeUnit.SECONDS); + assertThat(receivedMessage, equalTo("setByOnOpen")); + + session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeCode, equalTo(StatusCode.NORMAL)); + assertThat(clientEndpoint.closeReason, equalTo(null)); + } +} From 548ed9a08e04ec2ddb1b8c29194e185fbb9b7eb4 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 22 May 2024 12:19:16 +1000 Subject: [PATCH 2/2] add test for invaliding the session from WebSocket Signed-off-by: Lachlan Roberts --- .../ee11/websocket/tests/HttpSessionTest.java | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java b/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java index 43c3d960fb17..0cf8fc5d968c 100644 --- a/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java +++ b/jetty-ee11/jetty-ee11-websocket/jetty-ee11-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee11/websocket/tests/HttpSessionTest.java @@ -61,11 +61,26 @@ public void onOpen(Session session) @OnWebSocketMessage public void onMessage(Session session, String message) { - accessor.access(httpSession -> + if ("onOpenAttribute".equals(message)) { - String value = (String)httpSession.getAttribute("session"); - session.sendText(value, Callback.NOOP); - }); + try + { + accessor.access(httpSession -> + { + String value = (String)httpSession.getAttribute("session"); + session.sendText(value, Callback.NOOP); + }); + } + catch (Throwable t) + { + session.sendText(t.getMessage(), Callback.NOOP); + } + } + else if ("invalidate".equals(message)) + { + accessor.access(HttpSession::invalidate); + session.sendText("success", Callback.NOOP); + } } } @@ -106,10 +121,18 @@ public void testHttpSessionAfterWebSocketUpgrade() throws Exception URI uri = URI.create("ws://localhost:" + _connector.getLocalPort()); Session session = _client.connect(clientEndpoint, uri).get(); - session.sendText("hello", Callback.NOOP); + session.sendText("onOpenAttribute", Callback.NOOP); String receivedMessage = clientEndpoint.textMessages.poll(5, TimeUnit.SECONDS); assertThat(receivedMessage, equalTo("setByOnOpen")); + session.sendText("invalidate", Callback.NOOP); + receivedMessage = clientEndpoint.textMessages.poll(5, TimeUnit.SECONDS); + assertThat(receivedMessage, equalTo("success")); + + session.sendText("onOpenAttribute", Callback.NOOP); + receivedMessage = clientEndpoint.textMessages.poll(5, TimeUnit.SECONDS); + assertThat(receivedMessage, equalTo("Invalid session")); + session.close(); assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(clientEndpoint.closeCode, equalTo(StatusCode.NORMAL));