Issue #3734 - throw ISE for WebSocket suspend after close (jetty-9.4) (#4098)

* Issue #3734 - throw ISE for WebSocket suspend after close

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>

* Issue #3734 - suspend is error if onClose() has been called

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan 2019-09-25 14:55:13 +10:00 committed by GitHub
parent 11b60db4c3
commit 3edc6c9102
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 21 deletions

View File

@ -41,6 +41,7 @@ import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
public class SuspendResumeTest public class SuspendResumeTest
@ -195,8 +196,7 @@ public class SuspendResumeTest
assertThat(clientSocket.closeCode, is(StatusCode.NORMAL)); assertThat(clientSocket.closeCode, is(StatusCode.NORMAL));
assertThat(serverSocket.closeCode, is(StatusCode.NORMAL)); assertThat(serverSocket.closeCode, is(StatusCode.NORMAL));
// suspend the client so that no read events occur // suspend after closed throws ISE
SuspendToken suspendToken = clientSocket.session.suspend(); assertThrows(IllegalStateException.class, () -> clientSocket.session.suspend());
suspendToken.resume();
} }
} }

View File

@ -68,7 +68,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
private final EventDriver websocket; private final EventDriver websocket;
private final Executor executor; private final Executor executor;
private final WebSocketPolicy policy; private final WebSocketPolicy policy;
private final AtomicBoolean closed = new AtomicBoolean(); private final AtomicBoolean onCloseCalled = new AtomicBoolean(false);
private ClassLoader classLoader; private ClassLoader classLoader;
private ExtensionFactory extensionFactory; private ExtensionFactory extensionFactory;
private RemoteEndpointFactory remoteEndpointFactory; private RemoteEndpointFactory remoteEndpointFactory;
@ -80,7 +80,6 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
private UpgradeRequest upgradeRequest; private UpgradeRequest upgradeRequest;
private UpgradeResponse upgradeResponse; private UpgradeResponse upgradeResponse;
private CompletableFuture<Session> openFuture; private CompletableFuture<Session> openFuture;
private AtomicBoolean onCloseCalled = new AtomicBoolean(false);
public WebSocketSession(WebSocketContainerScope containerScope, URI requestURI, EventDriver websocket, LogicalConnection connection) public WebSocketSession(WebSocketContainerScope containerScope, URI requestURI, EventDriver websocket, LogicalConnection connection)
{ {
@ -338,10 +337,9 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
public boolean isOpen() public boolean isOpen()
{ {
if (this.connection == null) if (this.connection == null)
{
return false; return false;
}
return !closed.get() && this.connection.isOpen(); return !onCloseCalled.get() && this.connection.isOpen();
} }
@Override @Override
@ -546,6 +544,9 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
@Override @Override
public SuspendToken suspend() public SuspendToken suspend()
{ {
if (onCloseCalled.get())
throw new IllegalStateException("Not open");
return connection.suspend(); return connection.suspend();
} }

View File

@ -87,10 +87,8 @@ class ReadState
/** /**
* Requests that reads from the connection be suspended. * Requests that reads from the connection be suspended.
*
* @return whether the suspending was successful
*/ */
boolean suspending() void suspending()
{ {
synchronized (this) synchronized (this)
{ {
@ -101,9 +99,7 @@ class ReadState
{ {
case READING: case READING:
state = State.SUSPENDING; state = State.SUSPENDING;
return true; break;
case EOF:
return false;
default: default:
throw new IllegalStateException(toString(state)); throw new IllegalStateException(toString(state));
} }
@ -131,8 +127,6 @@ class ReadState
ByteBuffer bb = buffer; ByteBuffer bb = buffer;
buffer = null; buffer = null;
return bb; return bb;
case EOF:
return null;
default: default:
throw new IllegalStateException(toString(state)); throw new IllegalStateException(toString(state));
} }

View File

@ -27,7 +27,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ReadStateTest public class ReadStateTest
{ {
@ -50,7 +49,7 @@ public class ReadStateTest
ReadState readState = new ReadState(); ReadState readState = new ReadState();
assertThat("Initially reading", readState.isReading(), is(true)); assertThat("Initially reading", readState.isReading(), is(true));
assertTrue(readState.suspending()); readState.suspending();
assertThat("Suspending doesn't take effect immediately", readState.isSuspended(), is(false)); assertThat("Suspending doesn't take effect immediately", readState.isSuspended(), is(false));
assertNull(readState.resume()); assertNull(readState.resume());
@ -64,7 +63,7 @@ public class ReadStateTest
ReadState readState = new ReadState(); ReadState readState = new ReadState();
assertThat("Initially reading", readState.isReading(), is(true)); assertThat("Initially reading", readState.isReading(), is(true));
assertThat(readState.suspending(), is(true)); readState.suspending();
assertThat("Suspending doesn't take effect immediately", readState.isSuspended(), is(false)); assertThat("Suspending doesn't take effect immediately", readState.isSuspended(), is(false));
ByteBuffer content = BufferUtil.toBuffer("content"); ByteBuffer content = BufferUtil.toBuffer("content");
@ -84,8 +83,8 @@ public class ReadStateTest
assertThat(readState.isReading(), is(false)); assertThat(readState.isReading(), is(false));
assertThat(readState.isSuspended(), is(true)); assertThat(readState.isSuspended(), is(true));
assertThat(readState.suspending(), is(false)); assertThrows(IllegalStateException.class, readState::suspending);
assertThat(readState.getAction(content), is(ReadState.Action.EOF)); assertThat(readState.getAction(content), is(ReadState.Action.EOF));
assertNull(readState.resume()); assertThrows(IllegalStateException.class, readState::resume);
} }
} }