More spec tests from server point of view
This commit is contained in:
parent
acabe78101
commit
cbcb76eaea
|
@ -87,6 +87,11 @@ public class WebSocketEventDriver implements IncomingFrames
|
|||
|
||||
private void appendBuffer(ByteBuffer msgBuf, ByteBuffer byteBuffer)
|
||||
{
|
||||
if (byteBuffer == null)
|
||||
{
|
||||
// nothing to do (empty payload is possible)
|
||||
return;
|
||||
}
|
||||
if (msgBuf.remaining() < byteBuffer.remaining())
|
||||
{
|
||||
throw new MessageTooLargeException("Message exceeded maximum buffer");
|
||||
|
|
|
@ -192,7 +192,7 @@ public class Generator
|
|||
/*
|
||||
* prepare the byte buffer to put frame into
|
||||
*/
|
||||
ByteBuffer buffer = bufferPool.acquire(bufferSize,true);
|
||||
ByteBuffer buffer = bufferPool.acquire(bufferSize + OVERHEAD,true);
|
||||
BufferUtil.clearToFill(buffer);
|
||||
|
||||
if (frame.remaining() == frame.getPayloadLength())
|
||||
|
|
|
@ -141,7 +141,10 @@ public class WebSocketFrame implements Frame
|
|||
}
|
||||
payloadLength = copy.payloadLength;
|
||||
payloadStart = copy.payloadStart;
|
||||
if (copy.data != null) // deal with empty payloads
|
||||
{
|
||||
data = copy.data.slice();
|
||||
}
|
||||
continuationIndex = copy.continuationIndex;
|
||||
continuation = copy.continuation;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@ public class ByteBufferAssert
|
|||
}
|
||||
}
|
||||
|
||||
public static void assertEquals(String message, byte[] expectedBytes, ByteBuffer actualBuffer)
|
||||
{
|
||||
byte actualBytes[] = BufferUtil.toArray(actualBuffer);
|
||||
assertEquals(message,expectedBytes,actualBytes);
|
||||
}
|
||||
|
||||
public static void assertEquals(String message, ByteBuffer expectedBuffer, ByteBuffer actualBuffer)
|
||||
{
|
||||
byte expectedBytes[] = BufferUtil.toArray(expectedBuffer);
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package org.eclipse.jetty.websocket.server.ab;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.websocket.server.SimpleServletServer;
|
||||
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
public abstract class AbstractABCase
|
||||
{
|
||||
protected static final byte FIN = (byte)0x80;
|
||||
protected static final byte NOFIN = 0x00;
|
||||
private static final byte MASKED_BIT = (byte)0x80;
|
||||
private static final byte[] MASK =
|
||||
{ 0x12, 0x34, 0x56, 0x78 };
|
||||
|
||||
protected static SimpleServletServer server;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
server = new SimpleServletServer(new MyEchoServlet());
|
||||
server.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer()
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
protected byte[] masked(final byte[] data)
|
||||
{
|
||||
int len = data.length;
|
||||
byte ret[] = new byte[len];
|
||||
System.arraycopy(data,0,ret,0,len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
ret[i] ^= MASK[i % 4];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void putLength(ByteBuffer buf, int length, boolean masked)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Length cannot be negative");
|
||||
}
|
||||
byte b = (masked?MASKED_BIT:0x00);
|
||||
|
||||
// write the uncompressed length
|
||||
if (length > 0xFF_FF)
|
||||
{
|
||||
buf.put((byte)(b | 0x7F));
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)((length >> 24) & 0xFF));
|
||||
buf.put((byte)((length >> 16) & 0xFF));
|
||||
buf.put((byte)((length >> 8) & 0xFF));
|
||||
buf.put((byte)(length & 0xFF));
|
||||
}
|
||||
else if (length >= 0x7E)
|
||||
{
|
||||
buf.put((byte)(b | 0x7E));
|
||||
buf.put((byte)(length >> 8));
|
||||
buf.put((byte)(length & 0xFF));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.put((byte)(b | length));
|
||||
}
|
||||
}
|
||||
|
||||
public void putMask(ByteBuffer buf)
|
||||
{
|
||||
buf.put(MASK);
|
||||
}
|
||||
|
||||
public void putPayloadLength(ByteBuffer buf, int length)
|
||||
{
|
||||
putLength(buf,length,true);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import org.junit.runners.Suite;
|
|||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses(
|
||||
{ TestABCase5.class, TestABCase7_9.class })
|
||||
{ TestABCase1.class, TestABCase5.class, TestABCase7_9.class })
|
||||
public class AllTests
|
||||
{
|
||||
/* let junit do the rest */
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
// ========================================================================
|
||||
// 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.Arrays;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
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.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestABCase1 extends AbstractABCase
|
||||
{
|
||||
/**
|
||||
* Echo 0 byte text message
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_1() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(16);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,0);
|
||||
putMask(buf);
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(0));
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 125 byte text message (uses small 7-bit payload length)
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_2() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte msg[] = new byte[125];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(msg.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,msg.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(msg));
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(msg.length));
|
||||
ByteBufferAssert.assertEquals("Text.payload",msg,frame.getPayload());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 126 byte text message (uses medium 2 byte payload length)
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_3() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte msg[] = new byte[126];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(msg.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,msg.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(msg));
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(msg.length));
|
||||
ByteBufferAssert.assertEquals("Text.payload",msg,frame.getPayload());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 127 byte text message (uses medium 2 byte payload length)
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_4() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte msg[] = new byte[127];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(msg.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,msg.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(msg));
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(msg.length));
|
||||
ByteBufferAssert.assertEquals("Text.payload",msg,frame.getPayload());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 128 byte text message (uses medium 2 byte payload length)
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_5() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte msg[] = new byte[128];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(msg.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,msg.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(msg));
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(msg.length));
|
||||
ByteBufferAssert.assertEquals("Text.payload",msg,frame.getPayload());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 65535 byte text message (uses medium 2 byte payload length)
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_6() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte msg[] = new byte[65535];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(msg.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,msg.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(msg));
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(msg.length));
|
||||
ByteBufferAssert.assertEquals("Text.payload",msg,frame.getPayload());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo 65536 byte text message (uses large 8 byte payload length)
|
||||
*/
|
||||
@Test
|
||||
public void testCase1_1_7() throws Exception
|
||||
{
|
||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||
try
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
byte msg[] = new byte[65536];
|
||||
Arrays.fill(msg,(byte)'*');
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(msg.length + Generator.OVERHEAD);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
||||
buf.put((byte)(0x00 | FIN | OpCode.TEXT.getCode()));
|
||||
putPayloadLength(buf,msg.length);
|
||||
putMask(buf);
|
||||
buf.put(masked(msg));
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
client.writeRaw(buf);
|
||||
|
||||
// Read frame
|
||||
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||
WebSocketFrame frame = frames.remove();
|
||||
Assert.assertThat("frame should be TEXT frame",frame.getOpCode(),is(OpCode.TEXT));
|
||||
Assert.assertThat("Text.payloadLength",frame.getPayloadLength(),is(msg.length));
|
||||
ByteBufferAssert.assertEquals("Text.payload",msg,frame.getPayload());
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
|||
org.eclipse.jetty.io.LEVEL=WARN
|
||||
org.eclipse.jetty.server.LEVEL=WARN
|
||||
# org.eclipse.jetty.io.SelectorManager.LEVEL=INFO
|
||||
org.eclipse.jetty.websocket.LEVEL=WARN
|
||||
org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.protocol.Generator.LEVEL=INFO
|
||||
# org.eclipse.jetty.websocket.protocol.Parser.LEVEL=INFO
|
||||
|
|
Loading…
Reference in New Issue