diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java index 4d7ab23353..56c0a3066c 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpCodec.java @@ -27,4 +27,11 @@ public final class SpdyHttpCodec extends ChannelHandlerAppender { public SpdyHttpCodec(SpdyVersion version, int maxContentLength) { super(new SpdyHttpDecoder(version, maxContentLength), new SpdyHttpEncoder(version)); } + + /** + * Creates a new instance with the specified decoder options. + */ + public SpdyHttpCodec(SpdyVersion version, int maxContentLength, boolean validateHttpHeaders) { + super(new SpdyHttpDecoder(version, maxContentLength, validateHttpHeaders), new SpdyHttpEncoder(version)); + } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java index 0f1a503143..8718ce7a08 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java @@ -42,6 +42,7 @@ import static io.netty.handler.codec.spdy.SpdyHeaders.HttpNames.*; */ public class SpdyHttpDecoder extends MessageToMessageDecoder { + private final boolean validateHeaders; private final int spdyVersion; private final int maxContentLength; private final Map messageMap; @@ -55,7 +56,20 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { * a {@link TooLongFrameException} will be raised. */ public SpdyHttpDecoder(SpdyVersion version, int maxContentLength) { - this(version, maxContentLength, new HashMap()); + this(version, maxContentLength, new HashMap(), true); + } + + /** + * Creates a new instance. + * + * @param version the protocol version + * @param maxContentLength the maximum length of the message content. + * If the length of the message content exceeds this value, + * a {@link TooLongFrameException} will be raised. + * @param validateHeaders {@code true} if http headers should be validated + */ + public SpdyHttpDecoder(SpdyVersion version, int maxContentLength, boolean validateHeaders) { + this(version, maxContentLength, new HashMap(), validateHeaders); } /** @@ -68,6 +82,21 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { * @param messageMap the {@link Map} used to hold partially received messages. */ protected SpdyHttpDecoder(SpdyVersion version, int maxContentLength, Map messageMap) { + this(version, maxContentLength, messageMap, true); + } + + /** + * Creates a new instance with the specified parameters. + * + * @param version the protocol version + * @param maxContentLength the maximum length of the message content. + * If the length of the message content exceeds this value, + * a {@link TooLongFrameException} will be raised. + * @param messageMap the {@link Map} used to hold partially received messages. + * @param validateHeaders {@code true} if http headers should be validated + */ + protected SpdyHttpDecoder(SpdyVersion version, int maxContentLength, Map messageMap, boolean validateHeaders) { if (version == null) { throw new NullPointerException("version"); } @@ -78,6 +107,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { spdyVersion = version.getVersion(); this.maxContentLength = maxContentLength; this.messageMap = messageMap; + this.validateHeaders = validateHeaders; } protected FullHttpMessage putMessage(int streamId, FullHttpMessage message) { @@ -136,7 +166,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { try { FullHttpResponse httpResponseWithEntity = - createHttpResponse(spdyVersion, spdySynStreamFrame); + createHttpResponse(ctx, spdySynStreamFrame, validateHeaders); // Set the Stream-ID, Associated-To-Stream-ID, Priority, and URL as headers HttpHeaders.setIntHeader(httpResponseWithEntity, Names.STREAM_ID, streamId); @@ -212,7 +242,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { } try { - FullHttpResponse httpResponseWithEntity = createHttpResponse(spdyVersion, spdySynReplyFrame); + FullHttpResponse httpResponseWithEntity = createHttpResponse(ctx, spdySynReplyFrame, validateHeaders); // Set the Stream-ID as a header HttpHeaders.setIntHeader(httpResponseWithEntity, Names.STREAM_ID, streamId); @@ -328,8 +358,8 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { return req; } - private static FullHttpResponse createHttpResponse( - int spdyVersion, SpdyHeadersFrame responseFrame) throws Exception { + private static FullHttpResponse createHttpResponse(ChannelHandlerContext ctx, SpdyHeadersFrame responseFrame, + boolean validateHeaders) throws Exception { // Create the first line of the response from the name/value pairs SpdyHeaders headers = responseFrame.headers(); @@ -338,7 +368,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { headers.remove(STATUS); headers.remove(VERSION); - FullHttpResponse res = new DefaultFullHttpResponse(version, status); + FullHttpResponse res = new DefaultFullHttpResponse(version, status, ctx.alloc().buffer(), validateHeaders); for (Map.Entry e: responseFrame.headers()) { res.headers().add(e.getKey(), e.getValue()); }