402706 HttpSession.setMaxInactiveInterval(int) does not change JDBCSession expiry
This commit is contained in:
parent
11442814fa
commit
0834ad259c
|
@ -62,6 +62,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
public class JDBCSessionIdManager extends AbstractSessionIdManager
|
||||
{
|
||||
final static Logger LOG = SessionHandler.LOG;
|
||||
public final static int MAX_INTERVAL_NOT_SET = -999;
|
||||
|
||||
protected final HashSet<String> _sessionIds = new HashSet<String>();
|
||||
protected Server _server;
|
||||
|
@ -629,6 +630,9 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
|
|||
* Set up the tables in the database
|
||||
* @throws SQLException
|
||||
*/
|
||||
/**
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void prepareTables()
|
||||
throws SQLException
|
||||
{
|
||||
|
@ -671,9 +675,38 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
|
|||
_createSessionTable = "create table "+_sessionTable+" ("+_sessionTableRowId+" varchar(120), sessionId varchar(120), "+
|
||||
" contextPath varchar(60), virtualHost varchar(60), lastNode varchar(60), accessTime "+longType+", "+
|
||||
" lastAccessTime "+longType+", createTime "+longType+", cookieTime "+longType+", "+
|
||||
" lastSavedTime "+longType+", expiryTime "+longType+", map "+blobType+", primary key("+_sessionTableRowId+"))";
|
||||
" lastSavedTime "+longType+", expiryTime "+longType+", maxInterval "+longType+", map "+blobType+", primary key("+_sessionTableRowId+"))";
|
||||
connection.createStatement().executeUpdate(_createSessionTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
//session table exists, check it has maxinterval column
|
||||
ResultSet colResult = null;
|
||||
try
|
||||
{
|
||||
colResult = metaData.getColumns(null, null,_dbAdaptor.convertIdentifier(_sessionTable), _dbAdaptor.convertIdentifier("maxInterval"));
|
||||
}
|
||||
catch (SQLException s)
|
||||
{
|
||||
LOG.warn("Problem checking if "+_sessionTable+" table contains maxInterval column. Ensure table contains column definition: \"maxInterval long not null default -999\"");
|
||||
throw s;
|
||||
}
|
||||
|
||||
if (!colResult.next())
|
||||
{
|
||||
try
|
||||
{
|
||||
//add the maxinterval column
|
||||
String longType = _dbAdaptor.getLongType();
|
||||
connection.createStatement().executeUpdate("alter table "+_sessionTable+" add maxInterval "+longType+" not null default "+MAX_INTERVAL_NOT_SET);
|
||||
}
|
||||
catch (SQLException s)
|
||||
{
|
||||
LOG.warn("Problem adding maxInterval column. Ensure table contains column definition: \"maxInterval long not null default -999\"");
|
||||
throw s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//make some indexes on the JettySessions table
|
||||
String index1 = "idx_"+_sessionTable+"_expiry";
|
||||
|
@ -701,20 +734,20 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
|
|||
|
||||
//set up some strings representing the statements for session manipulation
|
||||
_insertSession = "insert into "+_sessionTable+
|
||||
" ("+_sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+
|
||||
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
" ("+_sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, maxInterval, map) "+
|
||||
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
_deleteSession = "delete from "+_sessionTable+
|
||||
" where "+_sessionTableRowId+" = ?";
|
||||
|
||||
_updateSession = "update "+_sessionTable+
|
||||
" set sessionId = ?, lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, map = ? where "+_sessionTableRowId+" = ?";
|
||||
" set sessionId = ?, lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, maxInterval = ?, map = ? where "+_sessionTableRowId+" = ?";
|
||||
|
||||
_updateSessionNode = "update "+_sessionTable+
|
||||
" set lastNode = ? where "+_sessionTableRowId+" = ?";
|
||||
|
||||
_updateSessionAccessTime = "update "+_sessionTable+
|
||||
" set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+_sessionTableRowId+" = ?";
|
||||
" set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, maxInterval = ? where "+_sessionTableRowId+" = ?";
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -160,10 +160,12 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
* @param created
|
||||
* @param accessed
|
||||
*/
|
||||
protected Session (String sessionId, String rowId, long created, long accessed)
|
||||
protected Session (String sessionId, String rowId, long created, long accessed, long maxInterval)
|
||||
{
|
||||
super(JDBCSessionManager.this, created, accessed, sessionId);
|
||||
_rowId = rowId;
|
||||
super.setMaxInactiveInterval((int)maxInterval); //restore the session's previous inactivity interval setting
|
||||
_expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
|
||||
}
|
||||
|
||||
|
||||
|
@ -279,6 +281,33 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Change the max idle time for this session. This recalculates the expiry time.
|
||||
* @see org.eclipse.jetty.server.session.AbstractSession#setMaxInactiveInterval(int)
|
||||
*/
|
||||
@Override
|
||||
public void setMaxInactiveInterval(int secs)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
super.setMaxInactiveInterval(secs);
|
||||
int maxInterval=getMaxInactiveInterval();
|
||||
_expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
|
||||
//force the session to be written out right now
|
||||
try
|
||||
{
|
||||
updateSessionAccessTime(this);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Problem saving changed max idle time for session "+ this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -346,7 +375,7 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
return "Session rowId="+_rowId+",id="+getId()+",lastNode="+_lastNode+
|
||||
",created="+getCreationTime()+",accessed="+getAccessed()+
|
||||
",lastAccessed="+getLastAccessedTime()+",cookieSet="+_cookieSet+
|
||||
",lastSaved="+_lastSaved+",expiry="+_expiryTime;
|
||||
",maxInterval="+getMaxInactiveInterval()+",lastSaved="+_lastSaved+",expiry="+_expiryTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -842,6 +871,9 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
final AtomicReference<Exception> _exception = new AtomicReference<Exception>();
|
||||
Runnable load = new Runnable()
|
||||
{
|
||||
/**
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void run()
|
||||
{
|
||||
|
@ -855,7 +887,15 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
ResultSet result = statement.executeQuery();
|
||||
if (result.next())
|
||||
{
|
||||
session = new Session(id, result.getString(_jdbcSessionIdMgr._sessionTableRowId), result.getLong("createTime"), result.getLong("accessTime"));
|
||||
long maxInterval = result.getLong("maxInterval");
|
||||
if (maxInterval == JDBCSessionIdManager.MAX_INTERVAL_NOT_SET)
|
||||
{
|
||||
maxInterval = getMaxInactiveInterval(); //if value not saved for maxInactiveInterval, use current value from sessionmanager
|
||||
}
|
||||
session = new Session(id, result.getString(_jdbcSessionIdMgr._sessionTableRowId),
|
||||
result.getLong("createTime"),
|
||||
result.getLong("accessTime"),
|
||||
maxInterval);
|
||||
session.setCookieSet(result.getLong("cookieTime"));
|
||||
session.setLastAccessedTime(result.getLong("lastAccessTime"));
|
||||
session.setLastNode(result.getString("lastNode"));
|
||||
|
@ -939,6 +979,7 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
statement.setLong(9, session.getCookieSet());//time cookie was set
|
||||
statement.setLong(10, now); //last saved time
|
||||
statement.setLong(11, session.getExpiryTime());
|
||||
statement.setLong(12, session.getMaxInactiveInterval());
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
|
@ -946,7 +987,8 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
|
||||
statement.setBinaryStream(13, bais, bytes.length);//attribute map as blob
|
||||
|
||||
|
||||
statement.executeUpdate();
|
||||
session.setRowId(rowId); //set it on the in-memory data as well as in db
|
||||
|
@ -989,6 +1031,7 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
statement.setLong(4, data.getLastAccessedTime()); //lastAccessTime
|
||||
statement.setLong(5, now); //last saved time
|
||||
statement.setLong(6, data.getExpiryTime());
|
||||
statement.setLong(7, data.getMaxInactiveInterval());
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
|
@ -996,8 +1039,8 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
byte[] bytes = baos.toByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
|
||||
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
|
||||
statement.setString(8, data.getRowId()); //rowId
|
||||
statement.setBinaryStream(8, bais, bytes.length);//attribute map as blob
|
||||
statement.setString(9, data.getRowId()); //rowId
|
||||
statement.executeUpdate();
|
||||
|
||||
data.setLastSaved(now);
|
||||
|
@ -1063,7 +1106,9 @@ public class JDBCSessionManager extends AbstractSessionManager
|
|||
statement.setLong(3, data.getLastAccessedTime());
|
||||
statement.setLong(4, now);
|
||||
statement.setLong(5, data.getExpiryTime());
|
||||
statement.setString(6, data.getRowId());
|
||||
statement.setLong(6, data.getMaxInactiveInterval());
|
||||
statement.setString(7, data.getRowId());
|
||||
|
||||
statement.executeUpdate();
|
||||
data.setLastSaved(now);
|
||||
statement.close();
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.assertTrue;
|
||||
|
||||
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.servlet.ServletContextHandler;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* ModifyMaxInactiveIntervalTest
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ModifyMaxInactiveIntervalTest
|
||||
{
|
||||
|
||||
public static int inactive = 4;
|
||||
public static int newMaxInactive = 20;
|
||||
public static int scavenge = 1;
|
||||
|
||||
@Test
|
||||
public void testSessionExpiryAfterModifiedMaxInactiveInterval() throws Exception
|
||||
{
|
||||
AbstractTestServer server = new JdbcTestServer(0,inactive,scavenge);
|
||||
|
||||
ServletContextHandler ctxA = server.addContext("/mod");
|
||||
ctxA.addServlet(TestModServlet.class, "/test");
|
||||
|
||||
server.start();
|
||||
int port=server.getPort();
|
||||
try
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
try
|
||||
{
|
||||
// Perform a request to create a session
|
||||
|
||||
ContentResponse response = client.GET("http://localhost:" + port + "/mod/test?action=create");
|
||||
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
String sessionCookie = response.getHeaders().getStringField("Set-Cookie");
|
||||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
//do another request to change the maxinactive interval
|
||||
Request request = client.newRequest("http://localhost:" + port + "/mod/test?action=change&val="+newMaxInactive);
|
||||
request.header("Cookie", sessionCookie);
|
||||
response = request.send();
|
||||
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
//wait for longer than the old inactive interval
|
||||
Thread.currentThread().sleep(10*1000L);
|
||||
|
||||
//do another request using the cookie to ensure the session is still there
|
||||
|
||||
request= client.newRequest("http://localhost:" + port + "/mod/test?action=test");
|
||||
request.header("Cookie", sessionCookie);
|
||||
response = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestModServlet 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);
|
||||
return;
|
||||
}
|
||||
|
||||
if ("change".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null)
|
||||
throw new ServletException("Session is null for action=change");
|
||||
|
||||
String tmp = request.getParameter("val");
|
||||
int interval = -1;
|
||||
interval = (tmp==null?-1:Integer.parseInt(tmp));
|
||||
|
||||
if (interval > 0)
|
||||
session.setMaxInactiveInterval(interval);
|
||||
return;
|
||||
}
|
||||
|
||||
if ("test".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null)
|
||||
throw new ServletException("Session does not exist");
|
||||
assertEquals(ModifyMaxInactiveIntervalTest.newMaxInactive, session.getMaxInactiveInterval());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue