use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class CompatibleMarshallingDecoder method decode.
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
if (discardingTooLongFrame) {
buffer.skipBytes(actualReadableBytes());
checkpoint();
return;
}
Unmarshaller unmarshaller = provider.getUnmarshaller(ctx);
ByteInput input = new ChannelBufferByteInput(buffer);
if (maxObjectSize != Integer.MAX_VALUE) {
input = new LimitingByteInput(input, maxObjectSize);
}
try {
unmarshaller.start(input);
Object obj = unmarshaller.readObject();
unmarshaller.finish();
out.add(obj);
} catch (LimitingByteInput.TooBigObjectException ignored) {
discardingTooLongFrame = true;
throw new TooLongFrameException();
} finally {
// Call close in a finally block as the ReplayingDecoder will throw an Error if not enough bytes are
// readable. This helps to be sure that we do not leak resource
unmarshaller.close();
}
}
use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class WebSocketFrameAggregatorTest method textFrameTooBig.
@Test
public void textFrameTooBig() throws Exception {
EmbeddedChannel channel = new EmbeddedChannel(new WebSocketFrameAggregator(8));
channel.writeInbound(new BinaryWebSocketFrame(true, 1, Unpooled.wrappedBuffer(content1)));
channel.writeInbound(new BinaryWebSocketFrame(false, 0, Unpooled.wrappedBuffer(content1)));
try {
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, Unpooled.wrappedBuffer(content2)));
fail();
} catch (TooLongFrameException e) {
// expected
}
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, Unpooled.wrappedBuffer(content2)));
channel.writeInbound(new ContinuationWebSocketFrame(true, 0, Unpooled.wrappedBuffer(content2)));
channel.writeInbound(new BinaryWebSocketFrame(true, 1, Unpooled.wrappedBuffer(content1)));
channel.writeInbound(new BinaryWebSocketFrame(false, 0, Unpooled.wrappedBuffer(content1)));
try {
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, Unpooled.wrappedBuffer(content2)));
fail();
} catch (TooLongFrameException e) {
// expected
}
channel.writeInbound(new ContinuationWebSocketFrame(false, 0, Unpooled.wrappedBuffer(content2)));
channel.writeInbound(new ContinuationWebSocketFrame(true, 0, Unpooled.wrappedBuffer(content2)));
for (; ; ) {
Object msg = channel.readInbound();
if (msg == null) {
break;
}
ReferenceCountUtil.release(msg);
}
channel.finish();
}
use of io.netty.handler.codec.TooLongFrameException in project netty by netty.
the class SpdyHttpDecoder method decode.
@Override
protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, List<Object> out) throws Exception {
if (msg instanceof SpdySynStreamFrame) {
// HTTP requests/responses are mapped one-to-one to SPDY streams.
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
int streamId = spdySynStreamFrame.streamId();
if (SpdyCodecUtil.isServerId(streamId)) {
// SYN_STREAM frames initiated by the server are pushed resources
int associatedToStreamId = spdySynStreamFrame.associatedStreamId();
// it must reply with a RST_STREAM with error code INVALID_STREAM.
if (associatedToStreamId == 0) {
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INVALID_STREAM);
ctx.writeAndFlush(spdyRstStreamFrame);
return;
}
// (we only support pushed resources divided into two header blocks).
if (spdySynStreamFrame.isLast()) {
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
return;
}
// reply with a RST_STREAM with error code INTERNAL_ERROR.
if (spdySynStreamFrame.isTruncated()) {
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INTERNAL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
return;
}
try {
FullHttpRequest httpRequestWithEntity = createHttpRequest(spdySynStreamFrame, ctx.alloc());
// Set the Stream-ID, Associated-To-Stream-ID, and Priority as headers
httpRequestWithEntity.headers().setInt(Names.STREAM_ID, streamId);
httpRequestWithEntity.headers().setInt(Names.ASSOCIATED_TO_STREAM_ID, associatedToStreamId);
httpRequestWithEntity.headers().setInt(Names.PRIORITY, spdySynStreamFrame.priority());
out.add(httpRequestWithEntity);
} catch (Throwable ignored) {
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
}
} else {
// reply with an HTTP 431 REQUEST HEADER FIELDS TOO LARGE reply.
if (spdySynStreamFrame.isTruncated()) {
SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
spdySynReplyFrame.setLast(true);
SpdyHeaders frameHeaders = spdySynReplyFrame.headers();
frameHeaders.setInt(STATUS, HttpResponseStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.code());
frameHeaders.setObject(VERSION, HttpVersion.HTTP_1_0);
ctx.writeAndFlush(spdySynReplyFrame);
return;
}
try {
FullHttpRequest httpRequestWithEntity = createHttpRequest(spdySynStreamFrame, ctx.alloc());
// Set the Stream-ID as a header
httpRequestWithEntity.headers().setInt(Names.STREAM_ID, streamId);
if (spdySynStreamFrame.isLast()) {
out.add(httpRequestWithEntity);
} else {
// Request body will follow in a series of Data Frames
putMessage(streamId, httpRequestWithEntity);
}
} catch (Throwable t) {
// If a client sends a SYN_STREAM without all of the getMethod, url (host and path),
// scheme, and version headers the server must reply with an HTTP 400 BAD REQUEST reply.
// Also sends HTTP 400 BAD REQUEST reply if header name/value pairs are invalid
SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
spdySynReplyFrame.setLast(true);
SpdyHeaders frameHeaders = spdySynReplyFrame.headers();
frameHeaders.setInt(STATUS, HttpResponseStatus.BAD_REQUEST.code());
frameHeaders.setObject(VERSION, HttpVersion.HTTP_1_0);
ctx.writeAndFlush(spdySynReplyFrame);
}
}
} else if (msg instanceof SpdySynReplyFrame) {
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
int streamId = spdySynReplyFrame.streamId();
// reply with a RST_STREAM frame with error code INTERNAL_ERROR.
if (spdySynReplyFrame.isTruncated()) {
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INTERNAL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
return;
}
try {
FullHttpResponse httpResponseWithEntity = createHttpResponse(spdySynReplyFrame, ctx.alloc(), validateHeaders);
// Set the Stream-ID as a header
httpResponseWithEntity.headers().setInt(Names.STREAM_ID, streamId);
if (spdySynReplyFrame.isLast()) {
HttpUtil.setContentLength(httpResponseWithEntity, 0);
out.add(httpResponseWithEntity);
} else {
// Response body will follow in a series of Data Frames
putMessage(streamId, httpResponseWithEntity);
}
} catch (Throwable t) {
// If a client receives a SYN_REPLY without valid getStatus and version headers
// the client must reply with a RST_STREAM frame indicating a PROTOCOL_ERROR
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
}
} else if (msg instanceof SpdyHeadersFrame) {
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
int streamId = spdyHeadersFrame.streamId();
FullHttpMessage fullHttpMessage = getMessage(streamId);
if (fullHttpMessage == null) {
// HEADERS frames may initiate a pushed response
if (SpdyCodecUtil.isServerId(streamId)) {
// reply with a RST_STREAM frame with error code INTERNAL_ERROR.
if (spdyHeadersFrame.isTruncated()) {
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INTERNAL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
return;
}
try {
fullHttpMessage = createHttpResponse(spdyHeadersFrame, ctx.alloc(), validateHeaders);
// Set the Stream-ID as a header
fullHttpMessage.headers().setInt(Names.STREAM_ID, streamId);
if (spdyHeadersFrame.isLast()) {
HttpUtil.setContentLength(fullHttpMessage, 0);
out.add(fullHttpMessage);
} else {
// Response body will follow in a series of Data Frames
putMessage(streamId, fullHttpMessage);
}
} catch (Throwable t) {
// If a client receives a SYN_REPLY without valid getStatus and version headers
// the client must reply with a RST_STREAM frame indicating a PROTOCOL_ERROR
SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
ctx.writeAndFlush(spdyRstStreamFrame);
}
}
return;
}
// Ignore trailers in a truncated HEADERS frame.
if (!spdyHeadersFrame.isTruncated()) {
for (Map.Entry<CharSequence, CharSequence> e : spdyHeadersFrame.headers()) {
fullHttpMessage.headers().add(e.getKey(), e.getValue());
}
}
if (spdyHeadersFrame.isLast()) {
HttpUtil.setContentLength(fullHttpMessage, fullHttpMessage.content().readableBytes());
removeMessage(streamId);
out.add(fullHttpMessage);
}
} else if (msg instanceof SpdyDataFrame) {
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
int streamId = spdyDataFrame.streamId();
FullHttpMessage fullHttpMessage = getMessage(streamId);
// If message is not in map discard Data Frame.
if (fullHttpMessage == null) {
return;
}
ByteBuf content = fullHttpMessage.content();
if (content.readableBytes() > maxContentLength - spdyDataFrame.content().readableBytes()) {
removeMessage(streamId);
throw new TooLongFrameException("HTTP content length exceeded " + maxContentLength + " bytes.");
}
ByteBuf spdyDataFrameData = spdyDataFrame.content();
int spdyDataFrameDataLen = spdyDataFrameData.readableBytes();
content.writeBytes(spdyDataFrameData, spdyDataFrameData.readerIndex(), spdyDataFrameDataLen);
if (spdyDataFrame.isLast()) {
HttpUtil.setContentLength(fullHttpMessage, content.readableBytes());
removeMessage(streamId);
out.add(fullHttpMessage);
}
} else if (msg instanceof SpdyRstStreamFrame) {
SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
int streamId = spdyRstStreamFrame.streamId();
removeMessage(streamId);
}
}
use of io.netty.handler.codec.TooLongFrameException in project vert.x by eclipse.
the class Http1xTest method testServerExceptionHandler.
@Test
public void testServerExceptionHandler() throws Exception {
Context serverCtx = vertx.getOrCreateContext();
server.exceptionHandler(err -> {
assertSame(serverCtx, Vertx.currentContext());
assertTrue(err instanceof TooLongFrameException);
testComplete();
});
server.requestHandler(req -> {
fail();
});
startServer(testAddress, serverCtx);
client.request(requestOptions).onComplete(onSuccess(req -> {
req.putHeader("the_header", TestUtils.randomAlphaString(10000)).sendHead();
}));
await();
}
use of io.netty.handler.codec.TooLongFrameException in project vert.x by eclipse.
the class Http1xTest method testInvalidTrailersInHttpClientResponse.
@Test
public void testInvalidTrailersInHttpClientResponse() throws Exception {
NetServer server = vertx.createNetServer();
CountDownLatch listenLatch = new CountDownLatch(1);
CompletableFuture<Void> cont = new CompletableFuture<>();
server.connectHandler(so -> {
so.handler(buff -> {
so.handler(null);
so.write("HTTP/1.1 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + // Empty chunk
"0\r\n");
// Send large trailer
});
cont.whenComplete((v, e) -> {
for (int i = 0; i < 2000; i++) {
so.write("01234567");
}
});
}).listen(testAddress, onSuccess(v -> listenLatch.countDown()));
awaitLatch(listenLatch);
AtomicInteger status = new AtomicInteger();
testHttpClientResponseDecodeError(cont::complete, err -> {
switch(status.incrementAndGet()) {
case 1:
assertTrue(err instanceof TooLongFrameException);
break;
case 2:
assertTrue(err instanceof VertxException);
assertTrue(err.getMessage().equals("Connection was closed"));
testComplete();
break;
}
});
}
Aggregations