Implement saving or passivating when all requests have exited session; implement separate timeout for expiry scavenge and idle timeout and periodic inspection
This commit is contained in:
parent
b61c5ffc1f
commit
436c4835a4
|
@ -0,0 +1,103 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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;
|
||||
|
||||
/**
|
||||
* AbstractInspector
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSessionInspector implements SessionInspector
|
||||
{
|
||||
/**
|
||||
* <0 means never inspect
|
||||
* 0 means always inspect
|
||||
* >0 means inspect at that interval
|
||||
*/
|
||||
protected int _timeoutSec = -1;
|
||||
|
||||
/**
|
||||
* -ve means never inspect
|
||||
* 0 means always inspect
|
||||
* +ve means inspect at interval
|
||||
*/
|
||||
protected long _lastTime;
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionInspector#getTimeoutSec()
|
||||
*/
|
||||
@Override
|
||||
public int getTimeoutSec()
|
||||
{
|
||||
return _timeoutSec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionInspector#setTimeoutSet(int)
|
||||
*/
|
||||
@Override
|
||||
public void setTimeoutSet(int sec)
|
||||
{
|
||||
_timeoutSec = sec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionInspector#preInspection()
|
||||
*/
|
||||
@Override
|
||||
public boolean preInspection()
|
||||
{
|
||||
long now = System.currentTimeMillis();
|
||||
return checkTimeout(now);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionInspector#inspect(org.eclipse.jetty.server.session.Session)
|
||||
*/
|
||||
@Override
|
||||
public void inspect(Session s)
|
||||
{
|
||||
_lastTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionInspector#postInspection()
|
||||
*/
|
||||
@Override
|
||||
public void postInspection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected boolean checkTimeout (long now)
|
||||
{
|
||||
if (_timeoutSec == 0)
|
||||
return true; // always inspect
|
||||
|
||||
if (_timeoutSec < 0)
|
||||
return false; //never inspect
|
||||
|
||||
if (_lastTime == 0)
|
||||
return true; //always perform inspection on first use
|
||||
|
||||
|
||||
return ((now - _lastTime)*1000L) >= _timeoutSec; //only inspect if interval since last inspection has expired
|
||||
}
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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 static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
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;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.server.SessionManager;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* IdleSessionTest
|
||||
*
|
||||
* Checks that a session can be idled and de-idled on the next request if it hasn't expired.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class IdleSessionTest
|
||||
{
|
||||
|
||||
public class IdleHashTestServer extends HashTestServer
|
||||
{
|
||||
private int _idlePeriod;
|
||||
private File _storeDir;
|
||||
|
||||
public IdleHashTestServer(int port, int maxInactivePeriod, int scavengePeriod, int idlePeriod, File storeDir)
|
||||
{
|
||||
super(port, maxInactivePeriod, scavengePeriod);
|
||||
_idlePeriod = idlePeriod;
|
||||
_storeDir = storeDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionManager newSessionManager()
|
||||
{
|
||||
FileSessionManager manager = new FileSessionManager();
|
||||
manager.getSessionStore().setIdlePassivationTimeoutSec(_idlePeriod);
|
||||
manager.getSessionDataStore().setStoreDir(_storeDir);
|
||||
return manager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public HashTestServer createServer(int port, int max, int scavenge, int idle, File storeDir)
|
||||
{
|
||||
return new IdleHashTestServer(port, max, scavenge, idle, storeDir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void pause (int sec)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(sec * 1000L);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSessionIdle() throws Exception
|
||||
{
|
||||
String contextPath = "";
|
||||
String servletMapping = "/server";
|
||||
int inactivePeriod = 200;
|
||||
int scavengePeriod = 3;
|
||||
int idlePeriod = 5;
|
||||
((StdErrLog)Log.getLogger("org.eclipse.jetty.server.session")).setHideStacks(true);
|
||||
System.setProperty("org.eclipse.jetty.STACKS", "false");
|
||||
File storeDir = new File (System.getProperty("java.io.tmpdir"), "idle-test");
|
||||
storeDir.deleteOnExit();
|
||||
|
||||
HashTestServer server1 = createServer(0, inactivePeriod, scavengePeriod, idlePeriod, storeDir);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
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 response = client.GET(url + "?action=init");
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
String sessionCookie = response.getHeaders().get("Set-Cookie");
|
||||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
//and wait until the session should be idled out
|
||||
pause(idlePeriod * 2);
|
||||
|
||||
//check that the file exists
|
||||
checkSessionIdled(storeDir, HashTestServer.extractSessionId(sessionCookie));
|
||||
|
||||
//make another request to de-idle the session
|
||||
Request request = client.newRequest(url + "?action=test");
|
||||
request.getHeaders().add("Cookie", sessionCookie);
|
||||
ContentResponse response2 = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
|
||||
|
||||
//check session de-idled
|
||||
checkSessionDeIdled(storeDir);
|
||||
|
||||
//wait again for the session to be idled
|
||||
pause(idlePeriod * 2);
|
||||
|
||||
//check that it is
|
||||
checkSessionIdled(storeDir, HashTestServer.extractSessionId(sessionCookie));
|
||||
|
||||
|
||||
//delete the file
|
||||
File idleFile = getIdleFile(storeDir, HashTestServer.extractSessionId(sessionCookie));
|
||||
assertTrue(idleFile.exists());
|
||||
assertTrue(idleFile.delete());
|
||||
|
||||
//make a request
|
||||
request = client.newRequest(url + "?action=testfail");
|
||||
request.getHeaders().add("Cookie", sessionCookie);
|
||||
response2 = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
|
||||
}
|
||||
finally
|
||||
{
|
||||
server1.stop();
|
||||
IO.delete(storeDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param sessionDir
|
||||
* @param sessionId
|
||||
*/
|
||||
public void checkSessionIdled (File sessionDir, String sessionId)
|
||||
{
|
||||
assertNotNull(sessionDir);
|
||||
assertTrue(sessionDir.exists());
|
||||
String[] files = sessionDir.list();
|
||||
assertNotNull(files);
|
||||
assertEquals(1, files.length);
|
||||
assertTrue(files[0].contains(sessionId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param sessionDir
|
||||
*/
|
||||
public void checkSessionDeIdled (File sessionDir)
|
||||
{
|
||||
assertNotNull(sessionDir);
|
||||
assertTrue(sessionDir.exists());
|
||||
String[] files = sessionDir.list();
|
||||
assertNotNull(files);
|
||||
assertEquals(0, files.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sessionDir
|
||||
* @param sessionId
|
||||
* @return
|
||||
*/
|
||||
public File getIdleFile (File sessionDir, String sessionId)
|
||||
{
|
||||
assertNotNull(sessionDir);
|
||||
assertTrue(sessionDir.exists());
|
||||
String[] files = sessionDir.list();
|
||||
assertNotNull(files);
|
||||
return new File(sessionDir, files[0]);
|
||||
}
|
||||
|
||||
|
||||
public static class TestServlet extends HttpServlet
|
||||
{
|
||||
public String originalId = null;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
|
||||
{
|
||||
String action = request.getParameter("action");
|
||||
if ("init".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
session.setAttribute("test", "test");
|
||||
originalId = session.getId();
|
||||
Session s = (Session)session;
|
||||
try (Lock lock = s.lock())
|
||||
{
|
||||
assertTrue(!s.isPassivated());
|
||||
}
|
||||
}
|
||||
else if ("test".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
assertTrue(session != null);
|
||||
assertTrue(originalId.equals(session.getId()));
|
||||
assertEquals("test", session.getAttribute("test"));
|
||||
}
|
||||
else if ("testfail".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
assertTrue(session == null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue