mirror of
https://github.com/jetty/jetty.project.git
synced 2025-02-28 02:49:11 +00:00
parent
34b6ecec6c
commit
06bbab50f9
@ -58,32 +58,7 @@ public class AsyncContextState implements AsyncContext
|
||||
@Override
|
||||
public void addListener(final AsyncListener listener, final ServletRequest request, final ServletResponse response)
|
||||
{
|
||||
AsyncListener wrap = new AsyncListener()
|
||||
{
|
||||
@Override
|
||||
public void onTimeout(AsyncEvent event) throws IOException
|
||||
{
|
||||
listener.onTimeout(new AsyncEvent(event.getAsyncContext(),request,response,event.getThrowable()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartAsync(AsyncEvent event) throws IOException
|
||||
{
|
||||
listener.onStartAsync(new AsyncEvent(event.getAsyncContext(),request,response,event.getThrowable()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(AsyncEvent event) throws IOException
|
||||
{
|
||||
listener.onError(new AsyncEvent(event.getAsyncContext(),request,response,event.getThrowable()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(AsyncEvent event) throws IOException
|
||||
{
|
||||
listener.onComplete(new AsyncEvent(event.getAsyncContext(),request,response,event.getThrowable()));
|
||||
}
|
||||
};
|
||||
AsyncListener wrap = new WrappedAsyncListener(listener, request, response);
|
||||
state().addListener(wrap);
|
||||
}
|
||||
|
||||
@ -188,6 +163,46 @@ public class AsyncContextState implements AsyncContext
|
||||
return state();
|
||||
}
|
||||
|
||||
|
||||
public static class WrappedAsyncListener implements AsyncListener
|
||||
{
|
||||
private final AsyncListener _listener;
|
||||
private final ServletRequest _request;
|
||||
private final ServletResponse _response;
|
||||
|
||||
public WrappedAsyncListener(AsyncListener listener, ServletRequest request, ServletResponse response)
|
||||
{
|
||||
_listener = listener;
|
||||
_request = request;
|
||||
_response = response;
|
||||
}
|
||||
|
||||
public AsyncListener getListener()
|
||||
{
|
||||
return _listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout(AsyncEvent event) throws IOException
|
||||
{
|
||||
_listener.onTimeout(new AsyncEvent(event.getAsyncContext(), _request, _response,event.getThrowable()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartAsync(AsyncEvent event) throws IOException
|
||||
{
|
||||
_listener.onStartAsync(new AsyncEvent(event.getAsyncContext(), _request, _response,event.getThrowable()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(AsyncEvent event) throws IOException
|
||||
{
|
||||
_listener.onError(new AsyncEvent(event.getAsyncContext(), _request, _response,event.getThrowable()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(AsyncEvent event) throws IOException
|
||||
{
|
||||
_listener.onComplete(new AsyncEvent(event.getAsyncContext(), _request, _response,event.getThrowable()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +149,25 @@ public class HttpChannelState
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasListener(AsyncListener listener)
|
||||
{
|
||||
try(Locker.Lock lock= _locker.lock())
|
||||
{
|
||||
if (_asyncListeners==null)
|
||||
return false;
|
||||
for (AsyncListener l : _asyncListeners)
|
||||
{
|
||||
if (l==listener)
|
||||
return true;
|
||||
|
||||
if (l instanceof AsyncContextState.WrappedAsyncListener && ((AsyncContextState.WrappedAsyncListener)l).getListener()==listener)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTimeout(long ms)
|
||||
{
|
||||
try(Locker.Lock lock= _locker.lock())
|
||||
|
@ -55,7 +55,7 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
private final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId";
|
||||
public final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId";
|
||||
|
||||
protected static final AtomicLong COUNTER = new AtomicLong();
|
||||
|
||||
|
@ -1148,4 +1148,18 @@ public class Session implements SessionHandler.SessionIf
|
||||
return _resident;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
try (Lock lock = _lock.lock())
|
||||
{
|
||||
return String.format("%s@%x{id=%s,x=%s,req=%d,res=%b}",
|
||||
getClass().getSimpleName(),
|
||||
hashCode(),
|
||||
_sessionData.getId(),
|
||||
_extendedId,
|
||||
_requests,
|
||||
_resident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,8 +162,22 @@ public class SessionHandler extends ScopedHandler
|
||||
@Override
|
||||
public void onComplete(AsyncEvent event) throws IOException
|
||||
{
|
||||
//An async request has completed, so we can complete the session
|
||||
complete(Request.getBaseRequest(event.getAsyncContext().getRequest()).getSession(false));
|
||||
// An async request has completed, so we can complete the session,
|
||||
// but we must locate the session instance for this context
|
||||
Request request = Request.getBaseRequest(event.getAsyncContext().getRequest());
|
||||
HttpSession session = request.getSession(false);
|
||||
String id;
|
||||
if (session!=null)
|
||||
id = session.getId();
|
||||
else
|
||||
{
|
||||
id = (String)request.getAttribute(DefaultSessionIdManager.__NEW_SESSION_ID);
|
||||
if (id==null)
|
||||
id = request.getRequestedSessionId();
|
||||
}
|
||||
|
||||
if (id!=null)
|
||||
complete(getSession(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -412,7 +426,7 @@ public class SessionHandler extends ScopedHandler
|
||||
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
|
||||
Session s = ((SessionIf)session).getSession();
|
||||
|
||||
try
|
||||
@ -425,25 +439,26 @@ public class SessionHandler extends ScopedHandler
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void complete (Session session, Request request)
|
||||
|
||||
@Deprecated
|
||||
public void complete(Session session, Request baseRequest)
|
||||
{
|
||||
if (request.isAsyncStarted() && request.getDispatcherType() == DispatcherType.REQUEST)
|
||||
ensureCompletion(baseRequest);
|
||||
}
|
||||
|
||||
private void ensureCompletion(Request baseRequest)
|
||||
{
|
||||
if (baseRequest.isAsyncStarted())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Adding AsyncListener for {}", request);
|
||||
request.getAsyncContext().addListener(_sessionAsyncListener);
|
||||
LOG.debug("Adding AsyncListener for {}", baseRequest);
|
||||
if (!baseRequest.getHttpChannelState().hasListener(_sessionAsyncListener))
|
||||
baseRequest.getAsyncContext().addListener(_sessionAsyncListener);
|
||||
}
|
||||
else
|
||||
{
|
||||
complete(session);
|
||||
complete(baseRequest.getSession(false));
|
||||
}
|
||||
//if dispatcher type is not async and not request, complete immediately (its a forward or an include)
|
||||
|
||||
//else if dispatcher type is request and not async, complete immediately
|
||||
|
||||
//else register an async callback completion listener that will complete the session
|
||||
}
|
||||
|
||||
|
||||
@ -460,7 +475,6 @@ public class SessionHandler extends ScopedHandler
|
||||
_context=ContextHandler.getCurrentContext();
|
||||
_loader=Thread.currentThread().getContextClassLoader();
|
||||
|
||||
|
||||
synchronized (server)
|
||||
{
|
||||
//Get a SessionDataStore and a SessionDataStore, falling back to in-memory sessions only
|
||||
@ -477,7 +491,6 @@ public class SessionHandler extends ScopedHandler
|
||||
|
||||
_sessionCache.setSessionDataStore(sds);
|
||||
}
|
||||
|
||||
|
||||
if (_sessionIdManager==null)
|
||||
{
|
||||
@ -1642,13 +1655,10 @@ public class SessionHandler extends ScopedHandler
|
||||
finally
|
||||
{
|
||||
//if there is a session that was created during handling this context, then complete it
|
||||
HttpSession finalSession = baseRequest.getSession(false);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("FinalSession={}, old_session_manager={}, this={}, calling complete={}", finalSession, old_session_manager, this, (old_session_manager != this));
|
||||
LOG.debug("FinalSession={}, old_session_manager={}, this={}, calling complete={}", baseRequest.getSession(false), old_session_manager, this, (old_session_manager != this));
|
||||
if (old_session_manager != this)
|
||||
{
|
||||
complete((Session)finalSession, baseRequest);
|
||||
}
|
||||
ensureCompletion(baseRequest);
|
||||
|
||||
if (old_session_manager != null && old_session_manager != this)
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ public class AttributeNameTest
|
||||
//Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=","$1\\$Path=");
|
||||
|
||||
//Make a request to the 2nd server which will do a refresh, use TestFooServlet to ensure that the
|
||||
//Make a request to the 2nd server which will do a refresh, use TestServlet to ensure that the
|
||||
//session attribute with dotted name is not removed
|
||||
Request request2 = client.newRequest("http://localhost:" + port2 + contextPath + servletMapping + "?action=get");
|
||||
request2.header("Cookie", sessionCookie);
|
||||
|
@ -1,77 +0,0 @@
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
|
||||
public class TestFooServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
String action = request.getParameter("action");
|
||||
|
||||
if ("create".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
TestFoo testFoo = new TestFoo();
|
||||
testFoo.setInt(33);
|
||||
FooInvocationHandler handler = new FooInvocationHandler(testFoo);
|
||||
Foo foo = (Foo)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {Foo.class}, handler);
|
||||
session.setAttribute("foo", foo);
|
||||
}
|
||||
else if ("test".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null)
|
||||
response.sendError(500, "Session not activated");
|
||||
Foo foo = (Foo)session.getAttribute("foo");
|
||||
if (foo == null || foo.getInt() != 33)
|
||||
response.sendError(500, "Foo not deserialized");
|
||||
}
|
||||
else if ("async".equals(action))
|
||||
{
|
||||
if (request.getAttribute("async-test") == null)
|
||||
{
|
||||
request.setAttribute("async-test", Boolean.TRUE);
|
||||
AsyncContext acontext = request.startAsync();
|
||||
System.err.println("Starting async and dispatching");
|
||||
|
||||
acontext.dispatch();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
System.err.println("After dispatch and finishing response");
|
||||
response.getWriter().println("OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -24,11 +24,16 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.WriteListener;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
@ -58,42 +63,35 @@ public class AsyncTest
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test async with a session.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
|
||||
@Test
|
||||
public void testSessionWithAsync() throws Exception
|
||||
public void testSessionWithAsyncDispatch() throws Exception
|
||||
{
|
||||
|
||||
|
||||
|
||||
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
|
||||
cacheFactory.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT);
|
||||
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
|
||||
TestServer server1 = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
|
||||
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
String contextPath = "";
|
||||
String fooMapping = "/server";
|
||||
TestFooServlet servlet = new TestFooServlet();
|
||||
String mapping = "/server";
|
||||
|
||||
ServletContextHandler contextHandler = server.addContext(contextPath);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
contextHandler.addServlet(holder, fooMapping);
|
||||
contextHandler.addServlet(holder, mapping);
|
||||
LatchServlet latchServlet = new LatchServlet();
|
||||
ServletHolder latchHolder = new ServletHolder(latchServlet);
|
||||
contextHandler.addServlet(latchHolder, "/latch");
|
||||
|
||||
server1.start();
|
||||
int port1 = server1.getPort();
|
||||
server.start();
|
||||
int port = server.getPort();
|
||||
|
||||
try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session")))
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
String url = "http://localhost:" + port1 + contextPath + fooMapping+"?action=async";
|
||||
String url = "http://localhost:" + port + contextPath + mapping+"?action=async";
|
||||
|
||||
//make a request to set up a session on the server
|
||||
ContentResponse response = client.GET(url);
|
||||
@ -101,11 +99,11 @@ public class AsyncTest
|
||||
|
||||
String sessionCookie = response.getHeaders().get("Set-Cookie");
|
||||
assertTrue(sessionCookie != null);
|
||||
|
||||
|
||||
//make another request, when this is handled, the first request is definitely finished being handled
|
||||
response = client.GET("http://localhost:" + port1 + contextPath + "/latch");
|
||||
response = client.GET("http://localhost:" + port + contextPath + "/latch");
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
|
||||
//session should now be evicted from the cache after request exited
|
||||
String id = TestServer.extractSessionId(sessionCookie);
|
||||
assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id));
|
||||
@ -113,7 +111,243 @@ public class AsyncTest
|
||||
}
|
||||
finally
|
||||
{
|
||||
server1.stop();
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSessionWithAsyncComplete() throws Exception
|
||||
{
|
||||
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
|
||||
cacheFactory.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT);
|
||||
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
|
||||
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
String contextPath = "";
|
||||
String mapping = "/server";
|
||||
|
||||
ServletContextHandler contextHandler = server.addContext(contextPath);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
contextHandler.addServlet(holder, mapping);
|
||||
LatchServlet latchServlet = new LatchServlet();
|
||||
ServletHolder latchHolder = new ServletHolder(latchServlet);
|
||||
contextHandler.addServlet(latchHolder, "/latch");
|
||||
|
||||
server.start();
|
||||
int port = server.getPort();
|
||||
|
||||
try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session")))
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
String url = "http://localhost:" + port + contextPath + mapping+"?action=asyncComplete";
|
||||
|
||||
//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);
|
||||
|
||||
//make another request, when this is handled, the first request is definitely finished being handled
|
||||
response = client.GET("http://localhost:" + port + contextPath + "/latch");
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
//session should now be evicted from the cache after request exited
|
||||
String id = TestServer.extractSessionId(sessionCookie);
|
||||
assertFalse(contextHandler.getSessionHandler().getSessionCache().contains(id));
|
||||
assertTrue(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore().exists(id));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSessionWithCrossContextAsync() throws Exception
|
||||
{
|
||||
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
|
||||
cacheFactory.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT);
|
||||
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
|
||||
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
ServletContextHandler contextA = server.addContext("/ctxA");
|
||||
CrossContextServlet ccServlet = new CrossContextServlet();
|
||||
ServletHolder ccHolder = new ServletHolder(ccServlet);
|
||||
contextA.addServlet(ccHolder, "/*");
|
||||
|
||||
ServletContextHandler contextB = server.addContext("/ctxB");
|
||||
TestServlet testServlet = new TestServlet();
|
||||
ServletHolder testHolder = new ServletHolder(testServlet);
|
||||
contextB.addServlet(testHolder, "/*");
|
||||
LatchServlet latchServlet = new LatchServlet();
|
||||
ServletHolder latchHolder = new ServletHolder(latchServlet);
|
||||
contextB.addServlet(latchHolder, "/latch");
|
||||
|
||||
|
||||
server.start();
|
||||
int port = server.getPort();
|
||||
|
||||
try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session")))
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
String url = "http://localhost:" + port + "/ctxA/test?action=async";
|
||||
|
||||
//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);
|
||||
|
||||
//make another request, when this is handled, the first request is definitely finished being handled
|
||||
response = client.GET("http://localhost:" + port + "/ctxB/latch");
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
//session should now be evicted from the cache after request exited
|
||||
String id = TestServer.extractSessionId(sessionCookie);
|
||||
assertFalse(contextB.getSessionHandler().getSessionCache().contains(id));
|
||||
assertTrue(contextB.getSessionHandler().getSessionCache().getSessionDataStore().exists(id));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSessionWithCrossContextAsyncComplete() throws Exception
|
||||
{
|
||||
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
|
||||
cacheFactory.setEvictionPolicy(SessionCache.EVICT_ON_SESSION_EXIT);
|
||||
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
|
||||
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
ServletContextHandler contextA = server.addContext("/ctxA");
|
||||
CrossContextServlet ccServlet = new CrossContextServlet();
|
||||
ServletHolder ccHolder = new ServletHolder(ccServlet);
|
||||
contextA.addServlet(ccHolder, "/*");
|
||||
|
||||
ServletContextHandler contextB = server.addContext("/ctxB");
|
||||
TestServlet testServlet = new TestServlet();
|
||||
ServletHolder testHolder = new ServletHolder(testServlet);
|
||||
contextB.addServlet(testHolder, "/*");
|
||||
LatchServlet latchServlet = new LatchServlet();
|
||||
ServletHolder latchHolder = new ServletHolder(latchServlet);
|
||||
contextB.addServlet(latchHolder, "/latch");
|
||||
|
||||
|
||||
server.start();
|
||||
int port = server.getPort();
|
||||
|
||||
try (StacklessLogging stackless = new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session")))
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
String url = "http://localhost:" + port + "/ctxA/test?action=asyncComplete";
|
||||
|
||||
//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);
|
||||
|
||||
//make another request, when this is handled, the first request is definitely finished being handled
|
||||
response = client.GET("http://localhost:" + port + "/ctxB/latch");
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
//session should now be evicted from the cache A after request exited
|
||||
String id = TestServer.extractSessionId(sessionCookie);
|
||||
assertFalse(contextA.getSessionHandler().getSessionCache().contains(id));
|
||||
assertTrue(contextA.getSessionHandler().getSessionCache().getSessionDataStore().exists(id));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
String action = request.getParameter("action");
|
||||
|
||||
if ("create".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
TestFoo testFoo = new TestFoo();
|
||||
testFoo.setInt(33);
|
||||
FooInvocationHandler handler = new FooInvocationHandler(testFoo);
|
||||
Foo foo = (Foo)Proxy
|
||||
.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {Foo.class}, handler);
|
||||
session.setAttribute("foo", foo);
|
||||
}
|
||||
else if ("test".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null)
|
||||
response.sendError(500, "Session not activated");
|
||||
Foo foo = (Foo)session.getAttribute("foo");
|
||||
if (foo == null || foo.getInt() != 33)
|
||||
response.sendError(500, "Foo not deserialized");
|
||||
}
|
||||
else if ("async".equals(action))
|
||||
{
|
||||
if (request.getAttribute("async-test") == null)
|
||||
{
|
||||
request.setAttribute("async-test", Boolean.TRUE);
|
||||
AsyncContext acontext = request.startAsync();
|
||||
acontext.dispatch();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
response.getWriter().println("OK");
|
||||
}
|
||||
}
|
||||
else if ("asyncComplete".equals(action))
|
||||
{
|
||||
AsyncContext acontext = request.startAsync();
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
out.setWriteListener(new WriteListener()
|
||||
{
|
||||
@Override
|
||||
public void onWritePossible() throws IOException
|
||||
{
|
||||
if (out.isReady())
|
||||
{
|
||||
request.getSession(true);
|
||||
out.print("OK\n");
|
||||
acontext.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CrossContextServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
AsyncContext acontext = request.startAsync();
|
||||
|
||||
acontext.dispatch(request.getServletContext().getContext("/ctxB"),"/test");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,12 +128,7 @@ public class DeleteUnloadableSessionTest
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TestFooServlet
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public static class TestServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -136,16 +136,9 @@ public class SessionEvictionFailureTest
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TestFooServlet
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public static class TestServlet extends HttpServlet
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user