[#1352] WebSocketFrameAggregator should only throw TooLongFrameException once per complete frame
This commit is contained in:
parent
c8de4f03f1
commit
3268d6fc2e
@ -31,6 +31,7 @@ import io.netty.handler.codec.TooLongFrameException;
|
|||||||
public class WebSocketFrameAggregator extends MessageToMessageDecoder<WebSocketFrame> {
|
public class WebSocketFrameAggregator extends MessageToMessageDecoder<WebSocketFrame> {
|
||||||
private final int maxFrameSize;
|
private final int maxFrameSize;
|
||||||
private WebSocketFrame currentFrame;
|
private WebSocketFrame currentFrame;
|
||||||
|
private boolean tooLongFrameFound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new instance
|
* Construct a new instance
|
||||||
@ -48,6 +49,7 @@ public class WebSocketFrameAggregator extends MessageToMessageDecoder<WebSocketF
|
|||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, MessageBuf<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, MessageBuf<Object> out) throws Exception {
|
||||||
if (currentFrame == null) {
|
if (currentFrame == null) {
|
||||||
|
tooLongFrameFound = false;
|
||||||
if (msg.isFinalFragment()) {
|
if (msg.isFinalFragment()) {
|
||||||
out.add(msg.retain());
|
out.add(msg.retain());
|
||||||
return;
|
return;
|
||||||
@ -66,8 +68,15 @@ public class WebSocketFrameAggregator extends MessageToMessageDecoder<WebSocketF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg instanceof ContinuationWebSocketFrame) {
|
if (msg instanceof ContinuationWebSocketFrame) {
|
||||||
|
if (tooLongFrameFound) {
|
||||||
|
if (msg.isFinalFragment()) {
|
||||||
|
currentFrame = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
CompositeByteBuf content = (CompositeByteBuf) currentFrame.content();
|
CompositeByteBuf content = (CompositeByteBuf) currentFrame.content();
|
||||||
if (content.readableBytes() > maxFrameSize - msg.content().readableBytes()) {
|
if (content.readableBytes() > maxFrameSize - msg.content().readableBytes()) {
|
||||||
|
tooLongFrameFound = true;
|
||||||
throw new TooLongFrameException(
|
throw new TooLongFrameException(
|
||||||
"WebSocketFrame length exceeded " + content +
|
"WebSocketFrame length exceeded " + content +
|
||||||
" bytes.");
|
" bytes.");
|
||||||
|
@ -101,11 +101,29 @@ public class WebSocketFrameAggregatorTest {
|
|||||||
Assert.assertNull(channel.readInbound());
|
Assert.assertNull(channel.readInbound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooLongFrameException.class)
|
@Test
|
||||||
public void textFrameTooBig() {
|
public void textFrameTooBig() {
|
||||||
EmbeddedMessageChannel channel = new EmbeddedMessageChannel(new WebSocketFrameAggregator(8));
|
EmbeddedMessageChannel channel = new EmbeddedMessageChannel(new WebSocketFrameAggregator(8));
|
||||||
channel.writeInbound(new BinaryWebSocketFrame(true, 1, content1.copy()));
|
channel.writeInbound(new BinaryWebSocketFrame(true, 1, content1.copy()));
|
||||||
channel.writeInbound(new BinaryWebSocketFrame(false, 0, content1.copy()));
|
channel.writeInbound(new BinaryWebSocketFrame(false, 0, content1.copy()));
|
||||||
|
try {
|
||||||
|
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, content2.copy()));
|
||||||
|
Assert.fail();
|
||||||
|
} catch (TooLongFrameException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, content2.copy()));
|
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, content2.copy()));
|
||||||
|
channel.writeInbound(new ContinuationWebSocketFrame(true, 0, content2.copy()));
|
||||||
|
|
||||||
|
channel.writeInbound(new BinaryWebSocketFrame(true, 1, content1.copy()));
|
||||||
|
channel.writeInbound(new BinaryWebSocketFrame(false, 0, content1.copy()));
|
||||||
|
try {
|
||||||
|
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, content2.copy()));
|
||||||
|
Assert.fail();
|
||||||
|
} catch (TooLongFrameException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, content2.copy()));
|
||||||
|
channel.writeInbound(new ContinuationWebSocketFrame(true, 0, content2.copy()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user