Issue #1307
This commit is contained in:
parent
c48b471caa
commit
f76dafebc3
|
@ -844,36 +844,14 @@ public class Session implements SessionHandler.SessionIf
|
|||
if (_handler == null)
|
||||
throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
|
||||
|
||||
boolean result = false;
|
||||
|
||||
try (Lock lock = _lock.lockIfNotHeld())
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case INVALID:
|
||||
{
|
||||
throw new IllegalStateException(); //spec does not allow invalidate of already invalid session
|
||||
}
|
||||
case VALID:
|
||||
{
|
||||
//only first change from valid to invalidating should be actionable
|
||||
result = true;
|
||||
_state = State.INVALIDATING;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG.info("Session {} already being invalidated", _sessionData.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean result = beginInvalidate();
|
||||
|
||||
try
|
||||
{
|
||||
//if the session was not already invalid, or in process of being invalidated, do invalidate
|
||||
if (result)
|
||||
{
|
||||
//tell id mgr to remove session from all other contexts
|
||||
//tell id mgr to remove session from all contexts
|
||||
_handler.getSessionIdManager().invalidateAll(_sessionData.getId());
|
||||
}
|
||||
}
|
||||
|
@ -901,6 +879,39 @@ public class Session implements SessionHandler.SessionIf
|
|||
{
|
||||
return _lock.lockIfNotHeld();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/**
|
||||
* @return true if the session is not already invalid or being invalidated.
|
||||
*/
|
||||
protected boolean beginInvalidate()
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
try (Lock lock = _lock.lockIfNotHeld())
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case INVALID:
|
||||
{
|
||||
throw new IllegalStateException(); //spec does not allow invalidate of already invalid session
|
||||
}
|
||||
case VALID:
|
||||
{
|
||||
//only first change from valid to invalidating should be actionable
|
||||
result = true;
|
||||
_state = State.INVALIDATING;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG.info("Session {} already being invalidated", _sessionData.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/** Call HttpSessionAttributeListeners as part of invalidating
|
||||
|
@ -908,7 +919,20 @@ public class Session implements SessionHandler.SessionIf
|
|||
*
|
||||
* @throws IllegalStateException
|
||||
*/
|
||||
@Deprecated
|
||||
protected void doInvalidate() throws IllegalStateException
|
||||
{
|
||||
finishInvalidate();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/** Call HttpSessionAttributeListeners as part of invalidating
|
||||
* a Session.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
*/
|
||||
protected void finishInvalidate() throws IllegalStateException
|
||||
{
|
||||
try (Lock lock = _lock.lockIfNotHeld())
|
||||
{
|
||||
|
|
|
@ -1048,6 +1048,8 @@ public class SessionHandler extends ScopedHandler
|
|||
{
|
||||
if (invalidate)
|
||||
{
|
||||
session.beginInvalidate();
|
||||
|
||||
if (_sessionListeners!=null)
|
||||
{
|
||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||
|
@ -1214,8 +1216,7 @@ public class SessionHandler extends ScopedHandler
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Called either when a session has expired, or the app has
|
||||
* invalidated it.
|
||||
* Called when a session has expired.
|
||||
*
|
||||
* @param id the id to invalidate
|
||||
*/
|
||||
|
@ -1232,7 +1233,7 @@ public class SessionHandler extends ScopedHandler
|
|||
if (session != null)
|
||||
{
|
||||
_sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
|
||||
session.doInvalidate();
|
||||
session.finishInvalidate();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -1242,7 +1243,11 @@ public class SessionHandler extends ScopedHandler
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Called periodically by the HouseKeeper to handle the list of
|
||||
* sessions that have expired since the last call to scavenge.
|
||||
*/
|
||||
public void scavenge ()
|
||||
{
|
||||
//don't attempt to scavenge if we are shutting down
|
||||
|
@ -1279,7 +1284,7 @@ public class SessionHandler extends ScopedHandler
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Each session has a timer that is configured to go off
|
||||
* when either the session has not been accessed for a
|
||||
|
|
|
@ -22,11 +22,8 @@ package org.eclipse.jetty.gcloud.session;
|
|||
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
|
||||
import org.eclipse.jetty.server.session.AbstractTestServer;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -37,10 +34,11 @@ import org.junit.Assert;
|
|||
public class SessionExpiryTest extends AbstractSessionExpiryTest
|
||||
{
|
||||
|
||||
@AfterClass
|
||||
public static void teardown () throws Exception
|
||||
@After
|
||||
public void teardown () throws Exception
|
||||
{
|
||||
GCloudTestSuite.__testSupport.deleteSessions();
|
||||
System.err.println("Deleted sessions");
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,25 +51,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest
|
|||
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testSessionNotExpired() throws Exception
|
||||
{
|
||||
super.testSessionNotExpired();
|
||||
GCloudTestSuite.__testSupport.deleteSessions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionExpiryTest#testSessionExpiry()
|
||||
*/
|
||||
@Test
|
||||
@Override
|
||||
public void testSessionExpiry() throws Exception
|
||||
{
|
||||
super.testSessionExpiry();
|
||||
|
||||
GCloudTestSuite.__testSupport.deleteSessions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifySessionCreated(TestHttpSessionListener listener, String sessionId)
|
||||
|
@ -80,6 +60,9 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest
|
|||
try {GCloudTestSuite.__testSupport.assertSessions(1);}catch(Exception e){ Assert.fail(e.getMessage());}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void verifySessionDestroyed(TestHttpSessionListener listener, String sessionId)
|
||||
{
|
||||
|
|
|
@ -49,9 +49,16 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest
|
|||
super.testSessionExpiry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionExpiryTest#testSessionExpiresWithListener()
|
||||
*/
|
||||
@Test
|
||||
public void testSessionExpiresWithListener() throws Exception
|
||||
{
|
||||
super.testSessionExpiresWithListener();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
|
|
|
@ -68,18 +68,90 @@ public abstract class AbstractSessionExpiryTest extends AbstractTestBase
|
|||
{
|
||||
public List<String> createdSessions = new ArrayList<String>();
|
||||
public List<String> destroyedSessions = new ArrayList<String>();
|
||||
public boolean accessAttribute = false;
|
||||
public Exception ex = null;
|
||||
|
||||
public TestHttpSessionListener(boolean access)
|
||||
{
|
||||
accessAttribute = access;
|
||||
}
|
||||
|
||||
public TestHttpSessionListener()
|
||||
{
|
||||
accessAttribute = false;
|
||||
}
|
||||
|
||||
public void sessionDestroyed(HttpSessionEvent se)
|
||||
{
|
||||
destroyedSessions.add(se.getSession().getId());
|
||||
if (accessAttribute)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
se.getSession().getAttribute("anything");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ex = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sessionCreated(HttpSessionEvent se)
|
||||
{
|
||||
createdSessions.add(se.getSession().getId());
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testSessionExpiresWithListener() throws Exception
|
||||
{
|
||||
String contextPath = "";
|
||||
String servletMapping = "/server";
|
||||
int inactivePeriod = 3;
|
||||
int scavengePeriod = 1;
|
||||
AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod, SessionCache.NEVER_EVICT);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler context = server1.addContext(contextPath);
|
||||
context.addServlet(holder, servletMapping);
|
||||
TestHttpSessionListener listener = new TestHttpSessionListener(true);
|
||||
|
||||
context.getSessionHandler().addEventListener(listener);
|
||||
|
||||
server1.start();
|
||||
int port1 = server1.getPort();
|
||||
|
||||
try
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
String url = "http://localhost:" + port1 + contextPath + servletMapping;
|
||||
|
||||
//make a request to set up a session on the server
|
||||
ContentResponse response1 = client.GET(url + "?action=init");
|
||||
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
|
||||
String sessionCookie = response1.getHeaders().get("Set-Cookie");
|
||||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
String sessionId = AbstractTestServer.extractSessionId(sessionCookie);
|
||||
|
||||
verifySessionCreated(listener,sessionId);
|
||||
|
||||
//and wait until the session should have expired
|
||||
pause(inactivePeriod+(scavengePeriod*2));
|
||||
|
||||
verifySessionDestroyed (listener, sessionId);
|
||||
assertNull(listener.ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
server1.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check session is preserved over stop/start
|
||||
|
|
Loading…
Reference in New Issue