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,
(isRsv1InUse()?'1':'.'),
(isRsv2InUse()?'1':'.'),
(isRsv3InUse()?'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
throw new ProtocolException("RSV1 not allowed to be set");
}
if ((b & 0x20) != 0)
{
if (isRsv2InUse())
frame.setRsv2(true);
else
throw new ProtocolException("RSV2 not allowed to be set");
}
if ((b & 0x10) != 0)
{
if (isRsv3InUse())
frame.setRsv3(true);
else
throw new ProtocolException("RSV3 not allowed to be set");
}
}
state = State.PAYLOAD_LEN;
break;