use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class WebSocket00FrameDecoder method decodeBinaryFrame.
private WebSocketFrame decodeBinaryFrame(ChannelHandlerContext ctx, byte type, ByteBuf buffer) {
long frameSize = 0;
int lengthFieldSize = 0;
byte b;
do {
b = buffer.readByte();
frameSize <<= 7;
frameSize |= b & 0x7f;
if (frameSize > maxFrameSize) {
throw new TooLongFrameException();
}
lengthFieldSize++;
if (lengthFieldSize > 8) {
// Perhaps a malicious peer?
throw new TooLongFrameException();
}
} while ((b & 0x80) == 0x80);
if (type == (byte) 0xFF && frameSize == 0) {
receivedClosingHandshake = true;
return new CloseWebSocketFrame(true, 0, ctx.alloc().buffer(0));
}
ByteBuf payload = readBytes(ctx.alloc(), buffer, (int) frameSize);
return new BinaryWebSocketFrame(payload);
}
use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class WebSocket08FrameEncoder method encode.
@Override
protected void encode(ChannelHandlerContext ctx, WebSocketFrame msg, List<Object> out) throws Exception {
final ByteBuf data = msg.content();
byte[] mask;
byte opcode;
if (msg instanceof TextWebSocketFrame) {
opcode = OPCODE_TEXT;
} else if (msg instanceof PingWebSocketFrame) {
opcode = OPCODE_PING;
} else if (msg instanceof PongWebSocketFrame) {
opcode = OPCODE_PONG;
} else if (msg instanceof CloseWebSocketFrame) {
opcode = OPCODE_CLOSE;
} else if (msg instanceof BinaryWebSocketFrame) {
opcode = OPCODE_BINARY;
} else if (msg instanceof ContinuationWebSocketFrame) {
opcode = OPCODE_CONT;
} else {
throw new UnsupportedOperationException("Cannot encode frame of type: " + msg.getClass().getName());
}
int length = data.readableBytes();
if (logger.isTraceEnabled()) {
logger.trace("Encoding WebSocket Frame opCode={} length={}", opcode, length);
}
int b0 = 0;
if (msg.isFinalFragment()) {
b0 |= 1 << 7;
}
b0 |= msg.rsv() % 8 << 4;
b0 |= opcode % 128;
if (opcode == OPCODE_PING && length > 125) {
throw new TooLongFrameException("invalid payload for PING (payload length must be <= 125, was " + length);
}
boolean release = true;
ByteBuf buf = null;
try {
int maskLength = maskPayload ? 4 : 0;
if (length <= 125) {
int size = 2 + maskLength;
if (maskPayload || length <= GATHERING_WRITE_THRESHOLD) {
size += length;
}
buf = ctx.alloc().buffer(size);
buf.writeByte(b0);
byte b = (byte) (maskPayload ? 0x80 | (byte) length : (byte) length);
buf.writeByte(b);
} else if (length <= 0xFFFF) {
int size = 4 + maskLength;
if (maskPayload || length <= GATHERING_WRITE_THRESHOLD) {
size += length;
}
buf = ctx.alloc().buffer(size);
buf.writeByte(b0);
buf.writeByte(maskPayload ? 0xFE : 126);
buf.writeByte(length >>> 8 & 0xFF);
buf.writeByte(length & 0xFF);
} else {
int size = 10 + maskLength;
if (maskPayload || length <= GATHERING_WRITE_THRESHOLD) {
size += length;
}
buf = ctx.alloc().buffer(size);
buf.writeByte(b0);
buf.writeByte(maskPayload ? 0xFF : 127);
buf.writeLong(length);
}
// Write payload
if (maskPayload) {
int random = PlatformDependent.threadLocalRandom().nextInt(Integer.MAX_VALUE);
mask = ByteBuffer.allocate(4).putInt(random).array();
buf.writeBytes(mask);
ByteOrder srcOrder = data.order();
ByteOrder dstOrder = buf.order();
int counter = 0;
int i = data.readerIndex();
int end = data.writerIndex();
if (srcOrder == dstOrder) {
// Use the optimized path only when byte orders match
// Remark: & 0xFF is necessary because Java will do signed expansion from
// byte to int which we don't want.
int intMask = ((mask[0] & 0xFF) << 24) | ((mask[1] & 0xFF) << 16) | ((mask[2] & 0xFF) << 8) | (mask[3] & 0xFF);
// into the same format, because getInt() and writeInt() will use a reversed byte order
if (srcOrder == ByteOrder.LITTLE_ENDIAN) {
intMask = Integer.reverseBytes(intMask);
}
for (; i + 3 < end; i += 4) {
int intData = data.getInt(i);
buf.writeInt(intData ^ intMask);
}
}
for (; i < end; i++) {
byte byteData = data.getByte(i);
buf.writeByte(byteData ^ mask[counter++ % 4]);
}
out.add(buf);
} else {
if (buf.writableBytes() >= data.readableBytes()) {
// merge buffers as this is cheaper then a gathering write if the payload is small enough
buf.writeBytes(data);
out.add(buf);
} else {
out.add(buf);
out.add(data.retain());
}
}
release = false;
} finally {
if (release && buf != null) {
buf.release();
}
}
}
use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class DelimiterBasedFrameDecoderTest method testFailSlowTooLongFrameRecovery.
@Test
public void testFailSlowTooLongFrameRecovery() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new DelimiterBasedFrameDecoder(1, true, false, Delimiters.nulDelimiter()));
for (int i = 0; i < 2; i++) {
ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 1, 2 }));
try {
assertTrue(ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 0 })));
fail(DecoderException.class.getSimpleName() + " must be raised.");
} catch (TooLongFrameException e) {
// Expected
}
ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 'A', 0 }));
ByteBuf buf = ch.readInbound();
assertEquals("A", buf.toString(CharsetUtil.ISO_8859_1));
buf.release();
}
}
use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class DelimiterBasedFrameDecoderTest method testFailFastTooLongFrameRecovery.
@Test
public void testFailFastTooLongFrameRecovery() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new DelimiterBasedFrameDecoder(1, Delimiters.nulDelimiter()));
for (int i = 0; i < 2; i++) {
try {
assertTrue(ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 1, 2 })));
fail(DecoderException.class.getSimpleName() + " must be raised.");
} catch (TooLongFrameException e) {
// Expected
}
ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 0, 'A', 0 }));
ByteBuf buf = ch.readInbound();
assertEquals("A", buf.toString(CharsetUtil.ISO_8859_1));
buf.release();
}
}
use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class LengthFieldBasedFrameDecoderTest method testFailFastTooLongFrameRecovery.
@Test
public void testFailFastTooLongFrameRecovery() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new LengthFieldBasedFrameDecoder(5, 0, 4, 0, 4));
for (int i = 0; i < 2; i++) {
try {
assertTrue(ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 0, 0, 0, 2 })));
fail(DecoderException.class.getSimpleName() + " must be raised.");
} catch (TooLongFrameException e) {
// Expected
}
ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { 0, 0, 0, 0, 0, 1, 'A' }));
ByteBuf buf = ch.readInbound();
assertEquals("A", buf.toString(CharsetUtil.ISO_8859_1));
buf.release();
}
}
Aggregations