More AB testing, reworked for Fuzzer
This commit is contained in:
parent
9a34c08b8e
commit
9a568514a6
|
@ -54,16 +54,19 @@ public class Parser
|
|||
private ByteBuffer payload;
|
||||
private int payloadLength;
|
||||
|
||||
/** Is there an extension using RSV1 */
|
||||
private boolean rsv1InUse = false;
|
||||
/** Is there an extension using RSV2 */
|
||||
private boolean rsv2InUse = false;
|
||||
/** Is there an extension using RSV3 */
|
||||
private boolean rsv3InUse = false;
|
||||
|
||||
private static final Logger LOG = Log.getLogger(Parser.class);
|
||||
private IncomingFrames incomingFramesHandler;
|
||||
private WebSocketPolicy policy;
|
||||
|
||||
public Parser(WebSocketPolicy wspolicy)
|
||||
{
|
||||
/*
|
||||
* TODO: Investigate addition of decompression factory similar to SPDY work in situation of negotiated deflate extension?
|
||||
*/
|
||||
|
||||
this.policy = wspolicy;
|
||||
}
|
||||
|
||||
|
@ -107,6 +110,21 @@ public class Parser
|
|||
return policy;
|
||||
}
|
||||
|
||||
public boolean isRsv1InUse()
|
||||
{
|
||||
return rsv1InUse;
|
||||
}
|
||||
|
||||
public boolean isRsv2InUse()
|
||||
{
|
||||
return rsv2InUse;
|
||||
}
|
||||
|
||||
public boolean isRsv3InUse()
|
||||
{
|
||||
return rsv3InUse;
|
||||
}
|
||||
|
||||
protected void notifyFrame(final WebSocketFrame f)
|
||||
{
|
||||
if (LOG_FRAMES.isDebugEnabled())
|
||||
|
@ -228,6 +246,27 @@ public class Parser
|
|||
|
||||
LOG.debug("OpCode {}, fin={}",opcode.name(),fin);
|
||||
|
||||
/*
|
||||
* RFC 6455 Section 5.2
|
||||
*
|
||||
* MUST be 0 unless an extension is negotiated that defines meanings for non-zero values. If a nonzero value is received and none of the
|
||||
* negotiated extensions defines the meaning of such a nonzero value, the receiving endpoint MUST _Fail the WebSocket Connection_.
|
||||
*/
|
||||
if (!rsv1InUse && rsv1)
|
||||
{
|
||||
throw new ProtocolException("RSV1 not allowed to be set");
|
||||
}
|
||||
|
||||
if (!rsv2InUse && rsv2)
|
||||
{
|
||||
throw new ProtocolException("RSV2 not allowed to be set");
|
||||
}
|
||||
|
||||
if (!rsv3InUse && rsv3)
|
||||
{
|
||||
throw new ProtocolException("RSV3 not allowed to be set");
|
||||
}
|
||||
|
||||
if (opcode.isControlFrame() && !fin)
|
||||
{
|
||||
throw new ProtocolException("Fragmented Control Frame [" + opcode.name() + "]");
|
||||
|
@ -442,6 +481,21 @@ public class Parser
|
|||
this.incomingFramesHandler = incoming;
|
||||
}
|
||||
|
||||
public void setRsv1InUse(boolean rsv1InUse)
|
||||
{
|
||||
this.rsv1InUse = rsv1InUse;
|
||||
}
|
||||
|
||||
public void setRsv2InUse(boolean rsv2InUse)
|
||||
{
|
||||
this.rsv2InUse = rsv2InUse;
|
||||
}
|
||||
|
||||
public void setRsv3InUse(boolean rsv3InUse)
|
||||
{
|
||||
this.rsv3InUse = rsv3InUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -388,14 +388,17 @@ public class WebSocketServerFactory extends AbstractLifeCycle implements WebSock
|
|||
if (ext.useRsv1())
|
||||
{
|
||||
connection.getGenerator().setRsv1InUse(true);
|
||||
connection.getParser().setRsv1InUse(true);
|
||||
}
|
||||
if (ext.useRsv2())
|
||||
{
|
||||
connection.getGenerator().setRsv2InUse(true);
|
||||
connection.getParser().setRsv2InUse(true);
|
||||
}
|
||||
if (ext.useRsv3())
|
||||
{
|
||||
connection.getGenerator().setRsv3InUse(true);
|
||||
connection.getParser().setRsv3InUse(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,11 @@ public class ByteBufferAssert
|
|||
|
||||
public static void assertEquals(String message, ByteBuffer expectedBuffer, ByteBuffer actualBuffer)
|
||||
{
|
||||
if (expectedBuffer == null)
|
||||
{
|
||||
Assert.assertThat(message,actualBuffer,nullValue());
|
||||
return;
|
||||
}
|
||||
byte expectedBytes[] = BufferUtil.toArray(expectedBuffer);
|
||||
byte actualBytes[] = BufferUtil.toArray(actualBuffer);
|
||||
assertEquals(message,expectedBytes,actualBytes);
|
||||
|
|
|
@ -44,6 +44,16 @@ public abstract class AbstractABCase
|
|||
server.stop();
|
||||
}
|
||||
|
||||
public Generator getLaxGenerator()
|
||||
{
|
||||
return laxGenerator;
|
||||
}
|
||||
|
||||
public SimpleServletServer getServer()
|
||||
{
|
||||
return server;
|
||||
}
|
||||
|
||||
protected byte[] masked(final byte[] data)
|
||||
{
|
||||
int len = data.length;
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.junit.runners.Suite;
|
|||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses(
|
||||
{ TestABCase1.class, TestABCase5.class, TestABCase7_9.class })
|
||||
{ TestABCase1.class, TestABCase2.class, TestABCase3.class, TestABCase5.class, TestABCase7_9.class })
|
||||
public class AllTests
|
||||
{
|
||||
/* let junit do the rest */
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.protocol.Generator;
|
||||
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.ByteBufferAssert;
|
||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Fuzzing utility for the AB tests.
|
||||
*/
|
||||
public class Fuzzer
|
||||
{
|
||||
public static enum SendMode
|
||||
{
|
||||
BULK,
|
||||
PER_FRAME,
|
||||
SLOW
|
||||
}
|
||||
|
||||
private static final Logger LOG = Log.getLogger(Fuzzer.class);
|
||||
|
||||
// Client side framing mask
|
||||
protected static final byte[] MASK =
|
||||
{ 0x11, 0x22, 0x33, 0x44 };
|
||||
|
||||
private final BlockheadClient client;
|
||||
private final Generator generator;
|
||||
private SendMode sendMode = SendMode.BULK;
|
||||
private int slowSendSegmentSize = 5;
|
||||
|
||||
public Fuzzer(AbstractABCase testcase) throws Exception
|
||||
{
|
||||
this.client = new BlockheadClient(testcase.getServer().getServerUri());
|
||||
this.generator = testcase.getLaxGenerator();
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
this.client.disconnect();
|
||||
}
|
||||
|
||||
public void connect() throws IOException
|
||||
{
|
||||
if (!client.isConnected())
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
}
|
||||
}
|
||||
|
||||
public void expect(List<WebSocketFrame> expect) throws IOException, TimeoutException
|
||||
{
|
||||
int expectedCount = expect.size();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(expect.size(),TimeUnit.MILLISECONDS,500);
|
||||
|
||||
String prefix = "";
|
||||
for (int i = 0; i < expectedCount; i++)
|
||||
{
|
||||
WebSocketFrame expected = expect.get(i);
|
||||
WebSocketFrame actual = capture.getFrames().pop();
|
||||
|
||||
prefix = "Frame[" + i + "]";
|
||||
|
||||
Assert.assertThat(prefix + ".opcode",actual.getOpCode(),is(expected.getOpCode()));
|
||||
prefix += "/" + actual.getOpCode();
|
||||
if (expected.getOpCode() == OpCode.CLOSE)
|
||||
{
|
||||
CloseInfo expectedClose = new CloseInfo(expected);
|
||||
CloseInfo actualClose = new CloseInfo(actual);
|
||||
Assert.assertThat(prefix + ".statusCode",actualClose.getStatusCode(),is(expectedClose.getStatusCode()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.assertThat(prefix + ".payloadLength",actual.getPayloadLength(),is(expected.getPayloadLength()));
|
||||
ByteBufferAssert.assertEquals(prefix + ".payload",expected.getPayload(),actual.getPayload());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void expect(WebSocketFrame expect) throws IOException, TimeoutException
|
||||
{
|
||||
expect(Collections.singletonList(expect));
|
||||
}
|
||||
|
||||
public SendMode getSendMode()
|
||||
{
|
||||
return sendMode;
|
||||
}
|
||||
|
||||
public int getSlowSendSegmentSize()
|
||||
{
|
||||
return slowSendSegmentSize;
|
||||
}
|
||||
|
||||
public void send(List<WebSocketFrame> send) throws IOException
|
||||
{
|
||||
Assert.assertThat("Client connected",client.isConnected(),is(true));
|
||||
LOG.debug("Sending {} frames (mode {})",send.size(),sendMode);
|
||||
if ((sendMode == SendMode.BULK) || (sendMode == SendMode.SLOW))
|
||||
{
|
||||
int buflen = 0;
|
||||
for (WebSocketFrame f : send)
|
||||
{
|
||||
buflen += f.getPayloadLength() + Generator.OVERHEAD;
|
||||
}
|
||||
ByteBuffer buf = ByteBuffer.allocate(buflen);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Generate frames
|
||||
for (WebSocketFrame f : send)
|
||||
{
|
||||
f.setMask(MASK); // make sure we have mask set
|
||||
BufferUtil.put(generator.generate(f),buf);
|
||||
}
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
|
||||
// Write Data Frame
|
||||
switch (sendMode)
|
||||
{
|
||||
case BULK:
|
||||
client.writeRaw(buf);
|
||||
break;
|
||||
case SLOW:
|
||||
client.writeRawSlowly(buf,slowSendSegmentSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (sendMode == SendMode.PER_FRAME)
|
||||
{
|
||||
for (WebSocketFrame f : send)
|
||||
{
|
||||
// Using lax generator, generate and send
|
||||
client.writeRaw(generator.generate(f));
|
||||
client.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void send(WebSocketFrame send) throws IOException
|
||||
{
|
||||
send(Collections.singletonList(send));
|
||||
}
|
||||
|
||||
public void setSendMode(SendMode sendMode)
|
||||
{
|
||||
this.sendMode = sendMode;
|
||||
}
|
||||
|
||||
public void setSlowSendSegmentSize(int segmentSize)
|
||||
{
|
||||
this.slowSendSegmentSize = segmentSize;
|
||||
}
|
||||
}
|
|
@ -15,201 +15,44 @@
|
|||
//========================================================================
|
||||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.protocol.Generator;
|
||||
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.ByteBufferAssert;
|
||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||
import org.junit.Assert;
|
||||
import org.eclipse.jetty.websocket.server.ab.Fuzzer.SendMode;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestABCase1 extends AbstractABCase
|
||||
{
|
||||
private void assertEchoEmptyFrame(OpCode opcode) throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare Frame
|
||||
buf.put((byte)(0x00 | FIN | opcode.getCode()));
|
||||
putPayloadLength(buf,0);
|
||||
putMask(buf);
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Prepare Close Frame
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL);
|
||||
buf = strictGenerator.generate(close.asFrame());
|
||||
|
||||
// Write Close Frame
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(2,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate echo'd frame
|
||||
WebSocketFrame frame = capture.getFrames().get(0);
|
||||
Assert.assertThat("frame should be " + opcode + " frame",frame.getOpCode(),is(opcode));
|
||||
Assert.assertThat(opcode + ".payloadLength",frame.getPayloadLength(),is(0));
|
||||
|
||||
// Validate close
|
||||
frame = capture.getFrames().get(1);
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertEchoFrame(OpCode opcode, byte[] payload) throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(payload.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare Frame
|
||||
buf.put((byte)(0x00 | FIN | opcode.getCode()));
|
||||
putPayloadLength(buf,payload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(payload));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Prepare Close Frame
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL);
|
||||
WebSocketFrame closeFrame = close.asFrame();
|
||||
closeFrame.setMask(MASK);
|
||||
buf = strictGenerator.generate(closeFrame);
|
||||
|
||||
// Write Close Frame
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(2,TimeUnit.MILLISECONDS,1000);
|
||||
|
||||
// Validate echo'd frame
|
||||
WebSocketFrame frame = capture.getFrames().get(0);
|
||||
Assert.assertThat("frame should be " + opcode + " frame",frame.getOpCode(),is(opcode));
|
||||
Assert.assertThat(opcode + ".payloadLength",frame.getPayloadLength(),is(payload.length));
|
||||
ByteBufferAssert.assertEquals(opcode + ".payload",payload,frame.getPayload());
|
||||
|
||||
// Validate close
|
||||
frame = capture.getFrames().get(1);
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertEchoSegmentedFrame(OpCode opcode, byte payload[], int segmentSize) throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(payload.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare Frame
|
||||
buf.put((byte)(0x00 | FIN | opcode.getCode()));
|
||||
putPayloadLength(buf,payload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(payload));
|
||||
|
||||
// Write frame, in small blocks of segmentSize
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
int origLimit = buf.limit();
|
||||
int limit = buf.limit();
|
||||
int len;
|
||||
int pos = buf.position();
|
||||
int overallLeft = buf.remaining();
|
||||
while (overallLeft > 0)
|
||||
{
|
||||
buf.position(pos);
|
||||
limit = Math.min(origLimit,pos + segmentSize);
|
||||
buf.limit(limit);
|
||||
len = buf.remaining();
|
||||
overallLeft -= len;
|
||||
pos += len;
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
}
|
||||
|
||||
// Prepare Close Frame
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL);
|
||||
buf = strictGenerator.generate(close.asFrame());
|
||||
|
||||
// Write Close Frame
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(2,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate echo'd frame
|
||||
WebSocketFrame frame = capture.getFrames().get(0);
|
||||
Assert.assertThat("frame should be " + opcode + " frame",frame.getOpCode(),is(opcode));
|
||||
Assert.assertThat(opcode + ".payloadLength",frame.getPayloadLength(),is(payload.length));
|
||||
ByteBufferAssert.assertEquals(opcode + ".payload",payload,frame.getPayload());
|
||||
|
||||
// Validate close
|
||||
frame = capture.getFrames().get(1);
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 0 byte TEXT message
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_1() throws Exception
|
||||
{
|
||||
assertEchoEmptyFrame(OpCode.TEXT);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text());
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text());
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,7 +64,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[125];
|
||||
Arrays.fill(payload,(byte)'*');
|
||||
|
||||
assertEchoFrame(OpCode.TEXT,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,7 +95,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[126];
|
||||
Arrays.fill(payload,(byte)'*');
|
||||
|
||||
assertEchoFrame(OpCode.TEXT,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +126,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[127];
|
||||
Arrays.fill(payload,(byte)'*');
|
||||
|
||||
assertEchoFrame(OpCode.TEXT,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +157,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[128];
|
||||
Arrays.fill(payload,(byte)'*');
|
||||
|
||||
assertEchoFrame(OpCode.TEXT,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,7 +188,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[65535];
|
||||
Arrays.fill(payload,(byte)'*');
|
||||
|
||||
assertEchoFrame(OpCode.TEXT,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -281,7 +219,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[65536];
|
||||
Arrays.fill(payload,(byte)'*');
|
||||
|
||||
assertEchoFrame(OpCode.TEXT,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,7 +255,27 @@ public class TestABCase1 extends AbstractABCase
|
|||
Arrays.fill(payload,(byte)'*');
|
||||
int segmentSize = 997;
|
||||
|
||||
assertEchoSegmentedFrame(OpCode.TEXT,payload,segmentSize);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.SLOW);
|
||||
fuzzer.setSlowSendSegmentSize(segmentSize);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,7 +284,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase1_2_1() throws Exception
|
||||
{
|
||||
assertEchoEmptyFrame(OpCode.BINARY);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary());
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary());
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -319,7 +315,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[125];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
|
||||
assertEchoFrame(OpCode.BINARY,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,7 +346,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[126];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
|
||||
assertEchoFrame(OpCode.BINARY,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,7 +377,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[127];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
|
||||
assertEchoFrame(OpCode.BINARY,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,7 +408,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[128];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
|
||||
assertEchoFrame(OpCode.BINARY,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -367,7 +439,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[65535];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
|
||||
assertEchoFrame(OpCode.BINARY,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -379,7 +470,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
byte payload[] = new byte[65536];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
|
||||
assertEchoFrame(OpCode.BINARY,payload);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -396,6 +506,26 @@ public class TestABCase1 extends AbstractABCase
|
|||
Arrays.fill(payload,(byte)0xFE);
|
||||
int segmentSize = 997;
|
||||
|
||||
assertEchoSegmentedFrame(OpCode.BINARY,payload,segmentSize);
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.binary().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(SendMode.SLOW);
|
||||
fuzzer.setSlowSendSegmentSize(segmentSize);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,224 +1,40 @@
|
|||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.protocol.Generator;
|
||||
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.ByteBufferAssert;
|
||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestABCase2 extends AbstractABCase
|
||||
{
|
||||
private void assertPingFrame(byte[] payload) throws Exception
|
||||
{
|
||||
boolean hasPayload = ((payload != null) && (payload.length > 0));
|
||||
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
int len = 0;
|
||||
if (hasPayload)
|
||||
{
|
||||
len = payload.length;
|
||||
}
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(len + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare PING Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PING.getCode()));
|
||||
putPayloadLength(buf,len);
|
||||
putMask(buf);
|
||||
if (hasPayload)
|
||||
{
|
||||
buf.put(masked(payload));
|
||||
}
|
||||
|
||||
// Prepare CLOSE Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.CLOSE.getCode()));
|
||||
putPayloadLength(buf,2);
|
||||
putMask(buf);
|
||||
buf.put(masked(new byte[]
|
||||
{ 0x03, (byte)0xE8 }));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(2,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate echo'd frame
|
||||
WebSocketFrame frame = capture.getFrames().get(0);
|
||||
Assert.assertThat("frame should be PONG frame",frame.getOpCode(),is(OpCode.PONG));
|
||||
if (hasPayload)
|
||||
{
|
||||
Assert.assertThat("PONG.payloadLength",frame.getPayloadLength(),is(payload.length));
|
||||
ByteBufferAssert.assertEquals("PONG.payload",payload,frame.getPayload());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.assertThat("PONG.payloadLength",frame.getPayloadLength(),is(0));
|
||||
}
|
||||
|
||||
// Validate close
|
||||
frame = capture.getFrames().get(1);
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertProtocolError(byte[] payload) throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(payload.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare PING Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PING.getCode()));
|
||||
putPayloadLength(buf,payload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(payload));
|
||||
|
||||
// Prepare CLOSE Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.CLOSE.getCode()));
|
||||
putPayloadLength(buf,2);
|
||||
putMask(buf);
|
||||
buf.put(masked(new byte[]
|
||||
{ 0x03, (byte)0xE8 }));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate close w/ Protocol Error
|
||||
WebSocketFrame frame = capture.getFrames().pop();
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.PROTOCOL));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a ping frame as separate segments, in an inefficient way.
|
||||
*
|
||||
* @param payload
|
||||
* the payload
|
||||
* @param segmentSize
|
||||
* the segment size for each inefficient segment (flush between)
|
||||
*/
|
||||
private void assertSegmentedPingFrame(byte[] payload, int segmentSize) throws Exception
|
||||
{
|
||||
Assert.assertThat("payload exists for segmented send",payload,notNullValue());
|
||||
Assert.assertThat("payload exists for segmented send",payload.length,greaterThan(0));
|
||||
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(payload.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare PING Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PING.getCode()));
|
||||
putPayloadLength(buf,payload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(payload));
|
||||
|
||||
// Prepare CLOSE Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.CLOSE.getCode()));
|
||||
putPayloadLength(buf,2);
|
||||
putMask(buf);
|
||||
buf.put(masked(new byte[]
|
||||
{ 0x03, (byte)0xE8 }));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
int origLimit = buf.limit();
|
||||
int limit = buf.limit();
|
||||
int len;
|
||||
int pos = buf.position();
|
||||
int overallLeft = buf.remaining();
|
||||
while (overallLeft > 0)
|
||||
{
|
||||
buf.position(pos);
|
||||
limit = Math.min(origLimit,pos + segmentSize);
|
||||
buf.limit(limit);
|
||||
len = buf.remaining();
|
||||
overallLeft -= len;
|
||||
pos += len;
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
}
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(2,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate echo'd frame
|
||||
WebSocketFrame frame = capture.getFrames().get(0);
|
||||
Assert.assertThat("frame should be PONG frame",frame.getOpCode(),is(OpCode.PONG));
|
||||
Assert.assertThat("PONG.payloadLength",frame.getPayloadLength(),is(payload.length));
|
||||
ByteBufferAssert.assertEquals("PONG.payload",payload,frame.getPayload());
|
||||
|
||||
// Validate close
|
||||
frame = capture.getFrames().get(1);
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping without payload
|
||||
*/
|
||||
@Test
|
||||
public void testCase2_1() throws Exception
|
||||
{
|
||||
byte payload[] = new byte[0];
|
||||
assertPingFrame(payload);
|
||||
WebSocketFrame send = WebSocketFrame.ping();
|
||||
|
||||
WebSocketFrame expect = WebSocketFrame.pong();
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,8 +45,35 @@ public class TestABCase2 extends AbstractABCase
|
|||
{
|
||||
// send 10 pings each with unique payload
|
||||
// send close
|
||||
// expect 10 pongs with OUR payload
|
||||
// expect 10 pongs with our unique payload
|
||||
// expect close
|
||||
|
||||
int pingCount = 10;
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < pingCount; i++)
|
||||
{
|
||||
String payload = String.format("ping-%d[%X]",i,i);
|
||||
send.add(WebSocketFrame.ping().setPayload(payload));
|
||||
expect.add(WebSocketFrame.pong().setPayload(payload));
|
||||
}
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,6 +86,34 @@ public class TestABCase2 extends AbstractABCase
|
|||
// send close
|
||||
// expect 10 pongs with OUR payload
|
||||
// expect close
|
||||
|
||||
int pingCount = 10;
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < pingCount; i++)
|
||||
{
|
||||
String payload = String.format("ping-%d[%X]",i,i);
|
||||
send.add(WebSocketFrame.ping().setPayload(payload));
|
||||
expect.add(WebSocketFrame.pong().setPayload(payload));
|
||||
}
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
|
||||
fuzzer.setSlowSendSegmentSize(5);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,7 +123,27 @@ public class TestABCase2 extends AbstractABCase
|
|||
public void testCase2_2() throws Exception
|
||||
{
|
||||
byte payload[] = StringUtil.getUtf8Bytes("Hello world");
|
||||
assertPingFrame(payload);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.ping().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.pong().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,7 +154,27 @@ public class TestABCase2 extends AbstractABCase
|
|||
{
|
||||
byte payload[] = new byte[]
|
||||
{ 0x00, (byte)0xFF, (byte)0xFE, (byte)0xFD, (byte)0xFC, (byte)0xFB, 0x00, (byte)0xFF };
|
||||
assertPingFrame(payload);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.ping().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.pong().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,7 +185,27 @@ public class TestABCase2 extends AbstractABCase
|
|||
{
|
||||
byte payload[] = new byte[125];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
assertPingFrame(payload);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.ping().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.pong().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,9 +214,29 @@ public class TestABCase2 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase2_5() throws Exception
|
||||
{
|
||||
byte payload[] = new byte[126];
|
||||
byte payload[] = new byte[126]; // intentionally too big
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
assertProtocolError(payload);
|
||||
|
||||
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).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);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,7 +247,28 @@ public class TestABCase2 extends AbstractABCase
|
|||
{
|
||||
byte payload[] = new byte[125];
|
||||
Arrays.fill(payload,(byte)0xFE);
|
||||
assertSegmentedPingFrame(payload,1);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.ping().setPayload(payload));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.pong().setPayload(payload));
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
|
||||
fuzzer.setSlowSendSegmentSize(1);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,50 +277,25 @@ public class TestABCase2 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase2_7() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.pong()); // unsolicited pong
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte payload[] = new byte[0];
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare Unsolicited PONG Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PONG.getCode()));
|
||||
putPayloadLength(buf,payload.length);
|
||||
putMask(buf);
|
||||
// buf.put(masked(payload));
|
||||
|
||||
// Prepare CLOSE Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.CLOSE.getCode()));
|
||||
putPayloadLength(buf,2);
|
||||
putMask(buf);
|
||||
buf.put(masked(new byte[]
|
||||
{ 0x03, (byte)0xE8 }));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate close
|
||||
WebSocketFrame frame = capture.getFrames().pop();
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
fuzzer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -357,48 +304,24 @@ public class TestABCase2 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase2_8() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.pong().setPayload("unsolicited")); // unsolicited pong
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte payload[] = StringUtil.getUtf8Bytes("unsolicited");
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare Unsolicited PONG Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PONG.getCode()));
|
||||
putPayloadLength(buf,payload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(payload));
|
||||
|
||||
// Prepare CLOSE Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.CLOSE.getCode()));
|
||||
putPayloadLength(buf,2);
|
||||
putMask(buf);
|
||||
buf.put(masked(new byte[]
|
||||
{ 0x03, (byte)0xE8 }));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate close
|
||||
WebSocketFrame frame = capture.getFrames().pop();
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,69 +331,26 @@ public class TestABCase2 extends AbstractABCase
|
|||
@Test
|
||||
public void testCase2_9() throws Exception
|
||||
{
|
||||
// send unsolicited pong with payload.
|
||||
// send OUR ping with payload
|
||||
// send close
|
||||
// expect pong with OUR payload
|
||||
// expect close
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.pong().setPayload("unsolicited")); // unsolicited pong
|
||||
send.add(WebSocketFrame.ping().setPayload("our ping")); // our ping
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.pong().setPayload("our ping")); // our pong
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte pongPayload[] = StringUtil.getUtf8Bytes("unsolicited");
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(512);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Prepare Unsolicited PONG Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PONG.getCode()));
|
||||
putPayloadLength(buf,pongPayload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(pongPayload));
|
||||
|
||||
// Prepare our PING with payload
|
||||
byte pingPayload[] = StringUtil.getUtf8Bytes("ping me");
|
||||
buf.put((byte)(0x00 | FIN | OpCode.PING.getCode()));
|
||||
putPayloadLength(buf,pingPayload.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(pingPayload));
|
||||
|
||||
// Prepare CLOSE Frame
|
||||
buf.put((byte)(0x00 | FIN | OpCode.CLOSE.getCode()));
|
||||
putPayloadLength(buf,2);
|
||||
putMask(buf);
|
||||
buf.put(masked(new byte[]
|
||||
{ 0x03, (byte)0xE8 }));
|
||||
|
||||
// Write Data Frame
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
client.flush();
|
||||
|
||||
// Read frames
|
||||
IncomingFramesCapture capture = client.readFrames(2,TimeUnit.MILLISECONDS,500);
|
||||
|
||||
// Validate PONG
|
||||
WebSocketFrame frame = capture.getFrames().pop();
|
||||
Assert.assertThat("frame should be PONG frame",frame.getOpCode(),is(OpCode.PONG));
|
||||
Assert.assertThat("PONG.payloadLength",frame.getPayloadLength(),is(pingPayload.length));
|
||||
ByteBufferAssert.assertEquals("PONG.payload",pingPayload,frame.getPayload());
|
||||
|
||||
// Validate close
|
||||
frame = capture.getFrames().pop();
|
||||
Assert.assertThat("CLOSE.frame.opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
Assert.assertThat("CLOSE.statusCode",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.disconnect();
|
||||
fuzzer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestABCase3 extends AbstractABCase
|
||||
{
|
||||
/**
|
||||
* Send small text frame, with RSV1 == true, with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_1() throws Exception
|
||||
{
|
||||
WebSocketFrame send = WebSocketFrame.text("small").setRsv1(true); // intentionally bad
|
||||
|
||||
WebSocketFrame expect = new CloseInfo(StatusCode.PROTOCOL).asFrame();
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send small text frame, send again with RSV2 == true, then ping, with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_2() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text("small"));
|
||||
send.add(WebSocketFrame.text("small").setRsv2(true)); // intentionally bad
|
||||
send.add(WebSocketFrame.ping().setPayload("ping"));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text("small")); // echo on good frame
|
||||
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);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send small text frame, send again with (RSV1 & RSV2), then ping, with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_3() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text("small"));
|
||||
send.add(WebSocketFrame.text("small").setRsv1(true).setRsv2(true)); // intentionally bad
|
||||
send.add(WebSocketFrame.ping().setPayload("ping"));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text("small")); // echo on good frame
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send small text frame, send again with (RSV3), then ping, with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_4() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text("small"));
|
||||
send.add(WebSocketFrame.text("small").setRsv3(true)); // intentionally bad
|
||||
send.add(WebSocketFrame.ping().setPayload("ping"));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text("small")); // echo on good frame
|
||||
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
|
||||
fuzzer.setSlowSendSegmentSize(1);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send binary frame with (RSV3 & RSV1), with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_5() throws Exception
|
||||
{
|
||||
byte payload[] = new byte[8];
|
||||
Arrays.fill(payload,(byte)0xFF);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.binary(payload).setRsv3(true).setRsv1(true)); // intentionally bad
|
||||
|
||||
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);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send ping frame with (RSV3 & RSV2), with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_6() throws Exception
|
||||
{
|
||||
byte payload[] = new byte[8];
|
||||
Arrays.fill(payload,(byte)0xFF);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.ping().setPayload(payload).setRsv3(true).setRsv2(true)); // intentionally bad
|
||||
|
||||
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);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send close frame with (RSV3 & RSV2 & RSV1), with no extensions defined.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3_7() throws Exception
|
||||
{
|
||||
byte payload[] = new byte[8];
|
||||
Arrays.fill(payload,(byte)0xFF);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
WebSocketFrame frame = new CloseInfo(StatusCode.NORMAL).asFrame();
|
||||
frame.setRsv1(true);
|
||||
frame.setRsv2(true);
|
||||
frame.setRsv3(true);
|
||||
send.add(frame); // intentionally bad
|
||||
|
||||
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);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -174,13 +174,16 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames
|
|||
LOG.debug("disconnect");
|
||||
IO.close(in);
|
||||
IO.close(out);
|
||||
try
|
||||
if (socket != null)
|
||||
{
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException ignore)
|
||||
{
|
||||
/* ignore */
|
||||
try
|
||||
{
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException ignore)
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,6 +321,11 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames
|
|||
incomingFrameQueue.incoming(copy);
|
||||
}
|
||||
|
||||
public boolean isConnected()
|
||||
{
|
||||
return (socket != null) && (socket.isConnected());
|
||||
}
|
||||
|
||||
public void lookFor(String string) throws IOException
|
||||
{
|
||||
String orig = string;
|
||||
|
@ -547,4 +555,24 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames
|
|||
LOG.debug("write((String)[{}]){}{})",str.length(),'\n',str);
|
||||
out.write(StringUtil.getBytes(str,StringUtil.__ISO_8859_1));
|
||||
}
|
||||
|
||||
public void writeRawSlowly(ByteBuffer buf, int segmentSize) throws IOException
|
||||
{
|
||||
int origLimit = buf.limit();
|
||||
int limit = buf.limit();
|
||||
int len;
|
||||
int pos = buf.position();
|
||||
int overallLeft = buf.remaining();
|
||||
while (overallLeft > 0)
|
||||
{
|
||||
buf.position(pos);
|
||||
limit = Math.min(origLimit,pos + segmentSize);
|
||||
buf.limit(limit);
|
||||
len = buf.remaining();
|
||||
overallLeft -= len;
|
||||
pos += len;
|
||||
writeRaw(buf);
|
||||
flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.io.LEVEL=WARN
|
||||
org.eclipse.jetty.LEVEL=WARN
|
||||
org.eclipse.jetty.server.LEVEL=WARN
|
||||
# org.eclipse.jetty.websocket.LEVEL=WARN
|
||||
org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF
|
||||
# See the read/write traffic
|
||||
org.eclipse.jetty.websocket.io.Frames.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.io.Frames.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.io.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.io.WebSocketAsyncConnection.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.util.thread.QueuedThreadPool.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.io.SelectorManager.LEVEL=INFO
|
||||
org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.driver.WebSocketEventDriver.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.protocol.Generator.LEVEL=INFO
|
||||
|
|
Loading…
Reference in New Issue