Reworking OpCode from enum to static class

This commit is contained in:
Joakim Erdfelt 2012-07-31 15:15:21 -07:00
parent 9a568514a6
commit a97fe106f9
23 changed files with 227 additions and 124 deletions

View File

@ -67,7 +67,7 @@ public class TestClient
} }
} }
public void send(OpCode op, byte[] data, int maxFragmentLength) public void send(byte op, byte[] data, int maxFragmentLength)
{ {
_starts.add(System.nanoTime()); _starts.add(System.nanoTime());
@ -215,7 +215,7 @@ public class TestClient
{ {
long next = System.currentTimeMillis() + delay; long next = System.currentTimeMillis() + delay;
OpCode op = OpCode.TEXT; byte op = OpCode.TEXT;
if (binary) if (binary)
{ {
op = OpCode.BINARY; op = OpCode.BINARY;
@ -225,7 +225,7 @@ public class TestClient
switch (op) switch (op)
{ {
case TEXT: case OpCode.TEXT:
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
while (b.length() < size) while (b.length() < size)
@ -235,7 +235,7 @@ public class TestClient
data = b.toString().getBytes(StringUtil.__UTF8_CHARSET); data = b.toString().getBytes(StringUtil.__UTF8_CHARSET);
break; break;
} }
case BINARY: case OpCode.BINARY:
{ {
data = new byte[size]; data = new byte[size];
__random.nextBytes(data); __random.nextBytes(data);
@ -328,7 +328,7 @@ public class TestClient
client.connect(wsUri,socket).get(10,TimeUnit.SECONDS); client.connect(wsUri,socket).get(10,TimeUnit.SECONDS);
} }
private void send(OpCode op, byte[] data, int fragment) private void send(byte op, byte[] data, int fragment)
{ {
socket.send(op,data,fragment); socket.send(op,data,fragment);
} }

View File

@ -179,7 +179,7 @@ public class WebSocketEventDriver implements IncomingFrames
{ {
switch (frame.getOpCode()) switch (frame.getOpCode())
{ {
case CLOSE: case OpCode.CLOSE:
{ {
CloseInfo close = new CloseInfo(frame); CloseInfo close = new CloseInfo(frame);
if (events.onClose != null) if (events.onClose != null)
@ -188,7 +188,7 @@ public class WebSocketEventDriver implements IncomingFrames
} }
throw new CloseException(close.getStatusCode(),close.getReason()); throw new CloseException(close.getStatusCode(),close.getReason());
} }
case PING: case OpCode.PING:
{ {
WebSocketFrame pong = new WebSocketFrame(OpCode.PONG); WebSocketFrame pong = new WebSocketFrame(OpCode.PONG);
if (frame.getPayloadLength() > 0) if (frame.getPayloadLength() > 0)
@ -203,7 +203,7 @@ public class WebSocketEventDriver implements IncomingFrames
session.output("pong",new FutureCallback<String>(),pong); session.output("pong",new FutureCallback<String>(),pong);
break; break;
} }
case BINARY: case OpCode.BINARY:
{ {
if (events.onBinary == null) if (events.onBinary == null)
{ {
@ -273,7 +273,7 @@ public class WebSocketEventDriver implements IncomingFrames
} }
return; return;
} }
case TEXT: case OpCode.TEXT:
{ {
if (events.onText == null) if (events.onText == null)
{ {

View File

@ -114,7 +114,7 @@ public class DeflateFrameExtension extends Extension
@Override @Override
public void incoming(WebSocketFrame frame) public void incoming(WebSocketFrame frame)
{ {
if (frame.getOpCode().isControlFrame() || !frame.isRsv1()) if (frame.isControlFrame() || !frame.isRsv1())
{ {
// Cannot modify incoming control frames or ones with RSV1 set. // Cannot modify incoming control frames or ones with RSV1 set.
super.incoming(frame); super.incoming(frame);
@ -183,7 +183,7 @@ public class DeflateFrameExtension extends Extension
@Override @Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
{ {
if (frame.getOpCode().isControlFrame()) if (frame.isControlFrame())
{ {
// skip, cannot compress control frames. // skip, cannot compress control frames.
nextOutput(context,callback,frame); nextOutput(context,callback,frame);

View File

@ -31,7 +31,7 @@ public class FragmentExtension extends Extension
@Override @Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
{ {
if (frame.getOpCode().isControlFrame()) if (frame.isControlFrame())
{ {
// Cannot fragment Control Frames // Cannot fragment Control Frames
nextOutput(context,callback,frame); nextOutput(context,callback,frame);
@ -40,7 +40,7 @@ public class FragmentExtension extends Extension
int length = frame.getPayloadLength(); int length = frame.getPayloadLength();
OpCode opcode = frame.getOpCode(); // original opcode byte opcode = frame.getOpCode(); // original opcode
ByteBuffer payload = frame.getPayload().slice(); ByteBuffer payload = frame.getPayload().slice();
int originalLimit = payload.limit(); int originalLimit = payload.limit();
int currentPosition = payload.position(); int currentPosition = payload.position();

View File

@ -36,7 +36,7 @@ public class ControlFrameBytes<C> extends FrameBytes<C>
super.completed(context); super.completed(context);
if(frame.getOpCode() == OpCode.CLOSE) if (frame.getOpCode() == OpCode.CLOSE)
{ {
// Disconnect the connection (no more packets/frames) // Disconnect the connection (no more packets/frames)
connection.disconnect(false); connection.disconnect(false);

View File

@ -244,7 +244,7 @@ public abstract class WebSocketAsyncConnection extends AbstractAsyncConnection i
{ {
FrameBytes<C> bytes = null; FrameBytes<C> bytes = null;
if (frame.getOpCode().isControlFrame()) if (frame.isControlFrame())
{ {
bytes = new ControlFrameBytes<C>(this,callback,context,frame); bytes = new ControlFrameBytes<C>(this,callback,context,frame);
} }

View File

@ -26,7 +26,7 @@ public interface Frame
{ {
public byte[] getMask(); public byte[] getMask();
public OpCode getOpCode(); public byte getOpCode();
public ByteBuffer getPayload(); public ByteBuffer getPayload();

View File

@ -125,7 +125,7 @@ public class Generator
throw new ProtocolException("RSV3 not allowed to be set"); throw new ProtocolException("RSV3 not allowed to be set");
} }
if (frame.getOpCode().isControlFrame()) if (frame.isControlFrame())
{ {
/* /*
* RFC 6455 Section 5.5 * RFC 6455 Section 5.5
@ -229,12 +229,12 @@ public class Generator
b |= 0x10; b |= 0x10;
} }
byte opcode = frame.getOpCode().getCode(); byte opcode = frame.getOpCode();
if (frame.isContinuation()) if (frame.isContinuation())
{ {
// Continuations are not the same OPCODE // Continuations are not the same OPCODE
opcode = OpCode.CONTINUATION.getCode(); opcode = OpCode.CONTINUATION;
} }
b |= opcode & 0x0F; b |= opcode & 0x0F;

View File

@ -15,89 +15,92 @@
//======================================================================== //========================================================================
package org.eclipse.jetty.websocket.protocol; package org.eclipse.jetty.websocket.protocol;
import java.util.HashMap;
import java.util.Map;
public enum OpCode public final class OpCode
{ {
/** /**
* OpCode for a Continuation Frame * OpCode for a Continuation Frame
* *
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a> * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
*/ */
CONTINUATION((byte)0x00), public static final byte CONTINUATION = (byte)0x00;
/** /**
* OpCode for a Text Frame * OpCode for a Text Frame
* *
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a> * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
*/ */
TEXT((byte)0x01), public static final byte TEXT = (byte)0x01;
/** /**
* OpCode for a Binary Frame * OpCode for a Binary Frame
* *
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a> * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
*/ */
BINARY((byte)0x02), public static final byte BINARY = (byte)0x02;
/** /**
* OpCode for a Close Frame * OpCode for a Close Frame
* *
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a> * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
*/ */
CLOSE((byte)0x08), public static final byte CLOSE = (byte)0x08;
/** /**
* OpCode for a Ping Frame * OpCode for a Ping Frame
* *
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a> * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
*/ */
PING((byte)0x09), public static final byte PING = (byte)0x09;
/** /**
* OpCode for a Pong Frame * OpCode for a Pong Frame
* *
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a> * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
*/ */
PONG((byte)0x0A); public static final byte PONG = (byte)0x0A;
private static class Codes public static boolean isControlFrame(byte opcode)
{ {
private static final Map<Byte, OpCode> codes = new HashMap<>(); return (opcode >= CLOSE);
}
public static boolean isDataFrame(byte opcode)
{
return (opcode == TEXT) || (opcode == BINARY);
} }
/** /**
* Get OpCode from specified value. * Test for known opcodes (per the RFC spec)
* *
* @param opcode * @param opcode
* @return * the opcode to test
* @return true if known. false if unknown, undefined, or reserved
*/ */
public static OpCode from(byte opcode) public static boolean isKnown(byte opcode)
{ {
return Codes.codes.get(opcode); return (opcode == CONTINUATION) || (opcode == TEXT) || (opcode == BINARY) || (opcode == CLOSE) || (opcode == PING) || (opcode == PONG);
} }
private byte opcode; public static String name(byte opcode)
private OpCode(byte opcode)
{ {
this.opcode = opcode; switch (opcode)
Codes.codes.put(opcode,this); {
} case -1:
return "NO-OP";
public byte getCode() case CONTINUATION:
{ return "CONTINUATION";
return this.opcode; case TEXT:
} return "TEXT";
case BINARY: return "BINARY";
public boolean isControlFrame() case CLOSE:
{ return "CLOSE";
return (opcode >= CLOSE.opcode); case PING:
} return "PING";
case PONG:
public boolean isDataFrame() return "PONG";
{ default:
return (this == TEXT) || (this == BINARY); return "NON-SPEC[" + opcode + "]";
}
} }
} }

View File

@ -49,7 +49,7 @@ public class Parser
private int cursor = 0; private int cursor = 0;
// Frame // Frame
private WebSocketFrame frame; private WebSocketFrame frame;
private OpCode lastDataOpcode; private byte lastDataOpcode;
// payload specific // payload specific
private ByteBuffer payload; private ByteBuffer payload;
private int payloadLength; private int payloadLength;
@ -83,14 +83,14 @@ public class Parser
switch (frame.getOpCode()) switch (frame.getOpCode())
{ {
case CLOSE: case OpCode.CLOSE:
if (len == 1) if (len == 1)
{ {
throw new ProtocolException("Invalid close frame payload length, [" + payloadLength + "]"); throw new ProtocolException("Invalid close frame payload length, [" + payloadLength + "]");
} }
// fall thru // fall thru
case PING: case OpCode.PING:
case PONG: case OpCode.PONG:
if (len > WebSocketFrame.MAX_CONTROL_PAYLOAD) if (len > WebSocketFrame.MAX_CONTROL_PAYLOAD)
{ {
throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed [" throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed ["
@ -237,14 +237,14 @@ public class Parser
boolean rsv2 = ((b & 0x20) != 0); boolean rsv2 = ((b & 0x20) != 0);
boolean rsv3 = ((b & 0x10) != 0); boolean rsv3 = ((b & 0x10) != 0);
byte opc = (byte)(b & 0x0F); byte opc = (byte)(b & 0x0F);
OpCode opcode = OpCode.from(opc); byte opcode = opc;
if (opcode == null) if (!OpCode.isKnown(opcode))
{ {
throw new WebSocketException("Unknown opcode: " + opc); throw new ProtocolException("Unknown opcode: " + opc);
} }
LOG.debug("OpCode {}, fin={}",opcode.name(),fin); LOG.debug("OpCode {}, fin={}",OpCode.name(opcode),fin);
/* /*
* RFC 6455 Section 5.2 * RFC 6455 Section 5.2
@ -267,9 +267,9 @@ public class Parser
throw new ProtocolException("RSV3 not allowed to be set"); throw new ProtocolException("RSV3 not allowed to be set");
} }
if (opcode.isControlFrame() && !fin) if (OpCode.isControlFrame(opcode) && !fin)
{ {
throw new ProtocolException("Fragmented Control Frame [" + opcode.name() + "]"); throw new ProtocolException("Fragmented Control Frame [" + OpCode.name(opcode) + "]");
} }
if (opcode == OpCode.CONTINUATION) if (opcode == OpCode.CONTINUATION)
@ -290,7 +290,7 @@ public class Parser
frame.setRsv3(rsv3); frame.setRsv3(rsv3);
frame.setOpCode(opcode); frame.setOpCode(opcode);
if (opcode.isDataFrame()) if (frame.isDataFrame())
{ {
lastDataOpcode = opcode; lastDataOpcode = opcode;
} }

View File

@ -84,7 +84,7 @@ public class WebSocketFrame implements Frame
private boolean rsv1 = false; private boolean rsv1 = false;
private boolean rsv2 = false; private boolean rsv2 = false;
private boolean rsv3 = false; private boolean rsv3 = false;
private OpCode opcode = null; private byte opcode = -1;
private boolean masked = false; private boolean masked = false;
private byte mask[]; private byte mask[];
/** /**
@ -111,7 +111,7 @@ public class WebSocketFrame implements Frame
/** /**
* Construct form opcode * Construct form opcode
*/ */
public WebSocketFrame(OpCode opcode) public WebSocketFrame(byte opcode)
{ {
reset(); reset();
this.opcode = opcode; this.opcode = opcode;
@ -151,7 +151,7 @@ public class WebSocketFrame implements Frame
public void assertValid() public void assertValid()
{ {
if (opcode.isControlFrame()) if (OpCode.isControlFrame(opcode))
{ {
if (getPayloadLength() > WebSocketFrame.MAX_CONTROL_PAYLOAD) if (getPayloadLength() > WebSocketFrame.MAX_CONTROL_PAYLOAD)
{ {
@ -211,7 +211,7 @@ public class WebSocketFrame implements Frame
} }
@Override @Override
public final OpCode getOpCode() public final byte getOpCode()
{ {
return opcode; return opcode;
} }
@ -275,6 +275,16 @@ public class WebSocketFrame implements Frame
return continuation; return continuation;
} }
public boolean isControlFrame()
{
return OpCode.isControlFrame(opcode);
}
public boolean isDataFrame()
{
return OpCode.isDataFrame(opcode);
}
@Override @Override
public boolean isFin() public boolean isFin()
{ {
@ -348,7 +358,7 @@ public class WebSocketFrame implements Frame
rsv1 = false; rsv1 = false;
rsv2 = false; rsv2 = false;
rsv3 = false; rsv3 = false;
opcode = null; opcode = -1;
masked = false; masked = false;
data = null; data = null;
payloadLength = 0; payloadLength = 0;
@ -388,9 +398,9 @@ public class WebSocketFrame implements Frame
return this; return this;
} }
public WebSocketFrame setOpCode(OpCode opCode) public WebSocketFrame setOpCode(byte op)
{ {
this.opcode = opCode; this.opcode = op;
return this; return this;
} }
@ -408,7 +418,7 @@ public class WebSocketFrame implements Frame
return this; return this;
} }
if (opcode.isControlFrame()) if (OpCode.isControlFrame(opcode))
{ {
if (buf.length > WebSocketFrame.MAX_CONTROL_PAYLOAD) if (buf.length > WebSocketFrame.MAX_CONTROL_PAYLOAD)
{ {
@ -436,7 +446,7 @@ public class WebSocketFrame implements Frame
return this; return this;
} }
if (opcode.isControlFrame()) if (OpCode.isControlFrame(opcode))
{ {
if (len > WebSocketFrame.MAX_CONTROL_PAYLOAD) if (len > WebSocketFrame.MAX_CONTROL_PAYLOAD)
{ {
@ -468,7 +478,7 @@ public class WebSocketFrame implements Frame
return this; return this;
} }
if (opcode.isControlFrame()) if (OpCode.isControlFrame(opcode))
{ {
if (buf.remaining() > WebSocketFrame.MAX_CONTROL_PAYLOAD) if (buf.remaining() > WebSocketFrame.MAX_CONTROL_PAYLOAD)
{ {
@ -510,14 +520,7 @@ public class WebSocketFrame implements Frame
public String toString() public String toString()
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
if (opcode != null) b.append(OpCode.name(opcode));
{
b.append(opcode.name());
}
else
{
b.append("NO-OP");
}
b.append('['); b.append('[');
b.append("len=").append(payloadLength); b.append("len=").append(payloadLength);
b.append(",fin=").append(fin); b.append(",fin=").append(fin);

View File

@ -23,9 +23,6 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.protocol.CloseInfo;
import org.eclipse.jetty.websocket.protocol.OpCode;
import org.eclipse.jetty.websocket.protocol.Parser;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -43,7 +40,7 @@ public class ClosePayloadParserTest
payload.flip(); payload.flip();
ByteBuffer buf = ByteBuffer.allocate(24); ByteBuffer buf = ByteBuffer.allocate(24);
buf.put((byte)(0x80 | OpCode.CLOSE.getCode())); // fin + close buf.put((byte)(0x80 | OpCode.CLOSE)); // fin + close
buf.put((byte)(0x80 | payload.remaining())); buf.put((byte)(0x80 | payload.remaining()));
MaskedByteBuffer.putMask(buf); MaskedByteBuffer.putMask(buf);
MaskedByteBuffer.putPayload(buf,payload); MaskedByteBuffer.putPayload(buf,payload);

View File

@ -47,14 +47,14 @@ public class IncomingFramesCapture implements IncomingFrames
Assert.assertThat(errorType.getSimpleName(),getErrorCount(errorType),is(expectedCount)); Assert.assertThat(errorType.getSimpleName(),getErrorCount(errorType),is(expectedCount));
} }
public void assertHasFrame(OpCode op) public void assertHasFrame(byte op)
{ {
Assert.assertThat(op.name(),getFrameCount(op),greaterThanOrEqualTo(1)); Assert.assertThat(OpCode.name(op),getFrameCount(op),greaterThanOrEqualTo(1));
} }
public void assertHasFrame(OpCode op, int expectedCount) public void assertHasFrame(byte op, int expectedCount)
{ {
Assert.assertThat(op.name(),getFrameCount(op),is(expectedCount)); Assert.assertThat(OpCode.name(op),getFrameCount(op),is(expectedCount));
} }
public void assertHasNoFrames() public void assertHasNoFrames()
@ -95,7 +95,7 @@ public class IncomingFramesCapture implements IncomingFrames
return errors; return errors;
} }
public int getFrameCount(OpCode op) public int getFrameCount(byte op)
{ {
int count = 0; int count = 0;
for(WebSocketFrame frame: frames) { for(WebSocketFrame frame: frames) {

View File

@ -40,14 +40,14 @@ public class OutgoingFramesCapture implements OutgoingFrames
Assert.assertThat("Captured frame count",writes.size(),is(expectedCount)); Assert.assertThat("Captured frame count",writes.size(),is(expectedCount));
} }
public void assertHasFrame(OpCode op) public void assertHasFrame(byte op)
{ {
Assert.assertThat(op.name(),getFrameCount(op),greaterThanOrEqualTo(1)); Assert.assertThat(OpCode.name(op),getFrameCount(op),greaterThanOrEqualTo(1));
} }
public void assertHasFrame(OpCode op, int expectedCount) public void assertHasFrame(byte op, int expectedCount)
{ {
Assert.assertThat(op.name(),getFrameCount(op),is(expectedCount)); Assert.assertThat(OpCode.name(op),getFrameCount(op),is(expectedCount));
} }
public void assertHasNoFrames() public void assertHasNoFrames()
@ -66,7 +66,7 @@ public class OutgoingFramesCapture implements OutgoingFrames
} }
} }
public int getFrameCount(OpCode op) public int getFrameCount(byte op)
{ {
int count = 0; int count = 0;
for (Write<?> write : writes) for (Write<?> write : writes)

View File

@ -5,7 +5,7 @@ import org.junit.runners.Suite;
@RunWith(Suite.class) @RunWith(Suite.class)
@Suite.SuiteClasses( @Suite.SuiteClasses(
{ TestABCase1.class, TestABCase2.class, TestABCase3.class, TestABCase5.class, TestABCase7_9.class }) { TestABCase1.class, TestABCase2.class, TestABCase3.class, TestABCase4.class, TestABCase5.class, TestABCase7_9.class })
public class AllTests public class AllTests
{ {
/* let junit do the rest */ /* let junit do the rest */

View File

@ -111,6 +111,20 @@ public class Fuzzer
return slowSendSegmentSize; return slowSendSegmentSize;
} }
public void send(ByteBuffer buf) throws IOException
{
Assert.assertThat("Client connected",client.isConnected(),is(true));
LOG.debug("Sending bytes {}",BufferUtil.toDetailString(buf));
if (sendMode == SendMode.SLOW)
{
client.writeRawSlowly(buf,slowSendSegmentSize);
}
else
{
client.writeRaw(buf);
}
}
public void send(List<WebSocketFrame> send) throws IOException public void send(List<WebSocketFrame> send) throws IOException
{ {
Assert.assertThat("Client connected",client.isConnected(),is(true)); Assert.assertThat("Client connected",client.isConnected(),is(true));

View File

@ -0,0 +1,85 @@
package org.eclipse.jetty.websocket.server.ab;
import java.nio.ByteBuffer;
import java.util.ArrayList;
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.WebSocketFrame;
import org.junit.Test;
public class TestABCase4 extends AbstractABCase
{
/**
* Send opcode 3 (reserved)
*/
@Test
public void testCase4_1_1() throws Exception
{
ByteBuffer buf = ByteBuffer.allocate(32);
BufferUtil.clearToFill(buf);
// Construct bad frame by hand
byte opcode = 3;
buf.put((byte)(0x00 | FIN | opcode)); // bad
putPayloadLength(buf,0);
putMask(buf);
BufferUtil.flipToFlush(buf,0);
// Expectations
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(buf);
fuzzer.expect(expect);
}
finally
{
fuzzer.close();
}
}
/**
* Send opcode 4 (reserved), with payload
*/
@Test
public void testCase4_1_2() throws Exception
{
byte payload[] = StringUtil.getUtf8Bytes("reserved payload");
ByteBuffer buf = ByteBuffer.allocate(32);
BufferUtil.clearToFill(buf);
// Construct bad frame by hand
byte opcode = 4;
buf.put((byte)(0x00 | FIN | opcode)); // bad
putPayloadLength(buf,payload.length);
putMask(buf);
buf.put(masked(payload));
BufferUtil.flipToFlush(buf,0);
// Expectations
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(buf);
fuzzer.expect(expect);
}
finally
{
fuzzer.close();
}
}
}

View File

@ -85,7 +85,7 @@ public class TestABCase5
String fragment1 = "fragment1"; String fragment1 = "fragment1";
// Intentionally bad PING (spec says control frames must be FIN==true) // Intentionally bad PING (spec says control frames must be FIN==true)
buf.put((byte)(NOFIN | OpCode.PING.getCode())); buf.put((byte)(NOFIN | OpCode.PING));
byte b = 0x00; // no masking byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F; b |= fragment1.length() & 0x7F;
@ -100,7 +100,7 @@ public class TestABCase5
String fragment2 = "fragment2"; String fragment2 = "fragment2";
buf2.put((byte)(FIN | OpCode.PING.getCode())); buf2.put((byte)(FIN | OpCode.PING));
b = 0x00; // no masking b = 0x00; // no masking
b |= fragment2.length() & 0x7F; b |= fragment2.length() & 0x7F;
buf2.put(b); buf2.put(b);
@ -172,7 +172,7 @@ public class TestABCase5
String fragment1 = "fragment1"; String fragment1 = "fragment1";
buf.put((byte)(NOFIN | OpCode.PONG.getCode())); buf.put((byte)(NOFIN | OpCode.PONG));
byte b = 0x00; // no masking byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F; b |= fragment1.length() & 0x7F;
@ -187,7 +187,7 @@ public class TestABCase5
String fragment2 = "fragment2"; String fragment2 = "fragment2";
buf2.put((byte)(FIN | OpCode.CONTINUATION.getCode())); buf2.put((byte)(FIN | OpCode.CONTINUATION));
b = 0x00; // no masking b = 0x00; // no masking
b |= fragment2.length() & 0x7F; b |= fragment2.length() & 0x7F;
buf2.put(b); buf2.put(b);
@ -258,7 +258,7 @@ public class TestABCase5
String fragment1 = "fragment1"; String fragment1 = "fragment1";
buf.put((byte)(NOFIN | OpCode.TEXT.getCode())); buf.put((byte)(NOFIN | OpCode.TEXT));
byte b = 0x00; // no masking byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F; b |= fragment1.length() & 0x7F;
@ -273,7 +273,7 @@ public class TestABCase5
String fragment2 = "fragment2"; String fragment2 = "fragment2";
buf2.put((byte)(FIN | OpCode.CONTINUATION.getCode())); buf2.put((byte)(FIN | OpCode.CONTINUATION));
b = 0x00; // no masking b = 0x00; // no masking
b |= fragment2.length() & 0x7F; b |= fragment2.length() & 0x7F;
buf2.put(b); buf2.put(b);
@ -313,7 +313,7 @@ public class TestABCase5
String fragment1 = "fragment1"; String fragment1 = "fragment1";
buf.put((byte)(NOFIN | OpCode.TEXT.getCode())); buf.put((byte)(NOFIN | OpCode.TEXT));
byte b = 0x00; // no masking byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F; b |= fragment1.length() & 0x7F;
@ -330,7 +330,7 @@ public class TestABCase5
String pingPayload = "ping payload"; String pingPayload = "ping payload";
pingBuf.put((byte)(FIN | OpCode.PING.getCode())); pingBuf.put((byte)(FIN | OpCode.PING));
b = 0x00; // no masking b = 0x00; // no masking
b |= pingPayload.length() & 0x7F; b |= pingPayload.length() & 0x7F;
@ -347,7 +347,7 @@ public class TestABCase5
String fragment2 = "fragment2"; String fragment2 = "fragment2";
buf2.put((byte)(FIN | OpCode.CONTINUATION.getCode())); buf2.put((byte)(FIN | OpCode.CONTINUATION));
b = 0x00; // no masking b = 0x00; // no masking
b |= fragment2.length() & 0x7F; b |= fragment2.length() & 0x7F;
buf2.put(b); buf2.put(b);
@ -445,7 +445,7 @@ public class TestABCase5
// continuation w / FIN // continuation w / FIN
buf.put((byte)(FIN | OpCode.CONTINUATION.getCode())); buf.put((byte)(FIN | OpCode.CONTINUATION));
byte b = 0x00; // no masking byte b = 0x00; // no masking
b |= fragment1.length() & 0x7F; b |= fragment1.length() & 0x7F;

View File

@ -118,7 +118,7 @@ public class TestABCase7_9
BufferUtil.clearToFill(buf); BufferUtil.clearToFill(buf);
// Create Close Frame manually, as we are testing the server's behavior of a bad client. // Create Close Frame manually, as we are testing the server's behavior of a bad client.
buf.put((byte)(0x80 | OpCode.CLOSE.getCode())); buf.put((byte)(0x80 | OpCode.CLOSE));
buf.put((byte)(0x80 | 2)); buf.put((byte)(0x80 | 2));
byte mask[] = new byte[] byte mask[] = new byte[]
{ 0x44, 0x44, 0x44, 0x44 }; { 0x44, 0x44, 0x44, 0x44 };
@ -159,7 +159,7 @@ public class TestABCase7_9
BufferUtil.clearToFill(buf); BufferUtil.clearToFill(buf);
// Create Close Frame manually, as we are testing the server's behavior of a bad client. // Create Close Frame manually, as we are testing the server's behavior of a bad client.
buf.put((byte)(0x80 | OpCode.CLOSE.getCode())); buf.put((byte)(0x80 | OpCode.CLOSE));
buf.put((byte)(0x80 | (2 + reason.length()))); buf.put((byte)(0x80 | (2 + reason.length())));
byte mask[] = new byte[] byte mask[] = new byte[]
{ 0x44, 0x44, 0x44, 0x44 }; { 0x44, 0x44, 0x44, 0x44 };

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.websocket.annotations.OnWebSocketFrame;
import org.eclipse.jetty.websocket.annotations.WebSocket; import org.eclipse.jetty.websocket.annotations.WebSocket;
import org.eclipse.jetty.websocket.api.WebSocketConnection; import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.protocol.Frame; import org.eclipse.jetty.websocket.protocol.Frame;
import org.eclipse.jetty.websocket.protocol.OpCode;
/** /**
* Echo back the incoming text or binary as 2 frames of (roughly) equal size. * Echo back the incoming text or binary as 2 frames of (roughly) equal size.
@ -35,7 +36,7 @@ public class EchoFragmentSocket
@OnWebSocketFrame @OnWebSocketFrame
public void onFrame(WebSocketConnection conn, Frame frame) public void onFrame(WebSocketConnection conn, Frame frame)
{ {
if (!frame.getOpCode().isDataFrame()) if (!OpCode.isDataFrame(frame.getOpCode()))
{ {
return; return;
} }
@ -55,11 +56,11 @@ public class EchoFragmentSocket
{ {
switch (frame.getOpCode()) switch (frame.getOpCode())
{ {
case BINARY: case OpCode.BINARY:
conn.write(null,nop,buf1); conn.write(null,nop,buf1);
conn.write(null,nop,buf2); conn.write(null,nop,buf2);
break; break;
case TEXT: case OpCode.TEXT:
// NOTE: This impl is not smart enough to split on a UTF8 boundary // NOTE: This impl is not smart enough to split on a UTF8 boundary
conn.write(null,nop,BufferUtil.toUTF8String(buf1)); conn.write(null,nop,BufferUtil.toUTF8String(buf1));
conn.write(null,nop,BufferUtil.toUTF8String(buf2)); conn.write(null,nop,BufferUtil.toUTF8String(buf2));

View File

@ -49,14 +49,14 @@ public class IncomingFramesCapture implements IncomingFrames
Assert.assertThat(errorType.getSimpleName(),getErrorCount(errorType),is(expectedCount)); Assert.assertThat(errorType.getSimpleName(),getErrorCount(errorType),is(expectedCount));
} }
public void assertHasFrame(OpCode op) public void assertHasFrame(byte op)
{ {
Assert.assertThat(op.name(),getFrameCount(op),greaterThanOrEqualTo(1)); Assert.assertThat(OpCode.name(op),getFrameCount(op),greaterThanOrEqualTo(1));
} }
public void assertHasFrame(OpCode op, int expectedCount) public void assertHasFrame(byte op, int expectedCount)
{ {
Assert.assertThat(op.name(),getFrameCount(op),is(expectedCount)); Assert.assertThat(OpCode.name(op),getFrameCount(op),is(expectedCount));
} }
public void assertHasNoFrames() public void assertHasNoFrames()
@ -98,7 +98,7 @@ public class IncomingFramesCapture implements IncomingFrames
return errors; return errors;
} }
public int getFrameCount(OpCode op) public int getFrameCount(byte op)
{ {
int count = 0; int count = 0;
for (WebSocketFrame frame : frames) for (WebSocketFrame frame : frames)

View File

@ -42,14 +42,14 @@ public class OutgoingFramesCapture implements OutgoingFrames
Assert.assertThat("Captured frame count",writes.size(),is(expectedCount)); Assert.assertThat("Captured frame count",writes.size(),is(expectedCount));
} }
public void assertHasFrame(OpCode op) public void assertHasFrame(byte op)
{ {
Assert.assertThat(op.name(),getFrameCount(op),greaterThanOrEqualTo(1)); Assert.assertThat(OpCode.name(op),getFrameCount(op),greaterThanOrEqualTo(1));
} }
public void assertHasFrame(OpCode op, int expectedCount) public void assertHasFrame(byte op, int expectedCount)
{ {
Assert.assertThat(op.name(),getFrameCount(op),is(expectedCount)); Assert.assertThat(OpCode.name(op),getFrameCount(op),is(expectedCount));
} }
public void assertHasNoFrames() public void assertHasNoFrames()
@ -68,7 +68,7 @@ public class OutgoingFramesCapture implements OutgoingFrames
} }
} }
public int getFrameCount(OpCode op) public int getFrameCount(byte op)
{ {
int count = 0; int count = 0;
for (Write<?> write : writes) for (Write<?> write : writes)

View File

@ -9,7 +9,7 @@ org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF
# org.eclipse.jetty.websocket.io.WebSocketAsyncConnection.LEVEL=DEBUG # org.eclipse.jetty.websocket.io.WebSocketAsyncConnection.LEVEL=DEBUG
# org.eclipse.jetty.util.thread.QueuedThreadPool.LEVEL=DEBUG # org.eclipse.jetty.util.thread.QueuedThreadPool.LEVEL=DEBUG
# org.eclipse.jetty.io.SelectorManager.LEVEL=INFO # 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.driver.WebSocketEventDriver.LEVEL=DEBUG
# org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG # org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG
# org.eclipse.jetty.websocket.protocol.Generator.LEVEL=INFO # org.eclipse.jetty.websocket.protocol.Generator.LEVEL=INFO