diff --git a/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregator.java b/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregator.java index b07db33c4c..65b099468b 100644 --- a/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregator.java +++ b/codec-memcache/src/main/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregator.java @@ -53,8 +53,9 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg } private static FullBinaryMemcacheRequest toFullRequest(BinaryMemcacheRequest request, ByteBuf content) { + ByteBuf extras = request.extras() == null ? null : request.extras().retain(); FullBinaryMemcacheRequest fullRequest = - new DefaultFullBinaryMemcacheRequest(request.key(), request.extras(), content); + new DefaultFullBinaryMemcacheRequest(request.key(), extras, content); fullRequest.setMagic(request.magic()); fullRequest.setOpcode(request.opcode()); @@ -70,8 +71,9 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg } private static FullBinaryMemcacheResponse toFullResponse(BinaryMemcacheResponse response, ByteBuf content) { + ByteBuf extras = response.extras() == null ? null : response.extras().retain(); FullBinaryMemcacheResponse fullResponse = - new DefaultFullBinaryMemcacheResponse(response.key(), response.extras(), content); + new DefaultFullBinaryMemcacheResponse(response.key(), extras, content); fullResponse.setMagic(response.magic()); fullResponse.setOpcode(response.opcode()); diff --git a/codec-memcache/src/test/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregatorTest.java b/codec-memcache/src/test/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregatorTest.java index e291d61c3e..29e231a1c5 100644 --- a/codec-memcache/src/test/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregatorTest.java +++ b/codec-memcache/src/test/java/io/netty/handler/codec/memcache/binary/BinaryMemcacheObjectAggregatorTest.java @@ -18,12 +18,17 @@ package io.netty.handler.codec.memcache.binary; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.memcache.DefaultLastMemcacheContent; +import io.netty.handler.codec.memcache.DefaultMemcacheContent; +import io.netty.util.CharsetUtil; import org.junit.Test; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.core.IsNull.notNullValue; import static org.hamcrest.core.IsNull.nullValue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; /** * Verifies the correct functionality of the {@link BinaryMemcacheObjectAggregator}. @@ -73,4 +78,40 @@ public class BinaryMemcacheObjectAggregatorTest { channel.finish(); } + + @Test + public void shouldRetainByteBufWhenAggregating() { + channel = new EmbeddedChannel( + new BinaryMemcacheRequestEncoder(), + new BinaryMemcacheRequestDecoder(), + new BinaryMemcacheObjectAggregator(MAX_CONTENT_SIZE)); + + String key = "Netty"; + ByteBuf extras = Unpooled.copiedBuffer("extras", CharsetUtil.UTF_8); + BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(key, extras); + request.setKeyLength((short) key.length()); + request.setExtrasLength((byte) extras.readableBytes()); + + DefaultMemcacheContent content1 = + new DefaultMemcacheContent(Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8)); + DefaultLastMemcacheContent content2 = + new DefaultLastMemcacheContent(Unpooled.copiedBuffer(" Rocks!", CharsetUtil.UTF_8)); + int totalBodyLength = key.length() + extras.readableBytes() + + content1.content().readableBytes() + content2.content().readableBytes(); + request.setTotalBodyLength(totalBodyLength); + + assertTrue(channel.writeOutbound(request, content1, content2)); + + assertThat(channel.outboundMessages().size(), is(3)); + assertTrue(channel.writeInbound(channel.readOutbound(), channel.readOutbound(), channel.readOutbound())); + + FullBinaryMemcacheRequest read = channel.readInbound(); + assertThat(read, notNullValue()); + assertThat(read.key(), is("Netty")); + assertThat(read.extras().toString(CharsetUtil.UTF_8), is("extras")); + assertThat(read.content().toString(CharsetUtil.UTF_8), is("Netty Rocks!")); + + read.release(); + assertFalse(channel.finish()); + } }