use of org.eclipse.jetty.websocket.api.ProtocolException in project jetty.project by eclipse.
the class TestABCase4 method testParserNonControlOpCode3Case4_1_1.
@Test
public void testParserNonControlOpCode3Case4_1_1() throws Exception {
ByteBuffer expected = ByteBuffer.allocate(32);
expected.put(new byte[] { (byte) 0x83, 0x00 });
expected.flip();
IncomingFramesCapture capture = new IncomingFramesCapture();
try (StacklessLogging logging = new StacklessLogging(Parser.class)) {
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
try {
parser.parse(expected);
} catch (ProtocolException ignore) {
// ignore
}
}
Assert.assertEquals("error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
Assert.assertTrue("undefined option should be in message", known.getMessage().contains("Unknown opcode: 3"));
}
use of org.eclipse.jetty.websocket.api.ProtocolException in project jetty.project by eclipse.
the class TestABCase4 method testParserControlOpCode12WithPayloadCase4_2_2.
@Test
public void testParserControlOpCode12WithPayloadCase4_2_2() throws Exception {
ByteBuffer expected = ByteBuffer.allocate(32);
expected.put(new byte[] { (byte) 0x8c, 0x01, 0x00 });
expected.flip();
IncomingFramesCapture capture = new IncomingFramesCapture();
try (StacklessLogging logging = new StacklessLogging(Parser.class)) {
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
try {
parser.parse(expected);
} catch (ProtocolException ignore) {
// ignore
}
}
Assert.assertEquals("error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
Assert.assertTrue("undefined option should be in message", known.getMessage().contains("Unknown opcode: 12"));
}
use of org.eclipse.jetty.websocket.api.ProtocolException in project jetty.project by eclipse.
the class TestABCase4 method testParserControlOpCode11Case4_2_1.
@Test
public void testParserControlOpCode11Case4_2_1() throws Exception {
ByteBuffer expected = ByteBuffer.allocate(32);
expected.put(new byte[] { (byte) 0x8b, 0x00 });
expected.flip();
IncomingFramesCapture capture = new IncomingFramesCapture();
try (StacklessLogging logging = new StacklessLogging(Parser.class)) {
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
try {
parser.parse(expected);
} catch (ProtocolException ignore) {
// ignore
}
}
Assert.assertEquals("error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
Assert.assertTrue("undefined option should be in message", known.getMessage().contains("Unknown opcode: 11"));
}
use of org.eclipse.jetty.websocket.api.ProtocolException in project jetty.project by eclipse.
the class Parser method parseFrame.
/**
* Parse the base framing protocol buffer.
* <p>
* Note the first byte (fin,rsv1,rsv2,rsv3,opcode) are parsed by the {@link Parser#parse(ByteBuffer)} method
* <p>
* Not overridable
*
* @param buffer
* the buffer to parse from.
* @return true if done parsing base framing protocol and ready for parsing of the payload. false if incomplete parsing of base framing protocol.
*/
private boolean parseFrame(ByteBuffer buffer) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} Parsing {} bytes", policy.getBehavior(), buffer.remaining());
}
while (buffer.hasRemaining()) {
switch(state) {
case START:
{
// peek at byte
byte b = buffer.get();
boolean fin = ((b & 0x80) != 0);
byte opcode = (byte) (b & 0x0F);
if (!OpCode.isKnown(opcode)) {
throw new ProtocolException("Unknown opcode: " + opcode);
}
if (LOG.isDebugEnabled())
LOG.debug("{} OpCode {}, fin={} rsv={}{}{}", policy.getBehavior(), OpCode.name(opcode), fin, (((b & 0x40) != 0) ? '1' : '.'), (((b & 0x20) != 0) ? '1' : '.'), (((b & 0x10) != 0) ? '1' : '.'));
// base framing flags
switch(opcode) {
case OpCode.TEXT:
frame = new TextFrame();
// data validation
if (priorDataFrame) {
throw new ProtocolException("Unexpected " + OpCode.name(opcode) + " frame, was expecting CONTINUATION");
}
break;
case OpCode.BINARY:
frame = new BinaryFrame();
// data validation
if (priorDataFrame) {
throw new ProtocolException("Unexpected " + OpCode.name(opcode) + " frame, was expecting CONTINUATION");
}
break;
case OpCode.CONTINUATION:
frame = new ContinuationFrame();
// continuation validation
if (!priorDataFrame) {
throw new ProtocolException("CONTINUATION frame without prior !FIN");
}
// Be careful to use the original opcode
break;
case OpCode.CLOSE:
frame = new CloseFrame();
// control frame validation
if (!fin) {
throw new ProtocolException("Fragmented Close Frame [" + OpCode.name(opcode) + "]");
}
break;
case OpCode.PING:
frame = new PingFrame();
// control frame validation
if (!fin) {
throw new ProtocolException("Fragmented Ping Frame [" + OpCode.name(opcode) + "]");
}
break;
case OpCode.PONG:
frame = new PongFrame();
// control frame validation
if (!fin) {
throw new ProtocolException("Fragmented Pong Frame [" + OpCode.name(opcode) + "]");
}
break;
}
frame.setFin(fin);
// Are any flags set?
if ((b & 0x70) != 0) {
/*
* 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 ((b & 0x40) != 0) {
if (isRsv1InUse())
frame.setRsv1(true);
else {
String err = "RSV1 not allowed to be set";
if (LOG.isDebugEnabled()) {
LOG.debug(err + ": Remaining buffer: {}", BufferUtil.toDetailString(buffer));
}
throw new ProtocolException(err);
}
}
if ((b & 0x20) != 0) {
if (isRsv2InUse())
frame.setRsv2(true);
else {
String err = "RSV2 not allowed to be set";
if (LOG.isDebugEnabled()) {
LOG.debug(err + ": Remaining buffer: {}", BufferUtil.toDetailString(buffer));
}
throw new ProtocolException(err);
}
}
if ((b & 0x10) != 0) {
if (isRsv3InUse())
frame.setRsv3(true);
else {
String err = "RSV3 not allowed to be set";
if (LOG.isDebugEnabled()) {
LOG.debug(err + ": Remaining buffer: {}", BufferUtil.toDetailString(buffer));
}
throw new ProtocolException(err);
}
}
}
state = State.PAYLOAD_LEN;
break;
}
case PAYLOAD_LEN:
{
byte b = buffer.get();
frame.setMasked((b & 0x80) != 0);
payloadLength = (byte) (0x7F & b);
if (// 0x7F
payloadLength == 127) {
// length 8 bytes (extended payload length)
payloadLength = 0;
state = State.PAYLOAD_LEN_BYTES;
cursor = 8;
// continue onto next state
break;
} else if (// 0x7E
payloadLength == 126) {
// length 2 bytes (extended payload length)
payloadLength = 0;
state = State.PAYLOAD_LEN_BYTES;
cursor = 2;
// continue onto next state
break;
}
assertSanePayloadLength(payloadLength);
if (frame.isMasked()) {
state = State.MASK;
} else {
// special case for empty payloads (no more bytes left in buffer)
if (payloadLength == 0) {
state = State.START;
return true;
}
maskProcessor.reset(frame);
state = State.PAYLOAD;
}
break;
}
case PAYLOAD_LEN_BYTES:
{
byte b = buffer.get();
--cursor;
payloadLength |= (b & 0xFF) << (8 * cursor);
if (cursor == 0) {
assertSanePayloadLength(payloadLength);
if (frame.isMasked()) {
state = State.MASK;
} else {
// special case for empty payloads (no more bytes left in buffer)
if (payloadLength == 0) {
state = State.START;
return true;
}
maskProcessor.reset(frame);
state = State.PAYLOAD;
}
}
break;
}
case MASK:
{
byte[] m = new byte[4];
frame.setMask(m);
if (buffer.remaining() >= 4) {
buffer.get(m, 0, 4);
// special case for empty payloads (no more bytes left in buffer)
if (payloadLength == 0) {
state = State.START;
return true;
}
maskProcessor.reset(frame);
state = State.PAYLOAD;
} else {
state = State.MASK_BYTES;
cursor = 4;
}
break;
}
case MASK_BYTES:
{
byte b = buffer.get();
frame.getMask()[4 - cursor] = b;
--cursor;
if (cursor == 0) {
// special case for empty payloads (no more bytes left in buffer)
if (payloadLength == 0) {
state = State.START;
return true;
}
maskProcessor.reset(frame);
state = State.PAYLOAD;
}
break;
}
case PAYLOAD:
{
frame.assertValid();
if (parsePayload(buffer)) {
// special check for close
if (frame.getOpCode() == OpCode.CLOSE) {
// TODO: yuck. Don't create an object to do validation checks!
new CloseInfo(frame);
}
state = State.START;
// we have a frame!
return true;
}
break;
}
}
}
return false;
}
use of org.eclipse.jetty.websocket.api.ProtocolException in project jetty.project by eclipse.
the class CloseInfo method asFrame.
public CloseFrame asFrame() {
CloseFrame frame = new CloseFrame();
frame.setFin(true);
if ((statusCode >= 1000) && (statusCode != StatusCode.NO_CLOSE) && (statusCode != StatusCode.NO_CODE)) {
if (statusCode == StatusCode.FAILED_TLS_HANDSHAKE) {
throw new ProtocolException("Close Frame with status code " + statusCode + " not allowed (per RFC6455)");
}
frame.setPayload(asByteBuffer());
}
return frame;
}
Aggregations