From a9450d70cb0fbfe9c352d14e0a265e6729ffa608 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 1 Sep 2020 17:35:21 +0200 Subject: [PATCH] Issue #4888 Ensure HttpSessionListener can access session via Request.getSession() Signed-off-by: Jan Bartel --- .../jetty/server/session/SessionHandler.java | 4 +- .../jetty/server/session/CreationTest.java | 77 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index 0d0f72c6e204..255b4b88eafc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -767,7 +767,9 @@ public HttpSession newHttpSession(HttpServletRequest request) try { _sessionCache.add(id, session); - Request.getBaseRequest(request).enterSession(session); + Request baseRequest = Request.getBaseRequest(request); + baseRequest.setSession(session); + baseRequest.enterSession(session); _sessionsCreatedStats.increment(); if (request != null && request.isSecure()) diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java index 02b87fdfcb85..165af557936b 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/CreationTest.java @@ -28,13 +28,17 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.servlet.ListenerHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlet.Source; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.StacklessLogging; @@ -56,7 +60,62 @@ */ public class CreationTest { + static ThreadLocal currentRequest = new ThreadLocal<>(); + @Test + public void testRequestGetSessionInsideListener() throws Exception + { + String contextPath = ""; + String servletMapping = "/server"; + + DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory(); + cacheFactory.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT); + SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory(); + + TestServer server1 = new TestServer(0, -1, -1, cacheFactory, storeFactory); + TestServlet servlet = new TestServlet(); + ServletHolder holder = new ServletHolder(servlet); + ServletContextHandler contextHandler = server1.addContext(contextPath); + + ListenerHolder h = contextHandler.getServletHandler().newListenerHolder(Source.EMBEDDED); + h.setListener(new MySessionListener()); + contextHandler.getServletHandler().addListener(h); + + TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener(); + server1.getServerConnector().addBean(scopeListener); + contextHandler.addServlet(holder, servletMapping); + servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore()); + server1.start(); + int port1 = server1.getPort(); + try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session"))) + { + HttpClient client = new HttpClient(); + client.start(); + + //make a session + String url = "http://localhost:" + port1 + contextPath + servletMapping + "?action=create&check=false"; + + CountDownLatch synchronizer = new CountDownLatch(1); + scopeListener.setExitSynchronizer(synchronizer); + + //make a request to set up a session on the server + ContentResponse response = client.GET(url); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + + String sessionCookie = response.getHeaders().get("Set-Cookie"); + assertTrue(sessionCookie != null); + + //ensure request has finished being handled + synchronizer.await(5, TimeUnit.SECONDS); + } + finally + { + server1.stop(); + } + + } + + /** * Test creating a session when the cache is set to * evict after the request exits. @@ -387,6 +446,23 @@ public void testSessionCreateForwardAndInvalidate() throws Exception } } + public static class MySessionListener implements HttpSessionListener + { + @Override + public void sessionCreated(HttpSessionEvent se) + { + System.err.println("Session created"); + currentRequest.get().getSession(true); + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) + { + System.err.println("Session destroyed"); + } + + } + public static class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; @@ -436,6 +512,7 @@ else if (action != null && "test".equals(action)) } else if (action != null && action.startsWith("create")) { + currentRequest.set(request); HttpSession session = request.getSession(true); _id = session.getId(); session.setAttribute("value", new Integer(1));