* 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:
parent
11b60db4c3
commit
3edc6c9102
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue