SPDY: ensure SpdyHeaderBlockRawDecoder always reads entire input
This commit is contained in:
parent
00bf5eb898
commit
b58277e079
@ -16,6 +16,7 @@
|
||||
package org.jboss.netty.handler.codec.spdy;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.jboss.netty.buffer.ChannelBuffers;
|
||||
|
||||
import static org.jboss.netty.handler.codec.spdy.SpdyCodecUtil.*;
|
||||
|
||||
@ -27,6 +28,8 @@ public class SpdyHeaderBlockRawDecoder extends SpdyHeaderBlockDecoder {
|
||||
|
||||
private State state;
|
||||
|
||||
private ChannelBuffer cumulation;
|
||||
|
||||
private int headerSize;
|
||||
private int numHeaders;
|
||||
private int length;
|
||||
@ -67,6 +70,24 @@ public class SpdyHeaderBlockRawDecoder extends SpdyHeaderBlockDecoder {
|
||||
throw new NullPointerException("frame");
|
||||
}
|
||||
|
||||
if (cumulation == null) {
|
||||
decodeHeaderBlock(headerBlock, frame);
|
||||
if (headerBlock.readable()) {
|
||||
cumulation = ChannelBuffers.dynamicBuffer(headerBlock.readableBytes());
|
||||
cumulation.writeBytes(headerBlock);
|
||||
}
|
||||
} else {
|
||||
cumulation.writeBytes(headerBlock);
|
||||
decodeHeaderBlock(cumulation, frame);
|
||||
if (cumulation.readable()) {
|
||||
cumulation.discardReadBytes();
|
||||
} else {
|
||||
cumulation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void decodeHeaderBlock(ChannelBuffer headerBlock, SpdyHeadersFrame frame) throws Exception {
|
||||
int skipLength;
|
||||
while (headerBlock.readable()) {
|
||||
switch(state) {
|
||||
@ -267,6 +288,9 @@ public class SpdyHeaderBlockRawDecoder extends SpdyHeaderBlockDecoder {
|
||||
if (state != State.END_HEADER_BLOCK) {
|
||||
frame.setInvalid();
|
||||
}
|
||||
|
||||
cumulation = null;
|
||||
|
||||
// Initialize header block decoding fields
|
||||
headerSize = 0;
|
||||
name = null;
|
||||
@ -275,5 +299,6 @@ public class SpdyHeaderBlockRawDecoder extends SpdyHeaderBlockDecoder {
|
||||
|
||||
@Override
|
||||
void end() {
|
||||
cumulation = null;
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ final class SpdyHeaderBlockZlibDecoder extends SpdyHeaderBlockRawDecoder {
|
||||
}
|
||||
|
||||
decompressed.writerIndex(decompressed.writerIndex() + numBytes);
|
||||
super.decode(decompressed, frame);
|
||||
super.decodeHeaderBlock(decompressed, frame);
|
||||
decompressed.discardReadBytes();
|
||||
|
||||
return numBytes;
|
||||
|
@ -391,25 +391,21 @@ public class SpdyHeaderBlockRawDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testMultipleDecodes() throws Exception {
|
||||
ChannelBuffer numHeaders = ChannelBuffers.buffer(4);
|
||||
numHeaders.writeInt(1);
|
||||
ChannelBuffer headerBlock = ChannelBuffers.buffer(21);
|
||||
headerBlock.writeInt(1);
|
||||
headerBlock.writeInt(4);
|
||||
headerBlock.writeBytes(nameBytes);
|
||||
headerBlock.writeInt(5);
|
||||
headerBlock.writeBytes(valueBytes);
|
||||
|
||||
ChannelBuffer nameBlock = ChannelBuffers.buffer(8);
|
||||
nameBlock.writeInt(4);
|
||||
nameBlock.writeBytes(nameBytes);
|
||||
|
||||
ChannelBuffer valueBlock = ChannelBuffers.buffer(9);
|
||||
valueBlock.writeInt(5);
|
||||
valueBlock.writeBytes(valueBytes);
|
||||
|
||||
decoder.decode(numHeaders, frame);
|
||||
decoder.decode(nameBlock, frame);
|
||||
decoder.decode(valueBlock, frame);
|
||||
int readableBytes = headerBlock.readableBytes();
|
||||
for (int i = 0; i < readableBytes; i++) {
|
||||
ChannelBuffer headerBlockSegment = headerBlock.slice(i, 1);
|
||||
decoder.decode(headerBlockSegment, frame);
|
||||
assertFalse(headerBlockSegment.readable());
|
||||
}
|
||||
decoder.endHeaderBlock(frame);
|
||||
|
||||
assertFalse(numHeaders.readable());
|
||||
assertFalse(nameBlock.readable());
|
||||
assertFalse(valueBlock.readable());
|
||||
assertFalse(frame.isInvalid());
|
||||
assertEquals(1, frame.headers().names().size());
|
||||
assertTrue(frame.headers().contains(name));
|
||||
|
@ -92,6 +92,7 @@ public class SpdyHeaderBlockZlibDecoderTest {
|
||||
for (int i = 0; i < readableBytes; i++) {
|
||||
ChannelBuffer headerBlockSegment = headerBlock.slice(i, 1);
|
||||
decoder.decode(headerBlockSegment, frame);
|
||||
assertFalse(headerBlockSegment.readable());
|
||||
}
|
||||
decoder.endHeaderBlock(frame);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user