diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSession.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSession.java index 2163320da..3f1e269cf 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSession.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSession.java @@ -40,6 +40,7 @@ public class AwsHttpSession implements HttpSession { private int maxInactiveInterval; private long lastAccessedTime; private boolean valid; + private boolean isNew = true; /** * @param id A unique session identifier @@ -50,7 +51,7 @@ public AwsHttpSession(String id) { } this.id = id; attributes = new HashMap<>(); - creationTime = Instant.now().getEpochSecond(); + creationTime = Instant.now().toEpochMilli(); maxInactiveInterval = SESSION_DURATION_SEC; lastAccessedTime = creationTime; valid = true; @@ -118,18 +119,27 @@ public void invalidate() { @Override public boolean isNew() { - return lastAccessedTime == creationTime; + if (!valid) { + throw new IllegalStateException("Session is invalidated"); + } + return isNew; } private void touch() { - lastAccessedTime = Instant.now().getEpochSecond(); + lastAccessedTime = Instant.now().toEpochMilli(); + isNew = false; } boolean isValid() { - if (lastAccessedTime - creationTime < maxInactiveInterval) { - return valid; - } else { + if (!valid) { return false; } + + if (maxInactiveInterval <= 0) { + return true; + } + + return Instant.now().toEpochMilli() - lastAccessedTime + < maxInactiveInterval * 1000L; } } diff --git a/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSessionTest.java b/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSessionTest.java index bcca83dda..c1f770a46 100644 --- a/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSessionTest.java +++ b/aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpSessionTest.java @@ -28,8 +28,14 @@ void new_withValidId_setsIdCorrectly() { @Test void new_creationTimePopulatedCorrectly() { + long beforeCreation = Instant.now().toEpochMilli(); + AwsHttpSession session = new AwsHttpSession("id"); - assertTrue(session.getCreationTime() > Instant.now().getEpochSecond() - 1); + + long afterCreation = Instant.now().toEpochMilli(); + + assertTrue(session.getCreationTime() >= beforeCreation); + assertTrue(session.getCreationTime() <= afterCreation); assertEquals(AwsHttpSession.SESSION_DURATION_SEC, session.getMaxInactiveInterval()); assertEquals(session.getLastAccessedTime(), session.getCreationTime()); } @@ -64,16 +70,30 @@ void attributes_dataStoredCorrectly() throws InterruptedException { } @Test - void validSession_expectCorrectValidationOrInvalidation() throws InterruptedException { + void validSession_expectCorrectValidationOrInvalidation() { AwsHttpSession sess = new AwsHttpSession("id"); + assertTrue(sess.isValid()); assertTrue(sess.isNew()); - Thread.sleep(1000); sess.setAttribute("test", "test"); + assertFalse(sess.isNew()); + sess.invalidate(); + assertFalse(sess.isValid()); - assertNull(sess.getAttribute("test")); + assertThrows(IllegalStateException.class, sess::isNew); + } + + @Test + void nonPositiveMaxInactiveIntervalDoesNotExpireSession() { + AwsHttpSession sess = new AwsHttpSession("id"); + + sess.setMaxInactiveInterval(0); + assertTrue(sess.isValid()); + + sess.setMaxInactiveInterval(-1); + assertTrue(sess.isValid()); } }