couple more test cases and fixed fragmented control frame response

This commit is contained in:
Jesse McConnell 2012-07-02 17:23:16 -05:00
parent 2d5fa0a3bc
commit 46da5fe5e2
4 changed files with 251 additions and 3 deletions

View File

@ -201,7 +201,7 @@ public class WebSocketEventDriver implements Parser.Listener
reason = reason.substring(0,CloseFrame.MAX_REASON);
}
}
LOG.debug("terminateConnection({},{})",statusCode,reason);
LOG.debug("terminateConnection({},{})",statusCode,rawreason);
connection.close(statusCode,reason);
}
catch (IOException e)

View File

@ -9,6 +9,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.OpCode;
import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.frames.BaseFrame;
@ -125,14 +126,14 @@ public class Parser
if (opcode.isControlFrame() && !fin)
{
throw new WebSocketException("Fragmented Control Frame [" + opcode.name() + "]");
throw new ProtocolException("Fragmented Control Frame [" + opcode.name() + "]");
}
if (opcode == OpCode.CONTINUATION)
{
if (parser == null)
{
throw new WebSocketException("Fragment continuation frame without prior !FIN");
throw new ProtocolException("Fragment continuation frame without prior !FIN");
}
}

View File

@ -17,7 +17,9 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.CloseException;
import org.eclipse.jetty.websocket.api.ExtensionConfig;
import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
@ -186,6 +188,7 @@ public class WebSocketAsyncConnection extends AbstractAsyncConnection implements
terminateConnection(StatusCode.PROTOCOL,null);
break;
}
parser.parse(buffer);
}
}

View File

@ -0,0 +1,244 @@
package org.eclipse.jetty.websocket.server.ab;
import static org.hamcrest.Matchers.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
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.api.OpCode;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.frames.BaseFrame;
import org.eclipse.jetty.websocket.frames.CloseFrame;
import org.eclipse.jetty.websocket.frames.PingFrame;
import org.eclipse.jetty.websocket.frames.TextFrame;
import org.eclipse.jetty.websocket.generator.FrameGenerator;
import org.eclipse.jetty.websocket.server.SimpleServletServer;
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
import org.eclipse.jetty.websocket.server.WebSocketServlet;
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
public class TestABCase5
{
@SuppressWarnings("serial")
public static class RFCServlet extends WebSocketServlet
{
@Override
public void registerWebSockets(WebSocketServerFactory factory)
{
factory.register(RFCSocket.class);
}
}
public static class RFCSocket extends WebSocketAdapter
{
private static Logger LOG = Log.getLogger(RFCSocket.class);
@Override
public void onWebSocketText(String message)
{
LOG.debug("onWebSocketText({})",message);
// Test the RFC 6455 close code 1011 that should close
// trigger a WebSocket server terminated close.
if (message.equals("CRASH"))
{
System.out.printf("Got OnTextMessage");
throw new RuntimeException("Something bad happened");
}
// echo the message back.
try
{
getConnection().write(message);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
}
private static SimpleServletServer server;
@BeforeClass
public static void startServer() throws Exception
{
server = new SimpleServletServer(new MyEchoServlet());
server.start();
}
@AfterClass
public static void stopServer()
{
server.stop();
}
@Test
public void testCase5_1PingIn2Packets() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
try
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
ByteBuffer buf = ByteBuffer.allocate(FrameGenerator.OVERHEAD + 2);
BufferUtil.clearToFill(buf);
String fragment1 = "fragment1";
buf.put((byte)(0x00 | OpCode.PING.getCode()));
byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F;
buf.put(b);
buf.put(fragment1.getBytes());
BufferUtil.flipToFlush(buf,0);
client.writeRaw(buf);
ByteBuffer buf2 = ByteBuffer.allocate(FrameGenerator.OVERHEAD + 2);
BufferUtil.clearToFill(buf2);
String fragment2 = "fragment2";
buf2.put((byte)(0x80 | OpCode.PING.getCode()));
b = 0x00; // no masking
b |= fragment2.length() & 0x7F;
buf2.put(b);
buf2.put(fragment2.getBytes());
BufferUtil.flipToFlush(buf2,0);
client.writeRaw(buf2);
// Read frame (hopefully text frame)
Queue<BaseFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
CloseFrame closeFrame = (CloseFrame)frames.remove();
Assert.assertThat("CloseFrame.status code",closeFrame.getStatusCode(),is(1002));
}
finally
{
client.close();
}
}
@Test
public void testCase5_2PongIn2Packets() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
try
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
ByteBuffer buf = ByteBuffer.allocate(FrameGenerator.OVERHEAD + 2);
BufferUtil.clearToFill(buf);
String fragment1 = "fragment1";
buf.put((byte)(0x00 | OpCode.PONG.getCode()));
byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F;
buf.put(b);
buf.put(fragment1.getBytes());
BufferUtil.flipToFlush(buf,0);
client.writeRaw(buf);
ByteBuffer buf2 = ByteBuffer.allocate(FrameGenerator.OVERHEAD + 2);
BufferUtil.clearToFill(buf2);
String fragment2 = "fragment2";
buf2.put((byte)(0x80 | OpCode.CONTINUATION.getCode()));
b = 0x00; // no masking
b |= fragment2.length() & 0x7F;
buf2.put(b);
buf2.put(fragment2.getBytes());
BufferUtil.flipToFlush(buf2,0);
client.writeRaw(buf2);
// Read frame (hopefully text frame)
Queue<BaseFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
CloseFrame closeFrame = (CloseFrame)frames.remove();
Assert.assertThat("CloseFrame.status code",closeFrame.getStatusCode(),is(1002));
}
finally
{
client.close();
}
}
@Test
@Ignore ("not re-assembling the strings, something odd with echo socket")
public void testCase5_3TextIn2Packets() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
try
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
ByteBuffer buf = ByteBuffer.allocate(FrameGenerator.OVERHEAD + 2);
BufferUtil.clearToFill(buf);
String fragment1 = "fragment1";
buf.put((byte)(0x00 | OpCode.TEXT.getCode()));
byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F;
buf.put(b);
buf.put(fragment1.getBytes());
BufferUtil.flipToFlush(buf,0);
client.writeRaw(buf);
ByteBuffer buf2 = ByteBuffer.allocate(FrameGenerator.OVERHEAD + 2);
BufferUtil.clearToFill(buf2);
String fragment2 = "fragment2";
buf2.put((byte)(0x80 | OpCode.CONTINUATION.getCode()));
b = 0x00; // no masking
b |= fragment2.length() & 0x7F;
buf2.put(b);
buf2.put(fragment2.getBytes());
BufferUtil.flipToFlush(buf2,0);
client.writeRaw(buf2);
// Read frame (hopefully text frame)
Queue<BaseFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,500);
TextFrame textFrame = (TextFrame)frames.remove();
Assert.assertThat("TextFrame.payload",textFrame.getPayloadUTF8(),is(fragment1 + fragment2));
}
finally
{
client.close();
}
}
}