This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 2c351d239e Avoid some scenarios of expiration of never expire sessions
2c351d239e is described below
commit 2c351d239e8065b86be830d6384b8ae5c0c1ee90
Author: remm <[email protected]>
AuthorDate: Fri Aug 28 11:44:55 2026 +0200
Avoid some scenarios of expiration of never expire sessions
Tests written by OpenCode.
---
.../apache/catalina/session/DataSourceStore.java | 1 +
java/org/apache/catalina/session/StoreBase.java | 3 +-
.../org/apache/catalina/session/TestFileStore.java | 34 ++++++++++++++++++
.../TestPersistentManagerDataSourceStore.java | 42 ++++++++++++++++++++++
4 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/catalina/session/DataSourceStore.java
b/java/org/apache/catalina/session/DataSourceStore.java
index 670174d6a7..ee7e9cbaac 100644
--- a/java/org/apache/catalina/session/DataSourceStore.java
+++ b/java/org/apache/catalina/session/DataSourceStore.java
@@ -356,6 +356,7 @@ public class DataSourceStore extends StoreBase {
private String[] keys(boolean expiredOnly) throws IOException {
String sqlTmp = "SELECT " + sessionIdCol + " FROM " + sessionTable + "
WHERE " + sessionAppCol + " = ?";
if (expiredOnly) {
+ sqlTmp += " AND " + sessionMaxInactiveCol + " >= 0";
sqlTmp += " AND (" + sessionLastAccessedCol + " + " +
sessionMaxInactiveCol + " * 1000 < ?)";
}
final String keysSql = sqlTmp;
diff --git a/java/org/apache/catalina/session/StoreBase.java
b/java/org/apache/catalina/session/StoreBase.java
index 5530f203b1..373594d6f5 100644
--- a/java/org/apache/catalina/session/StoreBase.java
+++ b/java/org/apache/catalina/session/StoreBase.java
@@ -160,7 +160,8 @@ public abstract class StoreBase extends LifecycleBase
implements Store {
continue;
}
int timeIdle = (int) ((timeNow -
session.getThisAccessedTime()) / 1000L);
- if (timeIdle < session.getMaxInactiveInterval()) {
+ int maxInactive = session.getMaxInactiveInterval();
+ if (maxInactive < 0 || timeIdle < maxInactive) {
continue;
}
if (manager.getContext().getLogger().isTraceEnabled()) {
diff --git a/test/org/apache/catalina/session/TestFileStore.java
b/test/org/apache/catalina/session/TestFileStore.java
index e2109a9dda..67a878a0fb 100644
--- a/test/org/apache/catalina/session/TestFileStore.java
+++ b/test/org/apache/catalina/session/TestFileStore.java
@@ -102,6 +102,40 @@ public class TestFileStore {
Assert.assertEquals(1, fileStore.getSize());
}
+ @Test
+ public void processExpiresNeverExpiringSession() throws Exception {
+ // Use a separate store and directory so this test does not
+ // interfere with the fixtures used by the other tests.
+ FileStore expireStore = new FileStore();
+ expireStore.setManager(manager);
+ expireStore.setDirectory(new File(dir, "expire").getAbsolutePath());
+ expireStore.start();
+ try {
+ // A session that is idle longer than its max inactive interval
+ // but that must never expire.
+ StandardSession neverExpiring = (StandardSession)
manager.createSession("never-expiring");
+ neverExpiring.setManager(manager);
+ neverExpiring.setMaxInactiveInterval(-1);
+ neverExpiring.setCreationTime(System.currentTimeMillis() -
60_000L);
+ expireStore.save(neverExpiring);
+
+ // A session that is idle longer than its max inactive interval
+ // and that must be expired.
+ StandardSession expiring = (StandardSession)
manager.createSession("expiring");
+ expiring.setManager(manager);
+ expiring.setMaxInactiveInterval(1);
+ expiring.setCreationTime(System.currentTimeMillis() - 60_000L);
+ expireStore.save(expiring);
+
+ expireStore.processExpires();
+
+ Assert.assertArrayEquals(new String[] { "never-expiring" },
expireStore.keys());
+ } finally {
+ expireStore.clear();
+ expireStore.stop();
+ }
+ }
+
@Test
public void pathTraversalSessionId() throws Exception {
File storageDir = dir.getAbsoluteFile();
diff --git
a/test/org/apache/catalina/session/TestPersistentManagerDataSourceStore.java
b/test/org/apache/catalina/session/TestPersistentManagerDataSourceStore.java
index 98168d1853..6949d6ba5d 100644
--- a/test/org/apache/catalina/session/TestPersistentManagerDataSourceStore.java
+++ b/test/org/apache/catalina/session/TestPersistentManagerDataSourceStore.java
@@ -36,6 +36,8 @@ import org.apache.catalina.LifecycleException;
import org.apache.catalina.Session;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.unittest.TesterContext;
+import org.apache.tomcat.unittest.TesterServletContext;
public class TestPersistentManagerDataSourceStore extends TomcatBaseTest {
@@ -144,6 +146,46 @@ public class TestPersistentManagerDataSourceStore extends
TomcatBaseTest {
store.clear();
}
+ @Test
+ public void testExpiredKeysNeverExpiringSessions() throws Exception {
+ StandardManager manager = new StandardManager();
+ TesterContext testerContext = new TesterContext();
+ testerContext.setServletContext(new TesterServletContext());
+ manager.setContext(testerContext);
+
+ DerbyDataSourceStore store = new DerbyDataSourceStore("expiredkeys");
+ store.setSessionTable("tomcatsessions");
+ store.setManager(manager);
+ store.start();
+ try {
+ // A session that must never expire.
+ StandardSession neverExpiring = (StandardSession)
manager.createSession("never-expiring");
+ neverExpiring.setManager(manager);
+ neverExpiring.setMaxInactiveInterval(-1);
+ store.save(neverExpiring);
+
+ // A session with a 1 second max inactive interval.
+ StandardSession expiring = (StandardSession)
manager.createSession("expiring");
+ expiring.setManager(manager);
+ expiring.setMaxInactiveInterval(1);
+ store.save(expiring);
+
+ // Make both saved sessions idle for 60 seconds so that the
+ // "expiring" session is well past its max inactive interval.
+ String dbUrl = "jdbc:derby:" +
getTemporaryDirectory().getAbsolutePath() +
+ "/store-expiredkeys";
+ try (Connection conn = DriverManager.getConnection(dbUrl);
+ Statement statement = conn.createStatement()) {
+ statement.execute("update tomcatsessions set lastaccess =
lastaccess - 60000");
+ }
+
+ Assert.assertArrayEquals(new String[] { "expiring" },
store.expiredKeys());
+ } finally {
+ store.clear();
+ store.stop();
+ }
+ }
+
private static class DummyServlet extends HttpServlet {
private static final long serialVersionUID = -3696433049266123995L;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]