add in some handshake state tracking into IOState to help track who initiated closes

This commit is contained in:
Jesse McConnell 2012-12-13 12:15:47 -06:00
parent 127f4978a9
commit bf3c5c7922
3 changed files with 90 additions and 3 deletions

View File

@ -36,11 +36,18 @@ public class IOState
private final AtomicBoolean inputClosed;
private final AtomicBoolean outputClosed;
private final AtomicBoolean cleanClose;
private final AtomicBoolean remoteCloseInitiated;
private final AtomicBoolean localCloseInitiated;
public IOState()
{
this.state = ConnectionState.CONNECTING;
this.inputClosed = new AtomicBoolean(false);
this.outputClosed = new AtomicBoolean(false);
this.remoteCloseInitiated = new AtomicBoolean(false);
this.localCloseInitiated = new AtomicBoolean(false);
this.cleanClose = new AtomicBoolean(false);
}
public void assertInputOpen() throws IOException
@ -111,11 +118,21 @@ public class IOState
{
in = true;
this.inputClosed.set(true);
if (!localCloseInitiated.get())
{
remoteCloseInitiated.set(true);
}
}
else
{
out = true;
this.outputClosed.set(true);
if ( !remoteCloseInitiated.get() )
{
localCloseInitiated.set(true);
}
}
LOG.debug("onCloseHandshake({},{}), input={}, output={}",incoming,close,in,out);
@ -123,6 +140,7 @@ public class IOState
if (in && out)
{
LOG.debug("Close Handshake satisfied, disconnecting");
cleanClose.set(true);
return true;
}
@ -144,4 +162,24 @@ public class IOState
{
this.state = state;
}
public boolean isCloseInitiated()
{
return remoteCloseInitiated.get() || localCloseInitiated.get();
}
public boolean wasRemoteCloseInitiated()
{
return remoteCloseInitiated.get();
}
public boolean wasLocalCloseInitiated()
{
return localCloseInitiated.get();
}
public boolean wasCleanClose()
{
return cleanClose.get();
}
}

View File

@ -38,6 +38,7 @@ import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.Generator;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.io.IOState;
import org.eclipse.jetty.websocket.server.ByteBufferAssert;
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
@ -55,6 +56,13 @@ public class Fuzzer
SLOW
}
public static enum CloseState
{
OPEN,
REMOTE_INITIATED,
LOCAL_INITIATED
}
private static final int KBYTE = 1024;
private static final int MBYTE = KBYTE * KBYTE;
@ -178,7 +186,30 @@ public class Fuzzer
public void expectServerClose(boolean wasClean) throws IOException, InterruptedException
{
// DOES NOT WORK -- Assert.assertThat("Should have disconnected",client.awaitDisconnect(2,TimeUnit.SECONDS),is(true));
// we expect that the close handshake to have occurred and the server should have closed the connection
try
{
int val = client.read();
Assert.fail("Server has not closed socket");
}
catch (SocketException e)
{
}
IOState ios = client.getIOState();
if (wasClean)
{
Assert.assertTrue(ios.wasRemoteCloseInitiated());
Assert.assertTrue(ios.wasCleanClose());
}
else
{
Assert.assertTrue(ios.wasRemoteCloseInitiated());
}
}
public SendMode getSendMode()
@ -327,4 +358,22 @@ public class Fuzzer
{
this.slowSendSegmentSize = segmentSize;
}
public CloseState getCloseState()
{
IOState ios = client.getIOState();
if ( ios.wasLocalCloseInitiated() )
{
return CloseState.LOCAL_INITIATED;
}
else if ( ios.wasRemoteCloseInitiated() )
{
return CloseState.REMOTE_INITIATED;
}
else
{
return CloseState.OPEN;
}
}
}

View File

@ -116,7 +116,7 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames
private ExtensionStack extensionStack;
private IOState ioState;
private CountDownLatch disconnectedLatch = new CountDownLatch(1);
public BlockheadClient(URI destWebsocketURI) throws URISyntaxException
{
this(WebSocketPolicy.newClientPolicy(),destWebsocketURI);
@ -173,7 +173,7 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames
public void close(int statusCode, String message)
{
try
{
{
CloseInfo close = new CloseInfo(statusCode,message);
if (ioState.onCloseHandshake(false,close))