-
Notifications
You must be signed in to change notification settings - Fork 574
Fix HTTP session timestamp units #1621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,7 +50,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; | ||
|
|
@@ -122,11 +122,11 @@ public boolean isNew() { | |
| } | ||
|
|
||
| private void touch() { | ||
| lastAccessedTime = Instant.now().getEpochSecond(); | ||
| lastAccessedTime = Instant.now().toEpochMilli(); | ||
| } | ||
|
|
||
| boolean isValid() { | ||
| if (lastAccessedTime - creationTime < maxInactiveInterval) { | ||
| if (lastAccessedTime - creationTime < maxInactiveInterval * 1000L) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [BUG] The unit conversion here is correct, but it cements a comparison that measures the wrong quantity: The check should compare current time against the last access: boolean isValid() {
if (Instant.now().toEpochMilli() - lastAccessedTime < maxInactiveInterval 1000L) {
return valid;
} else {
return false;
}
}While touching this line, also consider the spec rule that a zero or negative |
||
| return valid; | ||
| } else { | ||
| return false; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[BUG] Switching
touch()to millisecond resolution regressesisNew(), which is implemented as an equality check on the two timestamps (line 121):With second granularity, any
getAttribute/setAttribute/removeAttributecall occurring in the same wall-clock second as construction leftlastAccessedTimeequal tocreationTime, soisNew()stayedtruefor the duration of a typical sub-second Lambda invocation. WithtoEpochMilli(), the first attribute access almost always advances the timestamp, soisNew()starts returningfalsewithin the very same request that created the session.That contradicts the
HttpSessioncontract:isNew()must returntrueuntil the client has joined the session (i.e. until the client sends back the session id on a subsequent request). Since a session here is created per request and never returned by the client, it should remain new for its whole lifetime. Frameworks layered on top (for example Spring Security's session-fixation and "session created" handling) branch onisNew(), so the flip is externally observable.Decoupling
isNew()from the timestamps keeps the fix to units only:Note that the existing test
validSession_expectCorrectValidationOrInvalidationassertsassertFalse(sess.isNew())after aThread.sleep(1000), so it passes either way and does not cover this behavior change.