Skip to content

Commit

Permalink
Jetty 12.0.x object identity ee8 and ee9 (#11888)
Browse files Browse the repository at this point in the history
* Fix for ee8/9 object identity
  • Loading branch information
janbartel authored Jun 20, 2024
1 parent 422d73d commit fd263c7
Show file tree
Hide file tree
Showing 11 changed files with 605 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ public void setRefreshCookieAge(int ageInSeconds)
/**
* Get a known existing session
*
* @param extendedId The session id, possibly imcluding worker name suffix.
* @param extendedId The session id, possibly including worker name suffix.
* @return the Session matching the id or null if none exists
*/
@Override
Expand Down Expand Up @@ -1266,6 +1266,18 @@ protected RequestedSession resolveRequestedSessionId(Request request)
}
}

//try getting a session id for our context that has been newly created by another context
if (request.getContext().isCrossContextDispatch(request))
{
String tmp = (String)request.getAttribute(DefaultSessionIdManager.__NEW_SESSION_ID);
if (!StringUtil.isEmpty(tmp))
{
if (ids == null)
ids = new ArrayList<>();
ids.add(tmp);
}
}

if (ids == null)
return NO_REQUESTED_SESSION;

Expand Down Expand Up @@ -1425,7 +1437,8 @@ public HttpCookie getSessionCookie(ManagedSession session, boolean requestIsSecu

/**
* StreamWrapper to intercept commit and complete events to ensure
* session handling happens in context, with request available.
* session handling happens in context, with the request available.
* This implementation assumes that a request only has a single session.
*/
private class SessionStreamWrapper extends HttpStream.Wrapper
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,50 @@ public void testSessionCreateInvalidateCreate() throws Exception
}
}

@Test
public void testSessionCreateReForward() throws Exception
{
String contextPath = "";
String contextC = "/contextC";
String servletMapping = "/server";
int inactivePeriod = 20;
int scavengePeriod = 3;
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
cacheFactory.setFlushOnResponseCommit(true); //ensure session is saved before response comes back
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();

SessionTestSupport server1 = new SessionTestSupport(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
contextHandler.setCrossContextDispatchSupported(true);
contextHandler.addServlet(holder, servletMapping);
ServletContextHandler ctxC = server1.addContext(contextC);
ctxC.setCrossContextDispatchSupported(true);
ctxC.addServlet(TestServletC.class, servletMapping);
server1.start();
int port1 = server1.getPort();

try (StacklessLogging stackless = new StacklessLogging(CreationTest.class.getPackage()))
{
HttpClient client = new HttpClient();
client.start();
String url = "http://localhost:" + port1 + contextPath + servletMapping;

ContentResponse response = client.GET(url + "?action=forwardC");
assertEquals(HttpServletResponse.SC_OK, response.getStatus());

//check that the sessions exist persisted
Awaitility.waitAtMost(5, TimeUnit.SECONDS).until(() -> contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(servlet._id));
Awaitility.waitAtMost(5, TimeUnit.SECONDS).until(() -> ctxC.getSessionHandler().getSessionCache().getSessionDataStore().exists(servlet._id));
}
finally
{
server1.stop();
}
}

/**
* Create a session in a context, forward to another context and create a
* session in it too. Check that both sessions exist after the response
Expand Down Expand Up @@ -426,84 +470,99 @@ public void setStore(SessionDataStore store)
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
{
String action = request.getParameter("action");

if (action != null && action.startsWith("forward"))
switch (action.toLowerCase())
{
HttpSession session = request.getSession(true);

_id = session.getId();
session.setAttribute("value", 1);

ServletContext contextB = getServletContext().getContext("/contextB");
RequestDispatcher dispatcherB = contextB.getRequestDispatcher(request.getServletPath());
dispatcherB.forward(request, httpServletResponse);

if (action.endsWith("inv"))
{
session.invalidate();
}
else
case "forward" ->
{
HttpSession session = createAndSaveSessionId(request);
ServletContext contextB = getServletContext().getContext("/contextB");
RequestDispatcher dispatcherB = contextB.getRequestDispatcher(request.getServletPath());
dispatcherB.forward(request, httpServletResponse);

session = request.getSession(false);
assertNotNull(session);
assertEquals(_id, session.getId());
assertNotNull(session.getAttribute("value"));
assertNull(session.getAttribute("B")); //check we don't see stuff from other context
}
return;
}
else if ("test".equals(action))
{
HttpSession session = request.getSession(false);
assertNotNull(session);
return;
}
else if (action != null && action.startsWith("create"))
{
currentRequest.set(request);
HttpSession session = request.getSession(true);
_id = session.getId();
session.setAttribute("value", 1);

System.err.println("Created session " + _id);
String check = request.getParameter("check");
if (!StringUtil.isBlank(check) && _store != null)
case "forwardc" ->
{
boolean exists;
try
{
exists = _store.exists(_id);
System.err.println("Does session exist in store: " + exists);
}
catch (Exception e)
{
throw new ServletException(e);
}
HttpSession session = createAndSaveSessionId(request);

if ("false".equalsIgnoreCase(check))
assertFalse(exists);
else
assertTrue(exists);
//forward to contextC
ServletContext contextC = getServletContext().getContext("/contextC");
RequestDispatcher dispatcherC = contextC.getRequestDispatcher(request.getServletPath());
dispatcherC.forward(request, httpServletResponse);
}

if ("createinv".equals(action))
case "forwardinv" ->
{
session.invalidate();
assertNull(request.getSession(false));
HttpSession session = createAndSaveSessionId(request);
assertNotNull(session);

ServletContext contextB = getServletContext().getContext("/contextB");
RequestDispatcher dispatcherB = contextB.getRequestDispatcher(request.getServletPath());
dispatcherB.forward(request, httpServletResponse);
session.invalidate();
}
else if ("createinvcreate".equals(action))
case "test" ->
{
session.invalidate();
System.err.println("Session invalidated " + _id);
assertNull(request.getSession(false));
assertNotNull(_id);
HttpSession session = request.getSession(false);
assertNotNull(session);
session = request.getSession(true);
_id = session.getId();
System.err.println("Created another session " + _id);
assertNotNull(session.getAttribute("value")); //check we see our previous session
assertNull(session.getAttribute("B")); //check we don't see stuff from other contexts
assertNull(session.getAttribute("C"));
}
case "create", "createinv", "createinvcreate" ->
{
currentRequest.set(request);
HttpSession session = createAndSaveSessionId(request);
String check = request.getParameter("check");
if (!StringUtil.isBlank(check) && _store != null)
{
boolean exists = false;
try
{
exists = _store.exists(_id);
}
catch (Exception e)
{
throw new ServletException(e);
}

switch (check.toLowerCase())
{
case "true" -> assertTrue(exists);
case "false" -> assertFalse(exists);
}
}

if ("createinv".equals(action))
{
session.invalidate();
assertNull(request.getSession(false));
assertNotNull(session);
}
else if ("createinvcreate".equals(action))
{
session.invalidate();

assertNull(request.getSession(false));
assertNotNull(session);
session = request.getSession(true);
_id = session.getId();
}
}
}
}

private HttpSession createAndSaveSessionId(HttpServletRequest request)
{
HttpSession session = request.getSession(true);
_id = session.getId();
session.setAttribute("value", 1);
return session;
}
}

public static class TestServletB extends HttpServlet
Expand All @@ -525,4 +584,25 @@ protected void doGet(HttpServletRequest request, HttpServletResponse httpServlet
session.setAttribute("B", "B");
}
}

public static class TestServletC extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
{
HttpSession session = request.getSession(false);
assertNull(session);
session = request.getSession(true);

// Be sure nothing from contextA is present
Object objectA = session.getAttribute("value");
assertNull(objectA);

session.setAttribute("C", "C");

//forward back to A
ServletContext contextA = getServletContext().getContext("/");
RequestDispatcher dispatcherA = contextA.getRequestDispatcher(request.getServletPath() + "?action=test");
dispatcherA.forward(request, httpServletResponse);
}
}
}
Loading

0 comments on commit fd263c7

Please sign in to comment.