From 0393ffbfb2d8cebd3f5a87679ca9c30e59ba048b Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Sun, 14 Jul 2013 23:12:49 +0200 Subject: [PATCH] Reduce memory copies in HttpContentDecoder and so also the risk of memory leaks --- .../codec/http/HttpContentDecoder.java | 84 +++++++++---------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java index 41a75f15a0..0ece6b50c4 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java @@ -16,8 +16,6 @@ package io.netty.handler.codec.http; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufHolder; -import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.codec.MessageToMessageDecoder; @@ -108,15 +106,23 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder out) { ByteBuf content = c.content(); - decode(content, newContent); + + decode(content, out); if (c instanceof LastHttpContent) { - ByteBuf lastProduct = Unpooled.buffer(); - finishDecode(lastProduct); + finishDecode(out); // Generate an additional chunk if the decoder produced // the last product on closure, - if (lastProduct.isReadable()) { - if (header == null) { - return new Object[] { new DefaultHttpContent(newContent), new DefaultLastHttpContent(lastProduct)}; - } else { - return new Object[] { header, new DefaultHttpContent(newContent), - new DefaultLastHttpContent(lastProduct)}; - } - } else { - if (header == null) { - return new Object[] { new DefaultLastHttpContent(newContent) }; - } else { - return new Object[] { header, new DefaultLastHttpContent(newContent) }; - } - } - } - if (header == null) { - return new Object[] { new DefaultHttpContent(newContent) }; - } else { - return new Object[] { header, new DefaultHttpContent(newContent) }; + out.add(LastHttpContent.EMPTY_LAST_CONTENT); } } @@ -210,20 +197,28 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder out) { + // call retain here as it will call release after its written to the channel + decoder.writeOutbound(in.retain()); fetchDecoderOutput(out); } - private void finishDecode(ByteBuf out) { + private void finishDecode(List out) { if (decoder.finish()) { fetchDecoderOutput(out); } @@ -231,14 +226,17 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder out) { for (;;) { - ByteBuf buf = (ByteBuf) decoder.readInbound(); + ByteBuf buf = (ByteBuf) decoder.readOutbound(); if (buf == null) { break; } - out.writeBytes(buf); - buf.release(); + if (!buf.isReadable()) { + buf.release(); + continue; + } + out.add(new DefaultHttpContent(buf)); } } }