Merge branch 'master' into release-9
This commit is contained in:
commit
018a51a04e
|
@ -43,12 +43,12 @@
|
|||
<td>
|
||||
<h2>information ...</h2>
|
||||
<ul>
|
||||
<li><a href="http://www.eclipse.org/jetty/">Jetty @ Eclipse Home</a></li>
|
||||
<li><a href="http://wiki.eclipse.org/Jetty">Jetty @ Eclipse Doco</a></li>
|
||||
<li><a href="http://www.eclipse.org/jetty/">Jetty Homepage</a></li>
|
||||
<li><a href="http://www.eclipse.org/jetty/documentation/current">Jetty Documentation</a></li>
|
||||
<li><a href="/proxy/apidocs/">Javadoc</a> (via transparent proxy)</li>
|
||||
<li><a href="/proxy/xref/">Xref</a> (via transparent proxy)</li>
|
||||
<li><a
|
||||
href="http://docs.codehaus.org/display/JETTY/Jetty+Powered">Jetty Powered</a></li>
|
||||
href="http://www.eclipse.org/jetty/powered">Jetty Powered</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
|
|
|
@ -142,6 +142,21 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
}
|
||||
}
|
||||
|
||||
public class OnDisconnectCallback implements WriteCallback
|
||||
{
|
||||
@Override
|
||||
public void writeFailed(Throwable x)
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSuccess()
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Stats
|
||||
{
|
||||
private AtomicLong countFillInterestedEvents = new AtomicLong(0);
|
||||
|
@ -233,6 +248,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
@Override
|
||||
public void disconnect()
|
||||
{
|
||||
LOG.debug("{} disconnect()", policy.getBehavior());
|
||||
synchronized (writeBytes)
|
||||
{
|
||||
if (!writeBytes.isClosed())
|
||||
|
@ -426,7 +442,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
@Override
|
||||
public void onConnectionStateChange(ConnectionState state)
|
||||
{
|
||||
LOG.debug("Connection State Change: {}",state);
|
||||
LOG.debug("{} Connection State Change: {}",policy.getBehavior(),state);
|
||||
switch (state)
|
||||
{
|
||||
case OPEN:
|
||||
|
@ -439,7 +455,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
case CLOSING:
|
||||
CloseInfo close = ioState.getCloseInfo();
|
||||
// append close frame
|
||||
outgoingFrame(close.asFrame(),null);
|
||||
outgoingFrame(close.asFrame(),new OnDisconnectCallback());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -182,11 +182,13 @@ public class IOState
|
|||
*/
|
||||
public void onCloseLocal(CloseInfo close)
|
||||
{
|
||||
LOG.debug("onCloseLocal({})",close);
|
||||
ConnectionState event = null;
|
||||
ConnectionState initialState = this.state;
|
||||
if (initialState == ConnectionState.CLOSED)
|
||||
{
|
||||
// already closed
|
||||
LOG.debug("already closed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -225,14 +227,18 @@ public class IOState
|
|||
}
|
||||
}
|
||||
|
||||
LOG.debug("event = {}",event);
|
||||
|
||||
// Only notify on state change events
|
||||
if (event != null)
|
||||
{
|
||||
LOG.debug("notifying state listeners: {}",event);
|
||||
notifyStateListeners(event);
|
||||
|
||||
// if SHUTDOWN, we don't expect an answer.
|
||||
if (close.getStatusCode() == StatusCode.SHUTDOWN)
|
||||
// if harsh, we don't expect an answer.
|
||||
if (close.isHarsh())
|
||||
{
|
||||
LOG.debug("Harsh close, disconnecting");
|
||||
synchronized (this.state)
|
||||
{
|
||||
this.state = ConnectionState.CLOSED;
|
||||
|
@ -253,6 +259,7 @@ public class IOState
|
|||
*/
|
||||
public void onCloseRemote(CloseInfo close)
|
||||
{
|
||||
LOG.debug("onCloseRemote({})",close);
|
||||
ConnectionState event = null;
|
||||
synchronized (this.state)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||
import org.eclipse.jetty.websocket.common.ConnectionState;
|
||||
import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
||||
|
||||
public class WebSocketServerConnection extends AbstractWebSocketConnection
|
||||
|
|
|
@ -23,8 +23,12 @@ import static org.hamcrest.Matchers.*;
|
|||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||
|
@ -69,7 +73,7 @@ public class IdleTimeoutTest
|
|||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
client.setProtocols("onConnect");
|
||||
client.setTimeout(TimeUnit.MILLISECONDS,1500);
|
||||
client.setTimeout(TimeUnit.MILLISECONDS,2500);
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
|
@ -83,13 +87,15 @@ public class IdleTimeoutTest
|
|||
// Write to server (the server should be timed out and disconnect now)
|
||||
client.write(WebSocketFrame.text("Hello"));
|
||||
|
||||
// now attempt to read 2 echoed frames from server (shouldn't work)
|
||||
client.readFrames(2,TimeUnit.MILLISECONDS,1500);
|
||||
Assert.fail("Should have resulted in IOException");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Assert.assertThat("IOException",e.getMessage(),anyOf(containsString("closed"),containsString("disconnected")));
|
||||
// now read 1 frame from server (should be close frame)
|
||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,1500);
|
||||
WebSocketFrame frame = capture.getFrames().poll();
|
||||
Assert.assertThat("Was close frame", frame.getOpCode(), is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("Close.code", close.getStatusCode(), is(StatusCode.SHUTDOWN));
|
||||
Assert.assertThat("Close.reason", close.getReason(), containsString("Idle Timeout"));
|
||||
|
||||
client.expectServerDisconnect();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -65,7 +65,9 @@ public class WebSocketOverSSLTest
|
|||
client.start();
|
||||
|
||||
CaptureSocket clientSocket = new CaptureSocket();
|
||||
Future<Session> fut = client.connect(clientSocket,server.getServerUri());
|
||||
URI requestUri = server.getServerUri();
|
||||
System.err.printf("Request URI: %s%n",requestUri.toASCIIString());
|
||||
Future<Session> fut = client.connect(clientSocket,requestUri);
|
||||
|
||||
// wait for connect
|
||||
Session session = fut.get(3,TimeUnit.SECONDS);
|
||||
|
|
|
@ -63,12 +63,17 @@ public class Fuzzer
|
|||
SLOW
|
||||
}
|
||||
|
||||
public static enum DisconnectMode
|
||||
{
|
||||
/** Disconnect occurred after a proper close handshake */
|
||||
CLEAN,
|
||||
/** Disconnect occurred in a harsh manner, without a close handshake */
|
||||
UNCLEAN
|
||||
}
|
||||
|
||||
private static final int KBYTE = 1024;
|
||||
private static final int MBYTE = KBYTE * KBYTE;
|
||||
|
||||
public static final boolean CLEAN_CLOSE = true;
|
||||
public static final boolean NOT_CLEAN_CLOSE = false;
|
||||
|
||||
private static final Logger LOG = Log.getLogger(Fuzzer.class);
|
||||
|
||||
// Client side framing mask
|
||||
|
@ -88,6 +93,7 @@ public class Fuzzer
|
|||
int bigMessageSize = 20 * MBYTE;
|
||||
|
||||
policy.setMaxMessageSize(bigMessageSize);
|
||||
policy.setIdleTimeout(5000);
|
||||
|
||||
this.client = new BlockheadClient(policy,testcase.getServer().getServerUri());
|
||||
this.generator = testcase.getLaxGenerator();
|
||||
|
@ -183,35 +189,21 @@ public class Fuzzer
|
|||
// TODO Should test for no more frames. success if connection closed.
|
||||
}
|
||||
|
||||
public void expectServerClose(boolean wasClean) throws IOException, InterruptedException
|
||||
public void expectServerDisconnect(DisconnectMode mode)
|
||||
{
|
||||
// we expect that the close handshake to have occurred and the server should have closed the connection
|
||||
try
|
||||
{
|
||||
ByteBuffer buf = ByteBuffer.wrap(new byte[]
|
||||
{ 0x00 });
|
||||
BufferUtil.flipToFill(buf);
|
||||
int len = client.read(buf);
|
||||
|
||||
Assert.assertThat("Server has not closed socket",len,lessThanOrEqualTo(0));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// valid path
|
||||
}
|
||||
|
||||
client.expectServerDisconnect();
|
||||
IOState ios = client.getIOState();
|
||||
|
||||
if (wasClean)
|
||||
switch (mode)
|
||||
{
|
||||
Assert.assertTrue(ios.wasRemoteCloseInitiated());
|
||||
Assert.assertTrue(ios.wasCleanClose());
|
||||
case CLEAN:
|
||||
Assert.assertTrue(ios.wasRemoteCloseInitiated());
|
||||
Assert.assertTrue(ios.wasCleanClose());
|
||||
break;
|
||||
case UNCLEAN:
|
||||
Assert.assertTrue(ios.wasRemoteCloseInitiated());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.assertTrue(ios.wasRemoteCloseInitiated());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CloseState getCloseState()
|
||||
|
@ -342,20 +334,6 @@ public class Fuzzer
|
|||
}
|
||||
}
|
||||
|
||||
public void sendExpectingIOException(ByteBuffer part3)
|
||||
{
|
||||
try
|
||||
{
|
||||
send(part3);
|
||||
Assert.fail("Expected a IOException on this send");
|
||||
}
|
||||
catch (IOException ignore)
|
||||
{
|
||||
// Send, but expect the send to fail with a IOException.
|
||||
// Usually, this is a SocketException("Socket Closed") condition.
|
||||
}
|
||||
}
|
||||
|
||||
private void setClientMask(WebSocketFrame f)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
|
|
|
@ -51,7 +51,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerClose(Fuzzer.CLEAN_CLOSE);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -83,6 +83,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -114,6 +115,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -145,6 +147,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -176,6 +179,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -207,6 +211,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -238,6 +243,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -275,6 +281,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSlowSendSegmentSize(segmentSize);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -303,6 +310,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -334,6 +342,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -365,6 +374,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -396,6 +406,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -427,6 +438,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -458,6 +470,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -489,6 +502,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -526,6 +540,7 @@ public class TestABCase1 extends AbstractABCase
|
|||
fuzzer.setSlowSendSegmentSize(segmentSize);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
|
||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
|
@ -236,32 +237,32 @@ public class TestABCase2 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase2_5() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
byte payload[] = new byte[126]; // intentionally too big
|
||||
Arrays.fill(payload,(byte)'5');
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
// trick websocket frame into making extra large payload for ping
|
||||
send.add(WebSocketFrame.binary(payload).setOpCode(OpCode.PING));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL,"Test 2.5").asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
try(StacklessLogging scope = new StacklessLogging(Parser.class))
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
byte payload[] = new byte[126]; // intentionally too big
|
||||
Arrays.fill(payload,(byte)'5');
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
// trick websocket frame into making extra large payload for ping
|
||||
send.add(WebSocketFrame.binary(payload).setOpCode(OpCode.PING));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL,"Test 2.5").asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
|
@ -358,54 +359,55 @@ public class TestABCase6 extends AbstractABCase
|
|||
public void testCase6_4_3() throws Exception
|
||||
{
|
||||
// Disable Long Stacks from Parser (we know this test will throw an exception)
|
||||
enableStacks(Parser.class,false);
|
||||
|
||||
ByteBuffer payload = ByteBuffer.allocate(64);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.put(TypeUtil.fromHexString("cebae1bdb9cf83cebcceb5")); // good
|
||||
payload.put(TypeUtil.fromHexString("f4908080")); // INVALID
|
||||
payload.put(TypeUtil.fromHexString("656469746564")); // good
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
try(StacklessLogging scope = new StacklessLogging(Parser.class))
|
||||
{
|
||||
fuzzer.connect();
|
||||
ByteBuffer payload = ByteBuffer.allocate(64);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.put(TypeUtil.fromHexString("cebae1bdb9cf83cebcceb5")); // good
|
||||
payload.put(TypeUtil.fromHexString("f4908080")); // INVALID
|
||||
payload.put(TypeUtil.fromHexString("656469746564")); // good
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
ByteBuffer net = fuzzer.asNetworkBuffer(send);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
int splits[] =
|
||||
{ 17, 21, net.limit() };
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
|
||||
|
||||
ByteBuffer part1 = net.slice(); // Header + good UTF
|
||||
part1.limit(splits[0]);
|
||||
ByteBuffer part2 = net.slice(); // invalid UTF
|
||||
part2.position(splits[0]);
|
||||
part2.limit(splits[1]);
|
||||
ByteBuffer part3 = net.slice(); // good UTF
|
||||
part3.position(splits[1]);
|
||||
part3.limit(splits[2]);
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
|
||||
fuzzer.send(part1); // the header + good utf
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
fuzzer.send(part2); // the bad UTF
|
||||
ByteBuffer net = fuzzer.asNetworkBuffer(send);
|
||||
|
||||
fuzzer.expect(expect);
|
||||
int splits[] =
|
||||
{ 17, 21, net.limit() };
|
||||
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
fuzzer.sendExpectingIOException(part3); // the rest (shouldn't work)
|
||||
}
|
||||
finally
|
||||
{
|
||||
enableStacks(Parser.class,true);
|
||||
fuzzer.close();
|
||||
ByteBuffer part1 = net.slice(); // Header + good UTF
|
||||
part1.limit(splits[0]);
|
||||
ByteBuffer part2 = net.slice(); // invalid UTF
|
||||
part2.position(splits[0]);
|
||||
part2.limit(splits[1]);
|
||||
ByteBuffer part3 = net.slice(); // good UTF
|
||||
part3.position(splits[1]);
|
||||
part3.limit(splits[2]);
|
||||
|
||||
fuzzer.send(part1); // the header + good utf
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
fuzzer.send(part2); // the bad UTF
|
||||
|
||||
fuzzer.expect(expect);
|
||||
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
fuzzer.send(part3); // the rest (shouldn't work)
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.UNCLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ public class TestABCase6_BadUTF extends AbstractABCase
|
|||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectServerClose(Fuzzer.NOT_CLEAN_CLOSE);
|
||||
fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.UNCLEAN);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.net.InetAddress;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -125,10 +126,8 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames, Connecti
|
|||
{
|
||||
Assert.assertThat("Websocket URI scheme",destWebsocketURI.getScheme(),anyOf(is("ws"),is("wss")));
|
||||
this.destWebsocketURI = destWebsocketURI;
|
||||
String scheme = "http";
|
||||
if (destWebsocketURI.getScheme().equals("wss"))
|
||||
{
|
||||
scheme = "https";
|
||||
throw new RuntimeException("Sorry, BlockheadClient does not support SSL");
|
||||
}
|
||||
this.destHttpURI = WSURI.toHttp(destWebsocketURI);
|
||||
|
@ -415,7 +414,8 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames, Connecti
|
|||
switch (state)
|
||||
{
|
||||
case CLOSED:
|
||||
this.disconnect();
|
||||
// Per Spec, client should not initiate disconnect on its own
|
||||
// this.disconnect();
|
||||
break;
|
||||
case CLOSING:
|
||||
if (ioState.wasRemoteCloseInitiated())
|
||||
|
@ -465,6 +465,36 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames, Connecti
|
|||
}
|
||||
}
|
||||
|
||||
public void expectServerDisconnect()
|
||||
{
|
||||
if (eof)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int len = in.read();
|
||||
if (len == (-1))
|
||||
{
|
||||
// we are disconnected
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.assertThat("Expecting no data and proper socket disconnect (issued from server)",len,is(-1));
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
Assert.fail("Expected a server initiated disconnect, instead the read timed out");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// acceptable path
|
||||
}
|
||||
}
|
||||
|
||||
public int read(ByteBuffer buf) throws IOException
|
||||
{
|
||||
if (eof)
|
||||
|
|
Loading…
Reference in New Issue