From 304eee1db44b562e0f3c960afb58804e4167bfd7 Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Tue, 6 Mar 2012 15:41:59 -0800 Subject: [PATCH] SPDY: use java.util.zip for header block decompressor --- .../handler/codec/spdy/SpdyFrameDecoder.java | 10 ++++ .../spdy/SpdyHeaderBlockDecompressor.java | 5 +- .../SpdyHeaderBlockJZlibDecompressor.java | 7 +++ .../spdy/SpdyHeaderBlockZlibDecompressor.java | 59 +++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/jboss/netty/handler/codec/spdy/SpdyHeaderBlockZlibDecompressor.java diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java index 5d0c5140e9..75a419dafe 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyFrameDecoder.java @@ -66,6 +66,16 @@ public class SpdyFrameDecoder extends FrameDecoder { this.maxHeaderSize = maxHeaderSize; } + @Override + protected Object decodeLast( + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) + throws Exception { + Object frame = decode(ctx, channel, buffer); + headerBlockDecompressor.end(); + return frame; + } + + @Override protected Object decode( ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockDecompressor.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockDecompressor.java index 119ef46454..23b9f4a04b 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockDecompressor.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockDecompressor.java @@ -20,9 +20,10 @@ import io.netty.buffer.ChannelBuffer; abstract class SpdyHeaderBlockDecompressor { static SpdyHeaderBlockDecompressor newInstance() { - return new SpdyHeaderBlockJZlibDecompressor(); + return new SpdyHeaderBlockZlibDecompressor(); } abstract void setInput(ChannelBuffer compressed); - abstract void decode(ChannelBuffer decompressed); + abstract void decode(ChannelBuffer decompressed) throws Exception; + abstract void end(); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockJZlibDecompressor.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockJZlibDecompressor.java index 4ac52da869..a177fea398 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockJZlibDecompressor.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaderBlockJZlibDecompressor.java @@ -86,4 +86,11 @@ class SpdyHeaderBlockJZlibDecompressor extends SpdyHeaderBlockDecompressor { decompressed.writeBytes(out, 0, z.next_out_index); } } + + @Override + public void end() { + z.inflateEnd(); + z.next_in = null; + z.next_out = null; + } } diff --git a/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyHeaderBlockZlibDecompressor.java b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyHeaderBlockZlibDecompressor.java new file mode 100644 index 0000000000..fc7a3665c8 --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/spdy/SpdyHeaderBlockZlibDecompressor.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.handler.codec.spdy; + +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +import org.jboss.netty.buffer.ChannelBuffer; + +import static org.jboss.netty.handler.codec.spdy.SpdyCodecUtil.*; + +class SpdyHeaderBlockZlibDecompressor extends SpdyHeaderBlockDecompressor { + + private final byte[] out = new byte[8192]; + private final Inflater decompressor = new Inflater(); + + public SpdyHeaderBlockZlibDecompressor() { + } + + @Override + public void setInput(ChannelBuffer compressed) { + byte[] in = new byte[compressed.readableBytes()]; + compressed.readBytes(in); + decompressor.setInput(in); + } + + @Override + public void decode(ChannelBuffer decompressed) throws Exception { + try { + int numBytes = decompressor.inflate(out); + if (numBytes == 0 && decompressor.needsDictionary()) { + decompressor.setDictionary(SPDY_DICT); + numBytes = decompressor.inflate(out); + } + decompressed.writeBytes(out, 0, numBytes); + } catch (DataFormatException e) { + throw new SpdyProtocolException( + "Received invalid header block"); + } + } + + @Override + public void end() { + decompressor.end(); + } +}