Reduce memory copies in spdy compression implementation.

Motivation:

Currently we do more memory copies then needed.

Modification:

- Directly use heap buffers to reduce memory copy
- Correctly release buffers to fix buffer leak

Result:

Less memory copies and no leaks
This commit is contained in:
Norman Maurer 2014-06-25 21:16:27 +02:00
parent ee198d7cfc
commit d332c00e2f
10 changed files with 131 additions and 83 deletions

View File

@ -111,7 +111,7 @@ public class SpdyFrameCodec extends ByteToMessageDecoder implements SpdyFrameDec
} else if (msg instanceof SpdySynStreamFrame) {
SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
ByteBuf headerBlock = spdyHeaderBlockEncoder.encode(spdySynStreamFrame);
ByteBuf headerBlock = spdyHeaderBlockEncoder.encode(ctx.alloc(), spdySynStreamFrame);
try {
frame = spdyFrameEncoder.encodeSynStreamFrame(
ctx.alloc(),
@ -130,7 +130,7 @@ public class SpdyFrameCodec extends ByteToMessageDecoder implements SpdyFrameDec
} else if (msg instanceof SpdySynReplyFrame) {
SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
ByteBuf headerBlock = spdyHeaderBlockEncoder.encode(spdySynReplyFrame);
ByteBuf headerBlock = spdyHeaderBlockEncoder.encode(ctx.alloc(), spdySynReplyFrame);
try {
frame = spdyFrameEncoder.encodeSynReplyFrame(
ctx.alloc(),
@ -184,7 +184,7 @@ public class SpdyFrameCodec extends ByteToMessageDecoder implements SpdyFrameDec
} else if (msg instanceof SpdyHeadersFrame) {
SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
ByteBuf headerBlock = spdyHeaderBlockEncoder.encode(spdyHeadersFrame);
ByteBuf headerBlock = spdyHeaderBlockEncoder.encode(ctx.alloc(), spdyHeadersFrame);
try {
frame = spdyFrameEncoder.encodeHeadersFrame(
ctx.alloc(),
@ -285,7 +285,7 @@ public class SpdyFrameCodec extends ByteToMessageDecoder implements SpdyFrameDec
@Override
public void readHeaderBlock(ByteBuf headerBlock) {
try {
spdyHeaderBlockDecoder.decode(headerBlock, spdyHeadersFrame);
spdyHeaderBlockDecoder.decode(ctx.alloc(), headerBlock, spdyHeadersFrame);
} catch (Exception e) {
ctx.fireExceptionCaught(e);
} finally {

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
abstract class SpdyHeaderBlockDecoder {
@ -28,13 +29,14 @@ abstract class SpdyHeaderBlockDecoder {
* If the header block is malformed, the Headers frame will be marked as invalid.
* A stream error with status code PROTOCOL_ERROR must be issued in response to an invalid frame.
*
* @param alloc the {@link ByteBufAllocator} which can be used to allocate new {@link ByteBuf}s
* @param headerBlock the HeaderBlock to decode
* @param frame the Headers frame that receives the Name/Value pairs
* @throws Exception If the header block is malformed in a way that prevents any future
* decoding of any other header blocks, an exception will be thrown.
* A session error with status code PROTOCOL_ERROR must be issued.
*/
abstract void decode(ByteBuf headerBlock, SpdyHeadersFrame frame) throws Exception;
abstract void decode(ByteBufAllocator alloc, ByteBuf headerBlock, SpdyHeadersFrame frame) throws Exception;
abstract void endHeaderBlock(SpdyHeadersFrame frame) throws Exception;

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.internal.PlatformDependent;
abstract class SpdyHeaderBlockEncoder {
@ -32,6 +33,6 @@ abstract class SpdyHeaderBlockEncoder {
}
}
abstract ByteBuf encode(SpdyHeadersFrame frame) throws Exception;
abstract ByteBuf encode(ByteBufAllocator alloc, SpdyHeadersFrame frame) throws Exception;
abstract void end();
}

View File

@ -18,6 +18,7 @@ package io.netty.handler.codec.spdy;
import com.jcraft.jzlib.Deflater;
import com.jcraft.jzlib.JZlib;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.compression.CompressionException;
@ -60,28 +61,52 @@ class SpdyHeaderBlockJZlibEncoder extends SpdyHeaderBlockRawEncoder {
}
private void setInput(ByteBuf decompressed) {
byte[] in = new byte[decompressed.readableBytes()];
decompressed.readBytes(in);
int len = decompressed.readableBytes();
byte[] in;
int offset;
if (decompressed.hasArray()) {
in = decompressed.array();
offset = decompressed.arrayOffset() + decompressed.readerIndex();
} else {
in = new byte[len];
decompressed.getBytes(decompressed.readerIndex(), in);
offset = 0;
}
z.next_in = in;
z.next_in_index = 0;
z.avail_in = in.length;
z.next_in_index = offset;
z.avail_in = len;
}
private void encode(ByteBuf compressed) {
private ByteBuf encode(ByteBufAllocator alloc) {
boolean release = true;
ByteBuf out = null;
try {
byte[] out = new byte[(int) Math.ceil(z.next_in.length * 1.001) + 12];
z.next_out = out;
z.next_out_index = 0;
z.avail_out = out.length;
int oldNextInIndex = z.next_in_index;
int oldNextOutIndex = z.next_out_index;
int resultCode = z.deflate(JZlib.Z_SYNC_FLUSH);
int maxOutputLength = (int) Math.ceil(z.next_in.length * 1.001) + 12;
out = alloc.heapBuffer(maxOutputLength);
z.next_out = out.array();
z.next_out_index = out.arrayOffset() + out.writerIndex();
z.avail_out = maxOutputLength;
int resultCode;
try {
resultCode = z.deflate(JZlib.Z_SYNC_FLUSH);
} finally {
out.skipBytes(z.next_in_index - oldNextInIndex);
}
if (resultCode != JZlib.Z_OK) {
throw new CompressionException("compression failure: " + resultCode);
}
if (z.next_out_index != 0) {
compressed.writeBytes(out, 0, z.next_out_index);
int outputLength = z.next_out_index - oldNextOutIndex;
if (outputLength > 0) {
out.writerIndex(out.writerIndex() + outputLength);
}
release = false;
return out;
} finally {
// Deference the external references explicitly to tell the VM that
// the allocated byte arrays are temporary so that the call stack
@ -89,11 +114,14 @@ class SpdyHeaderBlockJZlibEncoder extends SpdyHeaderBlockRawEncoder {
// I'm not sure if the modern VMs do this optimization though.
z.next_in = null;
z.next_out = null;
if (release && out != null) {
out.release();
}
}
}
@Override
public ByteBuf encode(SpdyHeadersFrame frame) throws Exception {
public ByteBuf encode(ByteBufAllocator alloc, SpdyHeadersFrame frame) throws Exception {
if (frame == null) {
throw new IllegalArgumentException("frame");
}
@ -102,15 +130,17 @@ class SpdyHeaderBlockJZlibEncoder extends SpdyHeaderBlockRawEncoder {
return Unpooled.EMPTY_BUFFER;
}
ByteBuf decompressed = super.encode(frame);
if (decompressed.readableBytes() == 0) {
return Unpooled.EMPTY_BUFFER;
}
ByteBuf decompressed = super.encode(alloc, frame);
try {
if (!decompressed.isReadable()) {
return Unpooled.EMPTY_BUFFER;
}
ByteBuf compressed = decompressed.alloc().buffer();
setInput(decompressed);
encode(compressed);
return compressed;
setInput(decompressed);
return encode(alloc);
} finally {
decompressed.release();
}
}
@Override

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;
@ -61,7 +62,7 @@ public class SpdyHeaderBlockRawDecoder extends SpdyHeaderBlockDecoder {
}
@Override
void decode(ByteBuf headerBlock, SpdyHeadersFrame frame) throws Exception {
void decode(ByteBufAllocator alloc, ByteBuf headerBlock, SpdyHeadersFrame frame) throws Exception {
if (headerBlock == null) {
throw new NullPointerException("headerBlock");
}
@ -72,7 +73,7 @@ public class SpdyHeaderBlockRawDecoder extends SpdyHeaderBlockDecoder {
if (cumulation == null) {
decodeHeaderBlock(headerBlock, frame);
if (headerBlock.isReadable()) {
cumulation = headerBlock.alloc().buffer(headerBlock.readableBytes());
cumulation = alloc.buffer(headerBlock.readableBytes());
cumulation.writeBytes(headerBlock);
}
} else {

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import java.util.Set;
@ -42,7 +43,7 @@ public class SpdyHeaderBlockRawEncoder extends SpdyHeaderBlockEncoder {
}
@Override
public ByteBuf encode(SpdyHeadersFrame frame) throws Exception {
public ByteBuf encode(ByteBufAllocator alloc, SpdyHeadersFrame frame) throws Exception {
Set<String> names = frame.headers().names();
int numHeaders = names.size();
if (numHeaders == 0) {
@ -52,7 +53,7 @@ public class SpdyHeaderBlockRawEncoder extends SpdyHeaderBlockEncoder {
throw new IllegalArgumentException(
"header block contains too many headers");
}
ByteBuf headerBlock = Unpooled.buffer();
ByteBuf headerBlock = alloc.heapBuffer();
writeLengthField(headerBlock, numHeaders);
for (String name: names) {
byte[] nameBytes = name.getBytes("UTF-8");

View File

@ -38,12 +38,12 @@ final class SpdyHeaderBlockZlibDecoder extends SpdyHeaderBlockRawDecoder {
}
@Override
void decode(ByteBuf headerBlock, SpdyHeadersFrame frame) throws Exception {
void decode(ByteBufAllocator alloc, ByteBuf headerBlock, SpdyHeadersFrame frame) throws Exception {
int len = setInput(headerBlock);
int numBytes;
do {
numBytes = decompress(headerBlock.alloc(), frame);
numBytes = decompress(alloc, frame);
} while (numBytes > 0);
// z_stream has an internal 64-bit hold buffer

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import java.util.zip.Deflater;
@ -52,10 +53,20 @@ class SpdyHeaderBlockZlibEncoder extends SpdyHeaderBlockRawEncoder {
return len;
}
private void encode(ByteBuf compressed) {
while (compressInto(compressed)) {
// Although unlikely, it's possible that the compressed size is larger than the decompressed size
compressed.ensureWritable(compressed.capacity() << 1);
private ByteBuf encode(ByteBufAllocator alloc, int len) {
ByteBuf compressed = alloc.heapBuffer(len);
boolean release = true;
try {
while (compressInto(compressed)) {
// Although unlikely, it's possible that the compressed size is larger than the decompressed size
compressed.ensureWritable(compressed.capacity() << 1);
}
release = false;
return compressed;
} finally {
if (release) {
compressed.release();
}
}
}
@ -69,7 +80,7 @@ class SpdyHeaderBlockZlibEncoder extends SpdyHeaderBlockRawEncoder {
}
@Override
public ByteBuf encode(SpdyHeadersFrame frame) throws Exception {
public ByteBuf encode(ByteBufAllocator alloc, SpdyHeadersFrame frame) throws Exception {
if (frame == null) {
throw new IllegalArgumentException("frame");
}
@ -78,17 +89,17 @@ class SpdyHeaderBlockZlibEncoder extends SpdyHeaderBlockRawEncoder {
return Unpooled.EMPTY_BUFFER;
}
ByteBuf decompressed = super.encode(frame);
if (decompressed.readableBytes() == 0) {
return Unpooled.EMPTY_BUFFER;
ByteBuf decompressed = super.encode(alloc, frame);
try {
if (!decompressed.isReadable()) {
return Unpooled.EMPTY_BUFFER;
}
int len = setInput(decompressed);
return encode(alloc, len);
} finally {
decompressed.release();
}
ByteBuf compressed = decompressed.alloc().heapBuffer(decompressed.readableBytes());
int len = setInput(decompressed);
encode(compressed);
decompressed.skipBytes(len);
return compressed;
}
@Override

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;
import org.junit.After;
@ -52,7 +53,7 @@ public class SpdyHeaderBlockRawDecoderTest {
@Test
public void testEmptyHeaderBlock() throws Exception {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.EMPTY_BUFFER);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -64,7 +65,7 @@ public class SpdyHeaderBlockRawDecoderTest {
public void testZeroNameValuePairs() throws Exception {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.buffer(4));
headerBlock.writeInt(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -76,7 +77,7 @@ public class SpdyHeaderBlockRawDecoderTest {
public void testNegativeNameValuePairs() throws Exception {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.buffer(4));
headerBlock.writeInt(-1);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -91,7 +92,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(5);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -106,7 +107,7 @@ public class SpdyHeaderBlockRawDecoderTest {
public void testMissingNameLength() throws Exception {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.buffer(4));
headerBlock.writeInt(1);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -119,7 +120,7 @@ public class SpdyHeaderBlockRawDecoderTest {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.buffer(8));
headerBlock.writeInt(1);
headerBlock.writeInt(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -131,7 +132,7 @@ public class SpdyHeaderBlockRawDecoderTest {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.buffer(8));
headerBlock.writeInt(1);
headerBlock.writeInt(-1);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -143,7 +144,7 @@ public class SpdyHeaderBlockRawDecoderTest {
ByteBuf headerBlock = ReferenceCountUtil.releaseLater(Unpooled.buffer(8));
headerBlock.writeInt(1);
headerBlock.writeInt(4);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -159,7 +160,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeByte(0);
headerBlock.writeInt(5);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -172,7 +173,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(1);
headerBlock.writeInt(4);
headerBlock.writeBytes(nameBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -187,7 +188,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(4);
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -205,7 +206,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(4);
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(-1);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -219,7 +220,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(4);
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(5);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -235,7 +236,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(1);
headerBlock.writeByte(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -251,7 +252,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(6);
headerBlock.writeByte(0);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -267,7 +268,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(6);
headerBlock.writeBytes(valueBytes);
headerBlock.writeByte(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -284,7 +285,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeBytes(valueBytes);
headerBlock.writeByte(0);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -307,7 +308,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeByte(0);
headerBlock.writeBytes(valueBytes);
headerBlock.writeByte(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -328,7 +329,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeByte(0);
headerBlock.writeByte(0);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -344,7 +345,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(5);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -367,7 +368,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeBytes(nameBytes);
headerBlock.writeInt(5);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -386,7 +387,7 @@ public class SpdyHeaderBlockRawDecoderTest {
headerBlock.writeInt(5);
headerBlock.writeBytes(valueBytes);
headerBlock.writeByte(0);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
assertFalse(headerBlock.isReadable());
assertTrue(frame.isInvalid());
@ -408,7 +409,7 @@ public class SpdyHeaderBlockRawDecoderTest {
int readableBytes = headerBlock.readableBytes();
for (int i = 0; i < readableBytes; i++) {
ByteBuf headerBlockSegment = headerBlock.slice(i, 1);
decoder.decode(headerBlockSegment, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlockSegment, frame);
assertFalse(headerBlockSegment.isReadable());
}
decoder.endHeaderBlock(frame);
@ -433,10 +434,10 @@ public class SpdyHeaderBlockRawDecoderTest {
valueBlock.writeInt(5);
valueBlock.writeBytes(valueBytes);
decoder.decode(numHeaders, frame);
decoder.decode(nameBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, numHeaders, frame);
decoder.decode(ByteBufAllocator.DEFAULT, nameBlock, frame);
frame.setInvalid();
decoder.decode(valueBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, valueBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(numHeaders.isReadable());
@ -458,7 +459,7 @@ public class SpdyHeaderBlockRawDecoderTest {
}
headerBlock.writeInt(5);
headerBlock.writeBytes(valueBytes);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -477,7 +478,7 @@ public class SpdyHeaderBlockRawDecoderTest {
for (int i = 0; i < maxHeaderSize - 3; i++) {
headerBlock.writeByte('a');
}
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.spdy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;
import org.junit.After;
@ -68,7 +69,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
headerBlock.writeInt(5); // length of value
headerBlock.writeBytes(valueBytes);
headerBlock.writeBytes(zlibSyncFlush);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -98,7 +99,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
int readableBytes = headerBlock.readableBytes();
for (int i = 0; i < readableBytes; i++) {
ByteBuf headerBlockSegment = headerBlock.slice(i, 1);
decoder.decode(headerBlockSegment, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlockSegment, frame);
assertFalse(headerBlockSegment.isReadable());
}
decoder.endHeaderBlock(frame);
@ -126,7 +127,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
}
headerBlock.writeInt(0); // length of value
headerBlock.writeBytes(zlibSyncFlush);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -152,7 +153,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
headerBlock.writeByte('v');
}
headerBlock.writeBytes(zlibSyncFlush);
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
decoder.endHeaderBlock(frame);
assertFalse(headerBlock.isReadable());
@ -181,7 +182,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
headerBlock.writeByte(0x03); // adler-32 checksum
headerBlock.writeByte(0xc9); // adler-32 checksum
headerBlock.writeByte(0); // Data following zlib stream
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
}
@Test(expected = SpdyProtocolException.class)
@ -194,7 +195,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
headerBlock.writeByte(0x03); // Unknown dictionary
headerBlock.writeByte(0x04); // Unknown dictionary
headerBlock.writeByte(0); // Non-compressed block
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
}
@Test(expected = SpdyProtocolException.class)
@ -206,6 +207,6 @@ public class SpdyHeaderBlockZlibDecoderTest {
headerBlock.writeByte(0x00); // little-endian length (0)
headerBlock.writeByte(0x00); // invalid one's compliment
headerBlock.writeByte(0x00); // invalid one's compliment
decoder.decode(headerBlock, frame);
decoder.decode(ByteBufAllocator.DEFAULT, headerBlock, frame);
}
}