mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-03 12:29:31 +00:00
Adding the AB7 close test cases
This commit is contained in:
parent
93168a3d24
commit
b8fc39a53e
@ -114,7 +114,7 @@ public class StatusCode
|
||||
public final static int SERVER_ERROR = 1011;
|
||||
|
||||
/**
|
||||
* 1012 indicates that the service is restarted. a client may reconnect, and if it choses to do, should reconnect using a randomized delay of 5 - 30s.
|
||||
* 1012 indicates that the service is restarted. a client may reconnect, and if it chooses to do, should reconnect using a randomized delay of 5 - 30s.
|
||||
* <p>
|
||||
* See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">[hybi] Additional WebSocket Close Error Codes</a>
|
||||
*/
|
||||
|
@ -23,12 +23,11 @@ import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
@ -62,7 +61,6 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||
private WebSocketSession session;
|
||||
private List<ExtensionConfig> extensions;
|
||||
private boolean flushing;
|
||||
private AtomicLong writes;
|
||||
|
||||
public AbstractWebSocketConnection(EndPoint endp, Executor executor, ScheduledExecutorService scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||
{
|
||||
@ -74,14 +72,6 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||
this.scheduler = scheduler;
|
||||
this.extensions = new ArrayList<>();
|
||||
this.queue = new FrameQueue();
|
||||
this.writes = new AtomicLong(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen()
|
||||
{
|
||||
super.onOpen();
|
||||
fillInterested();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,6 +126,13 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||
|
||||
frameBytes = queue.pop();
|
||||
|
||||
if (!isOpen())
|
||||
{
|
||||
// No longer have an open connection, drop the frame.
|
||||
queue.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = frameBytes.getByteBuffer();
|
||||
|
||||
if (buffer == null)
|
||||
@ -236,6 +233,13 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen()
|
||||
{
|
||||
super.onOpen();
|
||||
fillInterested();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue internal frame from {@link OutgoingFrames} stack for eventual write out on the physical connection.
|
||||
*/
|
||||
@ -261,6 +265,9 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||
}
|
||||
|
||||
scheduleTimeout(bytes);
|
||||
|
||||
if (isOpen())
|
||||
{
|
||||
if (frame.getOpCode() == OpCode.PING)
|
||||
{
|
||||
queue.prepend(bytes);
|
||||
@ -270,6 +277,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||
queue.append(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class WebSocketFrameTest
|
||||
@Test
|
||||
public void testStrictValidClose()
|
||||
{
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL,null);
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL);
|
||||
ByteBuffer actual = strictGenerator.generate(close.asFrame());
|
||||
ByteBuffer expected = ByteBuffer.allocate(4);
|
||||
expected.put((byte)0x88);
|
||||
|
@ -14,7 +14,9 @@ import org.junit.runners.Suite;
|
||||
TestABCase6.class,
|
||||
TestABCase6_GoodUTF.class,
|
||||
TestABCase6_BadUTF.class,
|
||||
TestABCase7_9.class
|
||||
TestABCase7.class,
|
||||
TestABCase7_GoodStatusCodes.class,
|
||||
TestABCase7_BadStatusCodes.class,
|
||||
})
|
||||
// @formatter:on
|
||||
public class AllTests
|
||||
|
@ -127,6 +127,12 @@ public class Fuzzer
|
||||
expect(Collections.singletonList(expect));
|
||||
}
|
||||
|
||||
public void expectNoMoreFrames()
|
||||
{
|
||||
// TODO Should test for no more frames. success if connection closed.
|
||||
|
||||
}
|
||||
|
||||
public SendMode getSendMode()
|
||||
{
|
||||
return sendMode;
|
||||
|
@ -99,6 +99,7 @@ public class TestABCase6_GoodUTF extends AbstractABCase
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private final byte[] msg;
|
||||
|
||||
public TestABCase6_GoodUTF(String testId, String hexMsg)
|
||||
|
@ -0,0 +1,416 @@
|
||||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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.OpCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.server.helper.Hex;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test of Close Handling
|
||||
*/
|
||||
public class TestABCase7 extends AbstractABCase
|
||||
{
|
||||
/**
|
||||
* Basic message then close frame, normal behavior
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_1_1() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(WebSocketFrame.text("Hello World"));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(WebSocketFrame.text("Hello World"));
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close frame, then another close frame (send frame ignored)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_1_2() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
send.add(new CloseInfo().asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
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);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close frame, then ping frame (no pong received)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_1_3() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
send.add(WebSocketFrame.ping().setPayload("out of band ping"));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
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);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close frame, then ping frame (no pong received)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_1_4() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
send.add(WebSocketFrame.text("out of band text"));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
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);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Text fin=false, close, then continuation fin=true
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_1_5() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload("an").setFin(false));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("ticipation").setFin(true));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
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);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 256k msg, then close, then ping
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Problematic")
|
||||
public void testCase7_1_6() throws Exception
|
||||
{
|
||||
byte msg[] = new byte[256 * 1024];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload(msg));
|
||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||
send.add(new WebSocketFrame(OpCode.PING).setPayload("out of band"));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.TEXT).setPayload(msg));
|
||||
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);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with no payload (payload length 0)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_3_1() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CLOSE));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new WebSocketFrame(OpCode.CLOSE));
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with invalid payload (payload length 1)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_3_2() throws Exception
|
||||
{
|
||||
byte payload[] = new byte[]
|
||||
{ 0x00 };
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload));
|
||||
|
||||
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.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with valid payload (payload length 2)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_3_3() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
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
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with valid payload (with reason)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_3_4() throws Exception
|
||||
{
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseInfo(StatusCode.NORMAL,"Hic").asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL,"Hic").asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with valid payload (with 123 byte reason)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_3_5() throws Exception
|
||||
{
|
||||
byte utf[] = new byte[123];
|
||||
Arrays.fill(utf,(byte)'!');
|
||||
String reason = StringUtil.toUTF8String(utf,0,utf.length);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new CloseInfo(StatusCode.NORMAL,reason).asFrame());
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.NORMAL,reason).asFrame());
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with invalid payload (124 byte reason) (exceeds total allowed control frame payload bytes)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_3_6() throws Exception
|
||||
{
|
||||
ByteBuffer payload = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.put((byte)0xE8);
|
||||
payload.put((byte)0x03);
|
||||
byte reason[] = new byte[124]; // too big
|
||||
Arrays.fill(reason,(byte)'!');
|
||||
payload.put(reason);
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
WebSocketFrame close = new WebSocketFrame();
|
||||
close.setPayload(payload);
|
||||
close.setOpCode(OpCode.CLOSE); // set opcode after payload (to prevent early bad payload detection)
|
||||
send.add(close);
|
||||
|
||||
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.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close with invalid payload (124 byte reason) (exceeds total allowed control frame payload bytes)
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_5_1() throws Exception
|
||||
{
|
||||
ByteBuffer payload = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.put((byte)0xE8); // normal close
|
||||
payload.put((byte)0x03);
|
||||
byte invalidUtf[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5EDA080656469746564");
|
||||
payload.put(invalidUtf);
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
WebSocketFrame close = new WebSocketFrame();
|
||||
close.setPayload(payload);
|
||||
close.setOpCode(OpCode.CLOSE); // set opcode after payload (to prevent early bad payload detection)
|
||||
send.add(close);
|
||||
|
||||
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.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
// ========================================================================
|
||||
// Copyright 2011-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
//========================================================================
|
||||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
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.SimpleServletServer;
|
||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class TestABCase7_9
|
||||
{
|
||||
private static SimpleServletServer server;
|
||||
|
||||
@Parameters
|
||||
public static Collection<Integer[]> data()
|
||||
{
|
||||
List<Integer[]> data = new ArrayList<>();
|
||||
// @formatter:off
|
||||
data.add(new Integer[] { new Integer(0) });
|
||||
data.add(new Integer[] { new Integer(999) });
|
||||
data.add(new Integer[] { new Integer(1004) });
|
||||
data.add(new Integer[] { new Integer(1005) });
|
||||
data.add(new Integer[] { new Integer(1006) });
|
||||
data.add(new Integer[] { new Integer(1012) });
|
||||
data.add(new Integer[] { new Integer(1013) });
|
||||
data.add(new Integer[] { new Integer(1014) });
|
||||
data.add(new Integer[] { new Integer(1015) });
|
||||
data.add(new Integer[] { new Integer(1016) });
|
||||
data.add(new Integer[] { new Integer(1100) });
|
||||
data.add(new Integer[] { new Integer(2000) });
|
||||
data.add(new Integer[] { new Integer(2999) });
|
||||
|
||||
// @formatter:on
|
||||
return data;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
server = new SimpleServletServer(new MyEchoServlet());
|
||||
server.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer()
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
private int invalidStatusCode;
|
||||
|
||||
public TestABCase7_9(Integer invalidStatusCode)
|
||||
{
|
||||
this.invalidStatusCode = invalidStatusCode;
|
||||
}
|
||||
|
||||
private void remask(ByteBuffer buf, int position, byte[] mask)
|
||||
{
|
||||
int end = buf.position();
|
||||
int off;
|
||||
for (int i = position; i < end; i++)
|
||||
{
|
||||
off = i - position;
|
||||
// Mask each byte by its absolute position in the bytebuffer
|
||||
buf.put(i,(byte)(buf.get(i) ^ mask[off % 4]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the requirement of issuing
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_9_XInvalidCloseStatusCodes() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(Generator.OVERHEAD + 2);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Create Close Frame manually, as we are testing the server's behavior of a bad client.
|
||||
buf.put((byte)(0x80 | OpCode.CLOSE));
|
||||
buf.put((byte)(0x80 | 2));
|
||||
byte mask[] = new byte[]
|
||||
{ 0x44, 0x44, 0x44, 0x44 };
|
||||
buf.put(mask);
|
||||
int position = buf.position();
|
||||
buf.putChar((char)this.invalidStatusCode);
|
||||
remask(buf,position,mask);
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame (hopefully text frame)
|
||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame closeFrame = capture.getFrames().pop();
|
||||
Assert.assertThat("CloseFrame.status code",new CloseInfo(closeFrame).getStatusCode(),is(1002));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the requirement of issuing
|
||||
*/
|
||||
@Test
|
||||
public void testCase7_9_XInvalidCloseStatusCodesWithReason() throws Exception
|
||||
{
|
||||
String reason = "closing time";
|
||||
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(Generator.OVERHEAD + 2);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
// Create Close Frame manually, as we are testing the server's behavior of a bad client.
|
||||
buf.put((byte)(0x80 | OpCode.CLOSE));
|
||||
buf.put((byte)(0x80 | (2 + reason.length())));
|
||||
byte mask[] = new byte[]
|
||||
{ 0x44, 0x44, 0x44, 0x44 };
|
||||
buf.put(mask);
|
||||
int position = buf.position();
|
||||
buf.putChar((char)this.invalidStatusCode);
|
||||
buf.put(reason.getBytes(StringUtil.__UTF8_CHARSET));
|
||||
remask(buf,position,mask);
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame (hopefully text frame)
|
||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame closeFrame = capture.getFrames().pop();
|
||||
Assert.assertThat("CloseFrame.status code",new CloseInfo(closeFrame).getStatusCode(),is(1002));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/**
|
||||
* Test Bad Close Status Codes
|
||||
*/
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class TestABCase7_BadStatusCodes extends AbstractABCase
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TestABCase7_GoodStatusCodes.class);
|
||||
|
||||
@Parameters
|
||||
public static Collection<Object[]> data()
|
||||
{
|
||||
// The various Good UTF8 sequences as a String (hex form)
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
// @formatter:off
|
||||
data.add(new Object[] { "7.9.1", 0 });
|
||||
data.add(new Object[] { "7.9.2", 999 });
|
||||
data.add(new Object[] { "7.9.3", 1004 });
|
||||
data.add(new Object[] { "7.9.4", 1005 });
|
||||
data.add(new Object[] { "7.9.5", 1006 });
|
||||
data.add(new Object[] { "7.9.6", 1012 });
|
||||
data.add(new Object[] { "7.9.7", 1013 });
|
||||
data.add(new Object[] { "7.9.8", 1014 });
|
||||
data.add(new Object[] { "7.9.9", 1015 });
|
||||
data.add(new Object[] { "7.9.10", 1016 });
|
||||
data.add(new Object[] { "7.9.11", 1100 });
|
||||
data.add(new Object[] { "7.9.12", 2000 });
|
||||
data.add(new Object[] { "7.9.13", 2999 });
|
||||
// -- close status codes, with undefined events in spec
|
||||
data.add(new Object[] { "7.13.1", 5000 });
|
||||
data.add(new Object[] { "7.13.2", 65536 });
|
||||
// @formatter:on
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private final int statusCode;
|
||||
|
||||
public TestABCase7_BadStatusCodes(String testId, int statusCode)
|
||||
{
|
||||
LOG.debug("Test ID: {}",testId);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* just the close code, no reason
|
||||
*/
|
||||
@Test
|
||||
public void testBadStatusCode() throws Exception
|
||||
{
|
||||
ByteBuffer payload = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.putChar((char)statusCode);
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload.slice()));
|
||||
|
||||
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.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* the bad close code, with reason
|
||||
*/
|
||||
@Test
|
||||
public void testBadStatusCodeWithReason() throws Exception
|
||||
{
|
||||
ByteBuffer payload = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.putChar((char)statusCode);
|
||||
payload.put(StringUtil.getBytes("Reason"));
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload.slice()));
|
||||
|
||||
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.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/**
|
||||
* Test Good Close Status Codes
|
||||
*/
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class TestABCase7_GoodStatusCodes extends AbstractABCase
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TestABCase7_GoodStatusCodes.class);
|
||||
|
||||
@Parameters
|
||||
public static Collection<Object[]> data()
|
||||
{
|
||||
// The various Good UTF8 sequences as a String (hex form)
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
// @formatter:off
|
||||
data.add(new Object[] { "7.7.1", 1000 });
|
||||
data.add(new Object[] { "7.7.2", 1001 });
|
||||
data.add(new Object[] { "7.7.3", 1002 });
|
||||
data.add(new Object[] { "7.7.4", 1003 });
|
||||
data.add(new Object[] { "7.7.5", 1007 });
|
||||
data.add(new Object[] { "7.7.6", 1008 });
|
||||
data.add(new Object[] { "7.7.7", 1009 });
|
||||
data.add(new Object[] { "7.7.8", 1010 });
|
||||
data.add(new Object[] { "7.7.9", 1011 });
|
||||
data.add(new Object[] { "7.7.10", 3000 });
|
||||
data.add(new Object[] { "7.7.11", 3999 });
|
||||
data.add(new Object[] { "7.7.12", 4000 });
|
||||
data.add(new Object[] { "7.7.13", 4999 });
|
||||
// @formatter:on
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private final int statusCode;
|
||||
|
||||
public TestABCase7_GoodStatusCodes(String testId, int statusCode)
|
||||
{
|
||||
LOG.debug("Test ID: {}",testId);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* just the close code, no reason
|
||||
*/
|
||||
@Test
|
||||
public void testStatusCode() throws Exception
|
||||
{
|
||||
ByteBuffer payload = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.putChar((char)statusCode);
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload.slice()));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload.slice()));
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* the good close code, with reason
|
||||
*/
|
||||
@Test
|
||||
public void testStatusCodeWithReason() throws Exception
|
||||
{
|
||||
ByteBuffer payload = ByteBuffer.allocate(256);
|
||||
BufferUtil.clearToFill(payload);
|
||||
payload.putChar((char)statusCode);
|
||||
payload.put(StringUtil.getBytes("Reason"));
|
||||
BufferUtil.flipToFlush(payload,0);
|
||||
|
||||
List<WebSocketFrame> send = new ArrayList<>();
|
||||
send.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload.slice()));
|
||||
|
||||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new WebSocketFrame(OpCode.CLOSE).setPayload(payload.slice()));
|
||||
|
||||
Fuzzer fuzzer = new Fuzzer(this);
|
||||
try
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
fuzzer.expectNoMoreFrames();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fuzzer.close();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user