Skip to content

Commit

Permalink
fix: reset HTTP session on CLOSED state, not immidiately (#11377)
Browse files Browse the repository at this point in the history
fixes #6959
  • Loading branch information
Denis committed Jul 6, 2021
1 parent 813dd86 commit 7e89dfe
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ && getCurrent() == this) {
// it as soon as we acquire the lock.
service.fireSessionDestroy(this);
}
session = null;
}

/**
Expand Down Expand Up @@ -887,6 +886,10 @@ assert isValidChange(state) : "Invalid session state change "
+ this.state + "->" + state;

this.state = state;

if (VaadinSessionState.CLOSED.equals(state)) {
session = null;
}
}

private boolean isValidChange(VaadinSessionState newState) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -162,6 +163,24 @@ public void testFireSessionDestroy()
1, listener.callCount);
}

@Test
public void fireSessionDestroy_sessionStateIsSetToClosed()
throws ServletException, ServiceException {
VaadinService service = createService();

AtomicReference<VaadinSessionState> stateRef = new AtomicReference<>();
MockVaadinSession vaadinSession = new MockVaadinSession(service) {
@Override
protected void setState(VaadinSessionState state) {
stateRef.set(state);
}
};

service.fireSessionDestroy(vaadinSession);

Assert.assertEquals(VaadinSessionState.CLOSED, stateRef.get());
}

@Test
public void captionIsSetToACriticalNotification() {
String notification = createCriticalNotification("foobar", "message",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,55 @@ public void csrfToken_same_session_shouldBeSame() {
"getCsrfToken() should always return the same value for the same session",
token1, token2);
}

@Test
public void valueUnbound_wrappedSessionIsNotCleanedUp() {
ReentrantLock lock = Mockito.mock(ReentrantLock.class);
Mockito.when(lock.isHeldByCurrentThread()).thenReturn(true);
mockService = new MockVaadinServletService() {
@Override
protected Lock getSessionLock(WrappedSession wrappedSession) {
return lock;
}
};

VaadinSession vaadinSession = new VaadinSession(mockService);

WrappedSession httpSession = Mockito.mock(WrappedSession.class);
vaadinSession.refreshTransients(httpSession, mockService);

VaadinSession.setCurrent(vaadinSession);
mockService.setCurrentInstances(Mockito.mock(VaadinRequest.class),
Mockito.mock(VaadinResponse.class));

try {
vaadinSession
.valueUnbound(Mockito.mock(HttpSessionBindingEvent.class));

Assert.assertNotNull(vaadinSession.getSession());
} finally {
CurrentInstance.clearAll();
}
}

@Test
public void setState_closedState_sessionAttributeIsCleanedUp() {
ReentrantLock lock = Mockito.mock(ReentrantLock.class);
Mockito.when(lock.isHeldByCurrentThread()).thenReturn(true);
mockService = new MockVaadinServletService() {
@Override
protected Lock getSessionLock(WrappedSession wrappedSession) {
return lock;
}
};

VaadinSession vaadinSession = new VaadinSession(mockService);
WrappedSession httpSession = Mockito.mock(WrappedSession.class);
vaadinSession.refreshTransients(httpSession, mockService);

vaadinSession.setState(VaadinSessionState.CLOSING);
vaadinSession.setState(VaadinSessionState.CLOSED);

Assert.assertNull(vaadinSession.getSession());
}
}

0 comments on commit 7e89dfe

Please sign in to comment.