SPDY: allow empty header values in SPDY/3

Ported from 3
This commit is contained in:
Trustin Lee 2013-01-14 22:59:11 +09:00
parent 57153079a5
commit 1354b4a1ac
3 changed files with 34 additions and 14 deletions

View File

@ -347,10 +347,6 @@ final class SpdyCodecUtil {
if (value == null) {
throw new NullPointerException("value");
}
if (value.isEmpty()) {
throw new IllegalArgumentException(
"value cannot be length zero");
}
for (int i = 0; i < value.length(); i ++) {
char c = value.charAt(i);
if (c == 0) {

View File

@ -15,13 +15,14 @@
*/
package io.netty.handler.codec.spdy;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.TooLongFrameException;
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;
/**
* Decodes {@link ByteBuf}s into SPDY Data and Control Frames.
*/
@ -577,7 +578,7 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
}
}
while (numHeaders > 0) {
while (numHeaders -- > 0) {
int headerSize = this.headerSize;
decompressed.markReaderIndex();
@ -625,10 +626,23 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
int valueLength = readLengthField();
// Recipients of illegal value fields must issue a stream error
if (valueLength <= 0) {
if (valueLength < 0) {
spdyHeaderBlock.setInvalid();
return;
}
// SPDY/3 allows zero-length (empty) header values
if (valueLength == 0) {
if (version < 3) {
spdyHeaderBlock.setInvalid();
return;
} else {
spdyHeaderBlock.addHeader(name, "");
this.headerSize = headerSize;
continue;
}
}
headerSize += valueLength;
if (headerSize > maxHeaderSize) {
throw new TooLongFrameException(
@ -669,7 +683,6 @@ public class SpdyFrameDecoder extends ByteToMessageDecoder {
index ++;
offset = index;
}
numHeaders --;
this.headerSize = headerSize;
}
decompressed = null;

View File

@ -309,17 +309,28 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
writeLengthField(version, headerBlock, valueLength);
for (String value: headerFrame.getHeaders(name)) {
byte[] valueBytes = value.getBytes(CharsetUtil.UTF_8);
headerBlock.writeBytes(valueBytes);
headerBlock.writeByte(0);
valueLength += valueBytes.length + 1;
if (valueBytes.length > 0) {
headerBlock.writeBytes(valueBytes);
headerBlock.writeByte(0);
valueLength += valueBytes.length + 1;
}
}
if (valueLength == 0) {
if (version < 3) {
throw new IllegalArgumentException(
"header value cannot be empty: " + name);
}
} else {
valueLength --;
}
valueLength --;
if (valueLength > SPDY_MAX_NV_LENGTH) {
throw new IllegalArgumentException(
"header exceeds allowable length: " + name);
}
setLengthField(version, headerBlock, savedIndex, valueLength);
headerBlock.writerIndex(headerBlock.writerIndex() - 1);
if (valueLength > 0) {
setLengthField(version, headerBlock, savedIndex, valueLength);
headerBlock.writerIndex(headerBlock.writerIndex() - 1);
}
}
return headerBlock;
}