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:
parent
ee198d7cfc
commit
d332c00e2f
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user