Format code to align unaligned code. (#9062)
Motivation: Format code to align unaligned code. Modification: Reformat the code Result: Cleaner code
This commit is contained in:
parent
9c6365ee95
commit
18f27db194
@ -150,234 +150,234 @@ public class WebSocket08FrameDecoder extends ByteToMessageDecoder
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
|
|
||||||
// Discard all data received if closing handshake was received before.
|
// Discard all data received if closing handshake was received before.
|
||||||
if (receivedClosingHandshake) {
|
if (receivedClosingHandshake) {
|
||||||
in.skipBytes(actualReadableBytes());
|
in.skipBytes(actualReadableBytes());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (state) {
|
|
||||||
case READING_FIRST:
|
|
||||||
if (!in.isReadable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
framePayloadLength = 0;
|
switch (state) {
|
||||||
|
case READING_FIRST:
|
||||||
// FIN, RSV, OPCODE
|
if (!in.isReadable()) {
|
||||||
byte b = in.readByte();
|
return;
|
||||||
frameFinalFlag = (b & 0x80) != 0;
|
|
||||||
frameRsv = (b & 0x70) >> 4;
|
|
||||||
frameOpcode = b & 0x0F;
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Decoding WebSocket Frame opCode={}", frameOpcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
state = State.READING_SECOND;
|
|
||||||
case READING_SECOND:
|
|
||||||
if (!in.isReadable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// MASK, PAYLOAD LEN 1
|
|
||||||
b = in.readByte();
|
|
||||||
frameMasked = (b & 0x80) != 0;
|
|
||||||
framePayloadLen1 = b & 0x7F;
|
|
||||||
|
|
||||||
if (frameRsv != 0 && !allowExtensions) {
|
|
||||||
protocolViolation(ctx, "RSV != 0 and no extension negotiated, RSV:" + frameRsv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allowMaskMismatch && expectMaskedFrames != frameMasked) {
|
|
||||||
protocolViolation(ctx, "received a frame that is not masked as expected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frameOpcode > 7) { // control frame (have MSB in opcode set)
|
|
||||||
|
|
||||||
// control frames MUST NOT be fragmented
|
|
||||||
if (!frameFinalFlag) {
|
|
||||||
protocolViolation(ctx, "fragmented control frame");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// control frames MUST have payload 125 octets or less
|
|
||||||
if (framePayloadLen1 > 125) {
|
|
||||||
protocolViolation(ctx, "control frame with payload length > 125 octets");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for reserved control frame opcodes
|
|
||||||
if (!(frameOpcode == OPCODE_CLOSE || frameOpcode == OPCODE_PING
|
|
||||||
|| frameOpcode == OPCODE_PONG)) {
|
|
||||||
protocolViolation(ctx, "control frame using reserved opcode " + frameOpcode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// close frame : if there is a body, the first two bytes of the
|
|
||||||
// body MUST be a 2-byte unsigned integer (in network byte
|
|
||||||
// order) representing a getStatus code
|
|
||||||
if (frameOpcode == 8 && framePayloadLen1 == 1) {
|
|
||||||
protocolViolation(ctx, "received close control frame with payload len 1");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else { // data frame
|
|
||||||
// check for reserved data frame opcodes
|
|
||||||
if (!(frameOpcode == OPCODE_CONT || frameOpcode == OPCODE_TEXT
|
|
||||||
|| frameOpcode == OPCODE_BINARY)) {
|
|
||||||
protocolViolation(ctx, "data frame using reserved opcode " + frameOpcode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check opcode vs message fragmentation state 1/2
|
|
||||||
if (fragmentedFramesCount == 0 && frameOpcode == OPCODE_CONT) {
|
|
||||||
protocolViolation(ctx, "received continuation data frame outside fragmented message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check opcode vs message fragmentation state 2/2
|
|
||||||
if (fragmentedFramesCount != 0 && frameOpcode != OPCODE_CONT && frameOpcode != OPCODE_PING) {
|
|
||||||
protocolViolation(ctx,
|
|
||||||
"received non-continuation data frame while inside fragmented message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state = State.READING_SIZE;
|
|
||||||
case READING_SIZE:
|
|
||||||
|
|
||||||
// Read frame payload length
|
|
||||||
if (framePayloadLen1 == 126) {
|
|
||||||
if (in.readableBytes() < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
framePayloadLength = in.readUnsignedShort();
|
|
||||||
if (framePayloadLength < 126) {
|
|
||||||
protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (framePayloadLen1 == 127) {
|
|
||||||
if (in.readableBytes() < 8) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
framePayloadLength = in.readLong();
|
|
||||||
// TODO: check if it's bigger than 0x7FFFFFFFFFFFFFFF, Maybe
|
|
||||||
// just check if it's negative?
|
|
||||||
|
|
||||||
if (framePayloadLength < 65536) {
|
|
||||||
protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
framePayloadLength = framePayloadLen1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (framePayloadLength > maxFramePayloadLength) {
|
|
||||||
protocolViolation(ctx, "Max frame length of " + maxFramePayloadLength + " has been exceeded.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Decoding WebSocket Frame length={}", framePayloadLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
state = State.MASKING_KEY;
|
|
||||||
case MASKING_KEY:
|
|
||||||
if (frameMasked) {
|
|
||||||
if (in.readableBytes() < 4) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (maskingKey == null) {
|
|
||||||
maskingKey = new byte[4];
|
|
||||||
}
|
|
||||||
in.readBytes(maskingKey);
|
|
||||||
}
|
|
||||||
state = State.PAYLOAD;
|
|
||||||
case PAYLOAD:
|
|
||||||
if (in.readableBytes() < framePayloadLength) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuf payloadBuffer = null;
|
|
||||||
try {
|
|
||||||
payloadBuffer = readBytes(ctx.alloc(), in, toFrameLength(framePayloadLength));
|
|
||||||
|
|
||||||
// Now we have all the data, the next checkpoint must be the next
|
|
||||||
// frame
|
|
||||||
state = State.READING_FIRST;
|
|
||||||
|
|
||||||
// Unmask data if needed
|
|
||||||
if (frameMasked) {
|
|
||||||
unmask(payloadBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processing ping/pong/close frames because they cannot be
|
|
||||||
// fragmented
|
|
||||||
if (frameOpcode == OPCODE_PING) {
|
|
||||||
out.add(new PingWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
|
||||||
payloadBuffer = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frameOpcode == OPCODE_PONG) {
|
|
||||||
out.add(new PongWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
|
||||||
payloadBuffer = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frameOpcode == OPCODE_CLOSE) {
|
|
||||||
receivedClosingHandshake = true;
|
|
||||||
checkCloseFrameBody(ctx, payloadBuffer);
|
|
||||||
out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
|
||||||
payloadBuffer = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processing for possible fragmented messages for text and binary
|
|
||||||
// frames
|
|
||||||
if (frameFinalFlag) {
|
|
||||||
// Final frame of the sequence. Apparently ping frames are
|
|
||||||
// allowed in the middle of a fragmented message
|
|
||||||
if (frameOpcode != OPCODE_PING) {
|
|
||||||
fragmentedFramesCount = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Increment counter
|
|
||||||
fragmentedFramesCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the frame
|
|
||||||
if (frameOpcode == OPCODE_TEXT) {
|
|
||||||
out.add(new TextWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
|
||||||
payloadBuffer = null;
|
|
||||||
return;
|
|
||||||
} else if (frameOpcode == OPCODE_BINARY) {
|
|
||||||
out.add(new BinaryWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
|
||||||
payloadBuffer = null;
|
|
||||||
return;
|
|
||||||
} else if (frameOpcode == OPCODE_CONT) {
|
|
||||||
out.add(new ContinuationWebSocketFrame(frameFinalFlag, frameRsv,
|
|
||||||
payloadBuffer));
|
|
||||||
payloadBuffer = null;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: "
|
|
||||||
+ frameOpcode);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (payloadBuffer != null) {
|
|
||||||
payloadBuffer.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case CORRUPT:
|
|
||||||
if (in.isReadable()) {
|
|
||||||
// If we don't keep reading Netty will throw an exception saying
|
|
||||||
// we can't return null if no bytes read and state not changed.
|
|
||||||
in.readByte();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
throw new Error("Shouldn't reach here.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
framePayloadLength = 0;
|
||||||
|
|
||||||
|
// FIN, RSV, OPCODE
|
||||||
|
byte b = in.readByte();
|
||||||
|
frameFinalFlag = (b & 0x80) != 0;
|
||||||
|
frameRsv = (b & 0x70) >> 4;
|
||||||
|
frameOpcode = b & 0x0F;
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Decoding WebSocket Frame opCode={}", frameOpcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
state = State.READING_SECOND;
|
||||||
|
case READING_SECOND:
|
||||||
|
if (!in.isReadable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// MASK, PAYLOAD LEN 1
|
||||||
|
b = in.readByte();
|
||||||
|
frameMasked = (b & 0x80) != 0;
|
||||||
|
framePayloadLen1 = b & 0x7F;
|
||||||
|
|
||||||
|
if (frameRsv != 0 && !allowExtensions) {
|
||||||
|
protocolViolation(ctx, "RSV != 0 and no extension negotiated, RSV:" + frameRsv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allowMaskMismatch && expectMaskedFrames != frameMasked) {
|
||||||
|
protocolViolation(ctx, "received a frame that is not masked as expected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameOpcode > 7) { // control frame (have MSB in opcode set)
|
||||||
|
|
||||||
|
// control frames MUST NOT be fragmented
|
||||||
|
if (!frameFinalFlag) {
|
||||||
|
protocolViolation(ctx, "fragmented control frame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// control frames MUST have payload 125 octets or less
|
||||||
|
if (framePayloadLen1 > 125) {
|
||||||
|
protocolViolation(ctx, "control frame with payload length > 125 octets");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for reserved control frame opcodes
|
||||||
|
if (!(frameOpcode == OPCODE_CLOSE || frameOpcode == OPCODE_PING
|
||||||
|
|| frameOpcode == OPCODE_PONG)) {
|
||||||
|
protocolViolation(ctx, "control frame using reserved opcode " + frameOpcode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// close frame : if there is a body, the first two bytes of the
|
||||||
|
// body MUST be a 2-byte unsigned integer (in network byte
|
||||||
|
// order) representing a getStatus code
|
||||||
|
if (frameOpcode == 8 && framePayloadLen1 == 1) {
|
||||||
|
protocolViolation(ctx, "received close control frame with payload len 1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else { // data frame
|
||||||
|
// check for reserved data frame opcodes
|
||||||
|
if (!(frameOpcode == OPCODE_CONT || frameOpcode == OPCODE_TEXT
|
||||||
|
|| frameOpcode == OPCODE_BINARY)) {
|
||||||
|
protocolViolation(ctx, "data frame using reserved opcode " + frameOpcode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check opcode vs message fragmentation state 1/2
|
||||||
|
if (fragmentedFramesCount == 0 && frameOpcode == OPCODE_CONT) {
|
||||||
|
protocolViolation(ctx, "received continuation data frame outside fragmented message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check opcode vs message fragmentation state 2/2
|
||||||
|
if (fragmentedFramesCount != 0 && frameOpcode != OPCODE_CONT && frameOpcode != OPCODE_PING) {
|
||||||
|
protocolViolation(ctx,
|
||||||
|
"received non-continuation data frame while inside fragmented message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state = State.READING_SIZE;
|
||||||
|
case READING_SIZE:
|
||||||
|
|
||||||
|
// Read frame payload length
|
||||||
|
if (framePayloadLen1 == 126) {
|
||||||
|
if (in.readableBytes() < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
framePayloadLength = in.readUnsignedShort();
|
||||||
|
if (framePayloadLength < 126) {
|
||||||
|
protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (framePayloadLen1 == 127) {
|
||||||
|
if (in.readableBytes() < 8) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
framePayloadLength = in.readLong();
|
||||||
|
// TODO: check if it's bigger than 0x7FFFFFFFFFFFFFFF, Maybe
|
||||||
|
// just check if it's negative?
|
||||||
|
|
||||||
|
if (framePayloadLength < 65536) {
|
||||||
|
protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
framePayloadLength = framePayloadLen1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (framePayloadLength > maxFramePayloadLength) {
|
||||||
|
protocolViolation(ctx, "Max frame length of " + maxFramePayloadLength + " has been exceeded.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Decoding WebSocket Frame length={}", framePayloadLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
state = State.MASKING_KEY;
|
||||||
|
case MASKING_KEY:
|
||||||
|
if (frameMasked) {
|
||||||
|
if (in.readableBytes() < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (maskingKey == null) {
|
||||||
|
maskingKey = new byte[4];
|
||||||
|
}
|
||||||
|
in.readBytes(maskingKey);
|
||||||
|
}
|
||||||
|
state = State.PAYLOAD;
|
||||||
|
case PAYLOAD:
|
||||||
|
if (in.readableBytes() < framePayloadLength) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf payloadBuffer = null;
|
||||||
|
try {
|
||||||
|
payloadBuffer = readBytes(ctx.alloc(), in, toFrameLength(framePayloadLength));
|
||||||
|
|
||||||
|
// Now we have all the data, the next checkpoint must be the next
|
||||||
|
// frame
|
||||||
|
state = State.READING_FIRST;
|
||||||
|
|
||||||
|
// Unmask data if needed
|
||||||
|
if (frameMasked) {
|
||||||
|
unmask(payloadBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing ping/pong/close frames because they cannot be
|
||||||
|
// fragmented
|
||||||
|
if (frameOpcode == OPCODE_PING) {
|
||||||
|
out.add(new PingWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
||||||
|
payloadBuffer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (frameOpcode == OPCODE_PONG) {
|
||||||
|
out.add(new PongWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
||||||
|
payloadBuffer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (frameOpcode == OPCODE_CLOSE) {
|
||||||
|
receivedClosingHandshake = true;
|
||||||
|
checkCloseFrameBody(ctx, payloadBuffer);
|
||||||
|
out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
||||||
|
payloadBuffer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing for possible fragmented messages for text and binary
|
||||||
|
// frames
|
||||||
|
if (frameFinalFlag) {
|
||||||
|
// Final frame of the sequence. Apparently ping frames are
|
||||||
|
// allowed in the middle of a fragmented message
|
||||||
|
if (frameOpcode != OPCODE_PING) {
|
||||||
|
fragmentedFramesCount = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Increment counter
|
||||||
|
fragmentedFramesCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the frame
|
||||||
|
if (frameOpcode == OPCODE_TEXT) {
|
||||||
|
out.add(new TextWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
||||||
|
payloadBuffer = null;
|
||||||
|
return;
|
||||||
|
} else if (frameOpcode == OPCODE_BINARY) {
|
||||||
|
out.add(new BinaryWebSocketFrame(frameFinalFlag, frameRsv, payloadBuffer));
|
||||||
|
payloadBuffer = null;
|
||||||
|
return;
|
||||||
|
} else if (frameOpcode == OPCODE_CONT) {
|
||||||
|
out.add(new ContinuationWebSocketFrame(frameFinalFlag, frameRsv,
|
||||||
|
payloadBuffer));
|
||||||
|
payloadBuffer = null;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: "
|
||||||
|
+ frameOpcode);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (payloadBuffer != null) {
|
||||||
|
payloadBuffer.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case CORRUPT:
|
||||||
|
if (in.isReadable()) {
|
||||||
|
// If we don't keep reading Netty will throw an exception saying
|
||||||
|
// we can't return null if no bytes read and state not changed.
|
||||||
|
in.readByte();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw new Error("Shouldn't reach here.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unmask(ByteBuf frame) {
|
private void unmask(ByteBuf frame) {
|
||||||
|
Loading…
Reference in New Issue
Block a user