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 efb2dd426d..e5c2250001 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 @@ -28,4 +28,11 @@ public final class SpdyHttpCodec 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 e8c32b5b86..d3a1946f36 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 @@ -39,6 +39,7 @@ import java.util.Map; */ public class SpdyHttpDecoder extends MessageToMessageDecoder { + private final boolean validateHeaders; private final int spdyVersion; private final int maxContentLength; private final Map messageMap; @@ -52,7 +53,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); } /** @@ -65,6 +79,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"); } @@ -75,6 +104,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) { @@ -133,7 +163,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { try { FullHttpResponse httpResponseWithEntity = - createHttpResponse(spdyVersion, spdySynStreamFrame); + createHttpResponse(ctx, spdyVersion, spdySynStreamFrame, validateHeaders); // Set the Stream-ID, Associated-To-Stream-ID, Priority, and URL as headers SpdyHttpHeaders.setStreamId(httpResponseWithEntity, streamId); @@ -208,7 +238,8 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { } try { - FullHttpResponse httpResponseWithEntity = createHttpResponse(spdyVersion, spdySynReplyFrame); + FullHttpResponse httpResponseWithEntity = + createHttpResponse(ctx, spdyVersion, spdySynReplyFrame, validateHeaders); // Set the Stream-ID as a header SpdyHttpHeaders.setStreamId(httpResponseWithEntity, streamId); @@ -323,15 +354,17 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { return req; } - private static FullHttpResponse createHttpResponse(int spdyVersion, SpdyHeadersFrame responseFrame) - throws Exception { + private static FullHttpResponse createHttpResponse(ChannelHandlerContext ctx, int spdyVersion, + SpdyHeadersFrame responseFrame, + boolean validateHeaders) throws Exception { + // Create the first line of the response from the name/value pairs HttpResponseStatus status = SpdyHeaders.getStatus(spdyVersion, responseFrame); HttpVersion version = SpdyHeaders.getVersion(spdyVersion, responseFrame); SpdyHeaders.removeStatus(spdyVersion, responseFrame); SpdyHeaders.removeVersion(spdyVersion, responseFrame); - 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()); }