Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion core/src/main/java/lucee/runtime/PageContextImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3998,7 +3998,8 @@ public ClassLoader getRPCClassLoader(boolean reload, JavaSettings customJS) thro

public void resetSession() {
if (this.session != null && this.session instanceof JSession) {
getSession().invalidate();
HttpSession httpSession = getHttpServletRequest().getSession(false);
if (httpSession != null) httpSession.invalidate();
}
this.session = null;
}
Expand Down
23 changes: 14 additions & 9 deletions core/src/main/java/lucee/runtime/type/scope/ScopeContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ public void invalidateUserScope(PageContextImpl pc, boolean migrateSessionData,
if (hasSessionManagement) {
if (isJ2EESession) {
// For J2EE sessions, try the HttpSession attribute first
HttpSession httpSession = pc.getSession();
HttpSession httpSession = pc.getHttpServletRequest().getSession(false);
if (httpSession != null) {
Object session = httpSession.getAttribute(appContext.getName());
if (session instanceof JSession) {
Expand Down Expand Up @@ -999,7 +999,7 @@ public void invalidateUserScope(PageContextImpl pc, boolean migrateSessionData,

// For J2EE sessions, handle the servlet container's session (JSESSIONID)
if (isJ2EESession && hasSessionManagement) {
HttpSession httpSession = pc.getSession();
HttpSession httpSession = pc.getHttpServletRequest().getSession(false);
if (httpSession != null) {
if (migrateSessionData) {
// sessionRotate: rotate to a new session ID but keep session alive
Expand All @@ -1016,21 +1016,26 @@ public void invalidateUserScope(PageContextImpl pc, boolean migrateSessionData,
// For J2EE sessionRotate with a real httpSession (Tomcat), don't reset session - we already called
// changeSessionId() and want to keep the data
// But for JSR-223 (where httpSession is null), we need to reset to create a new session
HttpSession httpSessionForReset = pc.getSession();
HttpSession httpSessionForReset = pc.getHttpServletRequest().getSession(false);
if (!(isJ2EESession && migrateSessionData && httpSessionForReset != null)) {
pc.resetSession();
}
pc.resetClient();

if (oldSession != null) {
UserScope newSession;
if (isJ2EESession) {
newSession = getSessionScope(pc);
if (migrateSessionData) {
UserScope newSession;
if (isJ2EESession) {
newSession = getSessionScope(pc);
}
else {
newSession = (UserScope) getCFScope(pc, true, Scope.SCOPE_SESSION);
}
migrate(pc, oldSession, newSession, migrateSessionData);
}
else {
newSession = (UserScope) getCFScope(pc, true, Scope.SCOPE_SESSION);
oldSession.clear();
}
migrate(pc, oldSession, newSession, migrateSessionData);
}
if (oldClient != null) migrate(pc, oldClient, (UserScope) getCFScope(pc, true, Scope.SCOPE_CLIENT), migrateClientData);

Expand Down Expand Up @@ -1063,4 +1068,4 @@ else if (newScope instanceof JSession && oldScope instanceof JSession) {

}
}
}
}
19 changes: 0 additions & 19 deletions test/tickets/LDEV4166.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {

var appName = listFirst( trim( cfmlSessionId.filecontent ), '-' ) & "-" ;

// allow session to expire
expect( getSessionCount( appName ) ).toBe( 1 );

sleep(1001);
admin
action="purgeExpiredSessions"
type="server"
password="#request.SERVERADMINPASSWORD#";
//systemOutput(server.LDEV4166_ended_CFML_Sessions, true);
// let's check first that the session actually ended!
expect( getSessionCount( appName ) ).toBe( 0 );
expect( structKeyExists( server.LDEV4166_ended_CFML_Sessions, trim( cfmlSessionId.filecontent ) ) ).toBeTrue();
});
Expand All @@ -46,15 +36,6 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {

var appName = listFirst( trim( j2eeSessionId.filecontent ), '-' ) & "-" ;

expect( getSessionCount( appName ) ).toBe( 1 );
// allow session to expire
sleep(1001);
admin
action="purgeExpiredSessions"
type="server"
password="#request.SERVERADMINPASSWORD#";
//systemOutput(server.LDEV4166_ended_JEE_Sessions, true);
// let's check first that the session actually ended!
expect( getSessionCount( appName ) ).toBe( 0 );
expect( structKeyExists( server.LDEV4166_ended_JEE_Sessions, trim( j2eeSessionId.filecontent ) ) ).toBeTrue();
});
Expand Down
44 changes: 44 additions & 0 deletions test/tickets/LDEV6447.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {

function run( testResults, testBox ) {
describe( "LDEV-6447: sessionInvalidate() JEE session lifecycle", function() {
it( title="does not eagerly create a replacement JEE session", skip=isJsr223(), body=function( currentSpec ) {
var data = request( "invalidate-before-commit.cfm" );
expect( data.success ).toBeTrue( data.stacktrace ?: "no stacktrace" );
expect( data.oldSessionInvalidated ).toBeTrue( "The existing HttpSession should be invalidated" );
expect( data.replacementSessionExists ).toBeFalse( "sessionInvalidate() should not eagerly create a replacement HttpSession" );
expect( data.sessionCreatedAfterAccess ).toBeTrue( "Accessing SESSION should lazily create a new HttpSession" );
expect( data.oldSessionId ).notToBe( data.newSessionId, "The lazily-created session should have a new ID" );
});

it( title="invalidates an existing JEE session", skip=isJsr223(), body=function( currentSpec ) {
var data = request( "invalidate-after-commit.cfm" );
expect( data.success ).toBeTrue( data.stacktrace ?: "no stacktrace" );
expect( data.sessionInvalidated ).toBeTrue( "The existing HttpSession should be invalidated" );
});

it( title="is a no-op when no JEE session exists", skip=isJsr223(), body=function( currentSpec ) {
var data = request( "invalidate-after-commit-without-session.cfm" );
expect( data.success ).toBeTrue( data.stacktrace ?: "no stacktrace" );
});

});
}

private boolean function isJsr223() {
return cgi.request_url == "http://localhost/index.cfm";
}

private struct function request( required string template ) {
var hostIdx = find( cgi.script_name, cgi.request_url );
if ( hostIdx <= 0 ) {
throw "Failed to extract host from CGI values";
}

var result = "";
http method="get"
url="#left( cgi.request_url, hostIdx - 1 )#/test/tickets/LDEV6447/jee-session/#template#"
result="result";
return deserializeJSON( result.filecontent );
}
}
9 changes: 9 additions & 0 deletions test/tickets/LDEV6447/jee-session/Application.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
component {
this.name = "ldev6447_jee_session_invalidate";
this.sessionManagement = true;
this.sessionStorage = "memory";
this.sessionTimeout = createTimeSpan( 0, 0, 0, 30 );
this.setClientCookies = true;
this.applicationTimeout = createTimeSpan( 0, 0, 1, 0 );
this.sessionType = "jee";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<cfscript>
result = {
success: true,
stacktrace: ""
};

sessionInvalidate();
content type="application/json";
getPageContext().getResponse().flushBuffer();

try {
sessionInvalidate();
}
catch ( any e ) {
result.success = false;
result.stacktrace = e.stacktrace;
}

echo( serializeJSON( result ) );
</cfscript>
27 changes: 27 additions & 0 deletions test/tickets/LDEV6447/jee-session/invalidate-after-commit.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<cfscript>
result = {
success: true,
stacktrace: "",
sessionInvalidated: false
};

httpSession = getPageContext().getSession();
content type="application/json";
getPageContext().getResponse().flushBuffer();

try {
sessionInvalidate();
try {
httpSession.getAttribute( "test" );
}
catch ( any e ) {
result.sessionInvalidated = true;
}
}
catch ( any e ) {
result.success = false;
result.stacktrace = e.stacktrace;
}

echo( serializeJSON( result ) );
</cfscript>
36 changes: 36 additions & 0 deletions test/tickets/LDEV6447/jee-session/invalidate-before-commit.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<cfscript>
result = {
success: true,
stacktrace: "",
oldSessionInvalidated: false,
replacementSessionExists: true,
sessionCreatedAfterAccess: false,
oldSessionId: "",
newSessionId: ""
};

try {
httpSession = getPageContext().getSession();
result.oldSessionId = httpSession.getId();

sessionInvalidate();
result.replacementSessionExists = !isNull( getPageContext().getRequest().getSession( false ) );

try {
httpSession.getAttribute( "test" );
}
catch ( any e ) {
result.oldSessionInvalidated = true;
}

result.newSessionId = session.sessionid;
result.sessionCreatedAfterAccess = !isNull( getPageContext().getRequest().getSession( false ) );
}
catch ( any e ) {
result.success = false;
result.stacktrace = e.stacktrace;
}

content type="application/json";
echo( serializeJSON( result ) );
</cfscript>
Loading