diff --git a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyCodecUtil.java b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyCodecUtil.java index fd94358c2f..54f191b86f 100644 --- a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyCodecUtil.java +++ b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyCodecUtil.java @@ -349,10 +349,6 @@ final class SpdyCodecUtil { if (value == null) { throw new NullPointerException("value"); } - if (value.length() == 0) { - throw new IllegalArgumentException( - "value cannot be length zero"); - } for (int i = 0; i < value.length(); i ++) { char c = value.charAt(i); if (c == 0) { diff --git a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameDecoder.java b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameDecoder.java index 92188d01b7..4e56fb012b 100644 --- a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameDecoder.java @@ -594,7 +594,7 @@ public class SpdyFrameDecoder extends FrameDecoder { } } - while (numHeaders > 0) { + while (numHeaders -- > 0) { int headerSize = this.headerSize; decompressed.markReaderIndex(); @@ -642,10 +642,23 @@ public class SpdyFrameDecoder extends FrameDecoder { 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( @@ -686,7 +699,6 @@ public class SpdyFrameDecoder extends FrameDecoder { index ++; offset = index; } - numHeaders --; this.headerSize = headerSize; } decompressed = null; diff --git a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameEncoder.java b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameEncoder.java index d6d6820a30..dea22621bb 100644 --- a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyFrameEncoder.java @@ -383,17 +383,28 @@ public class SpdyFrameEncoder implements ChannelDownstreamHandler { writeLengthField(version, headerBlock, valueLength); for (String value: headerFrame.getHeaders(name)) { byte[] valueBytes = value.getBytes("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; }