예제 #1
0
        protected override EmbeddedChannel NewContentDecoder(ICharSequence contentEncoding)
        {
            if (HttpHeaderValues.Gzip.ContentEqualsIgnoreCase(contentEncoding) ||
                HttpHeaderValues.XGzip.ContentEqualsIgnoreCase(contentEncoding))
            {
                return(new EmbeddedChannel(
                           this.HandlerContext.Channel.Id,
                           this.HandlerContext.Channel.Metadata.HasDisconnect,
                           this.HandlerContext.Channel.Configuration,
                           ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.Gzip)));
            }

            if (HttpHeaderValues.Deflate.ContentEqualsIgnoreCase(contentEncoding) ||
                HttpHeaderValues.XDeflate.ContentEqualsIgnoreCase(contentEncoding))
            {
                ZlibWrapper wrapper = this.strict ? ZlibWrapper.Zlib : ZlibWrapper.ZlibOrNone;
                return(new EmbeddedChannel(
                           this.HandlerContext.Channel.Id,
                           this.HandlerContext.Channel.Metadata.HasDisconnect,
                           this.HandlerContext.Channel.Configuration,
                           ZlibCodecFactory.NewZlibDecoder(wrapper)));
            }

            // 'identity' or unsupported
            return(null);
        }
예제 #2
0
        public void CompressedFrame()
        {
            var encoderChannel = new EmbeddedChannel(new PerFrameDeflateEncoder(9, 15, false));
            var decoderChannel = new EmbeddedChannel(
                ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));

            var payload = new byte[300];

            this.random.NextBytes(payload);
            var frame = new BinaryWebSocketFrame(true,
                                                 WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload));

            encoderChannel.WriteOutbound(frame);
            var compressedFrame = encoderChannel.ReadOutbound <BinaryWebSocketFrame>();

            Assert.NotNull(compressedFrame);
            Assert.NotNull(compressedFrame.Content);
            Assert.IsType <BinaryWebSocketFrame>(compressedFrame);
            Assert.Equal(WebSocketRsv.Rsv1 | WebSocketRsv.Rsv3, compressedFrame.Rsv);

            decoderChannel.WriteInbound(compressedFrame.Content);
            decoderChannel.WriteInbound(DeflateDecoder.FrameTail);
            var uncompressedPayload = decoderChannel.ReadInbound <IByteBuffer>();

            Assert.Equal(300, uncompressedPayload.ReadableBytes);

            var finalPayload = new byte[300];

            uncompressedPayload.ReadBytes(finalPayload);

            Assert.Equal(payload, finalPayload);
            uncompressedPayload.Release();
        }
예제 #3
0
        static byte[] GzDecompress(byte[] input)
        {
            ZlibDecoder decoder = ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.Gzip);
            var         channel = new EmbeddedChannel(decoder);

            Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(input)));
            Assert.True(channel.Finish()); // close the channel to indicate end-of-data

            int         outputSize = 0;
            IByteBuffer o;
            var         inbound = new List <IByteBuffer>();

            while ((o = channel.ReadInbound <IByteBuffer>()) != null)
            {
                inbound.Add(o);
                outputSize += o.ReadableBytes;
            }

            var output    = new byte[outputSize];
            int readCount = 0;

            foreach (IByteBuffer b in inbound)
            {
                int readableBytes = b.ReadableBytes;
                b.ReadBytes(output, readCount, readableBytes);
                b.Release();
                readCount += readableBytes;
            }
            Assert.True(channel.InboundMessages.Count == 0 && channel.OutboundMessages.Count == 0);

            return(output);
        }
예제 #4
0
        protected override void InitChannel(ISocketChannel channel)
        {
            IChannelPipeline pipeline = channel.Pipeline;

            // Enable stream compression.
            pipeline.AddLast(ZlibCodecFactory.NewZlibEncoder(ZlibWrapper.Gzip));
            pipeline.AddLast(ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.Gzip));

            // Add the number codec first.
            pipeline.AddLast(new BigIntegerDecoder());
            pipeline.AddLast(new BigIntegerEncoder());

            // Add the business logic.
            pipeline.AddLast(new FactorialClientHandler());
        }
예제 #5
0
        protected override void InitChannel(ISocketChannel channel)
        {
            IChannelPipeline pipeline = channel.Pipeline;

            // Enable stream compresion.
            pipeline.AddLast(ZlibCodecFactory.NewZlibEncoder(ZlibWrapper.Gzip));
            pipeline.AddLast(ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.Gzip));

            // Add the number codec first.
            pipeline.AddLast(new BigIntegerDecoder());
            pipeline.AddLast(new BigIntegerEncoder());

            // Add the business logic.
            // Please note, we create a handler for every new channel, because it has stateful properties.
            pipeline.AddLast(new FactorialServerHandler());
        }
예제 #6
0
        public void SelectivityCompressionSkip()
        {
            var             selectivityCompressionFilter = new SelectivityDecompressionFilter0();
            EmbeddedChannel encoderChannel = new EmbeddedChannel(
                new PerMessageDeflateEncoder(9, 15, false, selectivityCompressionFilter));
            EmbeddedChannel decoderChannel = new EmbeddedChannel(
                ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));

            string textPayload = "not compressed payload";

            byte[] binaryPayload = new byte[101];
            _random.NextBytes(binaryPayload);

            WebSocketFrame       textFrame   = new TextWebSocketFrame(textPayload);
            BinaryWebSocketFrame binaryFrame = new BinaryWebSocketFrame(Unpooled.WrappedBuffer(binaryPayload));

            Assert.True(encoderChannel.WriteOutbound(textFrame));
            Assert.True(encoderChannel.WriteOutbound(binaryFrame));

            var outboundTextFrame = encoderChannel.ReadOutbound <WebSocketFrame>();

            //compression skipped for textFrame
            Assert.Equal(0, outboundTextFrame.Rsv);
            Assert.Equal(textPayload, outboundTextFrame.Content.ToString(Encoding.UTF8));
            Assert.True(outboundTextFrame.Release());

            var outboundBinaryFrame = encoderChannel.ReadOutbound <WebSocketFrame>();

            //compression not skipped for binaryFrame
            Assert.Equal(WebSocketRsv.Rsv1, outboundBinaryFrame.Rsv);

            Assert.True(decoderChannel.WriteInbound(outboundBinaryFrame.Content.Retain()));
            var uncompressedBinaryPayload = decoderChannel.ReadInbound <IByteBuffer>();

            Assert.Equal(binaryPayload, ByteBufferUtil.GetBytes(uncompressedBinaryPayload));

            Assert.True(outboundBinaryFrame.Release());
            Assert.True(uncompressedBinaryPayload.Release());

            Assert.False(encoderChannel.Finish());
            Assert.False(decoderChannel.Finish());
        }
예제 #7
0
        /// <summary>
        /// Returns a new <see cref="EmbeddedChannel"/> that decodes the HTTP2 message content encoded in the specified
        /// <paramref name="contentEncoding"/>.
        /// </summary>
        /// <param name="ctx">The context</param>
        /// <param name="contentEncoding">the value of the <c>content-encoding</c> header</param>
        /// <returns>a new <see cref="ByteToMessageDecoder"/> if the specified encoding is supported. <c>null</c> otherwise
        /// (alternatively, you can throw a <see cref="Http2Exception"/> to block unknown encoding).</returns>
        /// <exception cref="Http2Exception">If the specified encoding is not not supported and warrants an exception.</exception>
        protected EmbeddedChannel NewContentDecompressor(IChannelHandlerContext ctx, ICharSequence contentEncoding)
        {
            var channel = ctx.Channel;

            if (HttpHeaderValues.Gzip.ContentEqualsIgnoreCase(contentEncoding) ||
                HttpHeaderValues.XGzip.ContentEqualsIgnoreCase(contentEncoding))
            {
                return(new EmbeddedChannel(channel.Id, channel.Metadata.HasDisconnect,
                                           channel.Configuration, ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.Gzip)));
            }
            if (HttpHeaderValues.Deflate.ContentEqualsIgnoreCase(contentEncoding) ||
                HttpHeaderValues.XDeflate.ContentEqualsIgnoreCase(contentEncoding))
            {
                ZlibWrapper wrapper = _strict ? ZlibWrapper.Zlib : ZlibWrapper.ZlibOrNone;
                // To be strict, 'deflate' means ZLIB, but some servers were not implemented correctly.
                return(new EmbeddedChannel(channel.Id, channel.Metadata.HasDisconnect,
                                           channel.Configuration, ZlibCodecFactory.NewZlibDecoder(wrapper)));
            }
            // 'identity' or unsupported
            return(null);
        }
예제 #8
0
        protected internal override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, List <object> output)
        {
            if (this.decoder == null)
            {
                if (!(msg is TextWebSocketFrame) && !(msg is BinaryWebSocketFrame))
                {
                    throw new CodecException($"unexpected initial frame type: {msg.GetType().Name}");
                }

                this.decoder = new EmbeddedChannel(ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));
            }

            bool readable = msg.Content.IsReadable();

            this.decoder.WriteInbound(msg.Content.Retain());
            if (this.AppendFrameTail(msg))
            {
                this.decoder.WriteInbound(Unpooled.WrappedBuffer(FrameTail));
            }

            CompositeByteBuffer compositeUncompressedContent = ctx.Allocator.CompositeDirectBuffer();

            for (;;)
            {
                var partUncompressedContent = this.decoder.ReadInbound <IByteBuffer>();
                if (partUncompressedContent == null)
                {
                    break;
                }

                if (!partUncompressedContent.IsReadable())
                {
                    partUncompressedContent.Release();
                    continue;
                }

                compositeUncompressedContent.AddComponent(true, partUncompressedContent);
            }

            // Correctly handle empty frames
            // See https://github.com/netty/netty/issues/4348
            if (readable && compositeUncompressedContent.NumComponents <= 0)
            {
                compositeUncompressedContent.Release();
                throw new CodecException("cannot read uncompressed buffer");
            }

            if (msg.IsFinalFragment && this.noContext)
            {
                this.Cleanup();
            }

            WebSocketFrame outMsg;

            if (msg is TextWebSocketFrame)
            {
                outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent);
            }
            else if (msg is BinaryWebSocketFrame)
            {
                outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent);
            }
            else if (msg is ContinuationWebSocketFrame)
            {
                outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent);
            }
            else
            {
                throw new CodecException($"unexpected frame type: {msg.GetType().Name}");
            }

            output.Add(outMsg);
        }
예제 #9
0
        public void FramementedFrame()
        {
            var encoderChannel = new EmbeddedChannel(new PerFrameDeflateEncoder(9, 15, false));
            var decoderChannel = new EmbeddedChannel(
                ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));

            var payload1 = new byte[100];

            this.random.NextBytes(payload1);
            var payload2 = new byte[100];

            this.random.NextBytes(payload2);
            var payload3 = new byte[100];

            this.random.NextBytes(payload3);

            var frame1 = new BinaryWebSocketFrame(false,
                                                  WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload1));
            var frame2 = new ContinuationWebSocketFrame(false,
                                                        WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload2));
            var frame3 = new ContinuationWebSocketFrame(true,
                                                        WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload3));

            encoderChannel.WriteOutbound(frame1);
            encoderChannel.WriteOutbound(frame2);
            encoderChannel.WriteOutbound(frame3);
            var compressedFrame1 = encoderChannel.ReadOutbound <BinaryWebSocketFrame>();
            var compressedFrame2 = encoderChannel.ReadOutbound <ContinuationWebSocketFrame>();
            var compressedFrame3 = encoderChannel.ReadOutbound <ContinuationWebSocketFrame>();

            Assert.NotNull(compressedFrame1);
            Assert.NotNull(compressedFrame2);
            Assert.NotNull(compressedFrame3);
            Assert.Equal(WebSocketRsv.Rsv1 | WebSocketRsv.Rsv3, compressedFrame1.Rsv);
            Assert.Equal(WebSocketRsv.Rsv1 | WebSocketRsv.Rsv3, compressedFrame2.Rsv);
            Assert.Equal(WebSocketRsv.Rsv1 | WebSocketRsv.Rsv3, compressedFrame3.Rsv);
            Assert.False(compressedFrame1.IsFinalFragment);
            Assert.False(compressedFrame2.IsFinalFragment);
            Assert.True(compressedFrame3.IsFinalFragment);

            decoderChannel.WriteInbound(compressedFrame1.Content);
            decoderChannel.WriteInbound(Unpooled.WrappedBuffer(DeflateDecoder.FrameTail));
            var uncompressedPayload1 = decoderChannel.ReadInbound <IByteBuffer>();
            var finalPayload1        = new byte[100];

            uncompressedPayload1.ReadBytes(finalPayload1);
            Assert.Equal(payload1, finalPayload1);
            uncompressedPayload1.Release();

            decoderChannel.WriteInbound(compressedFrame2.Content);
            decoderChannel.WriteInbound(Unpooled.WrappedBuffer(DeflateDecoder.FrameTail));
            var uncompressedPayload2 = decoderChannel.ReadInbound <IByteBuffer>();
            var finalPayload2        = new byte[100];

            uncompressedPayload2.ReadBytes(finalPayload2);
            Assert.Equal(payload2, finalPayload2);
            uncompressedPayload2.Release();

            decoderChannel.WriteInbound(compressedFrame3.Content);
            decoderChannel.WriteInbound(Unpooled.WrappedBuffer(DeflateDecoder.FrameTail));
            var uncompressedPayload3 = decoderChannel.ReadInbound <IByteBuffer>();
            var finalPayload3        = new byte[100];

            uncompressedPayload3.ReadBytes(finalPayload3);
            Assert.Equal(payload3, finalPayload3);
            uncompressedPayload3.Release();
        }
예제 #10
0
        public void FragmentedFrame()
        {
            var encoderChannel = new EmbeddedChannel(new PerMessageDeflateEncoder(9, 15, false, NeverSkipWebSocketExtensionFilter.Instance));
            var decoderChannel = new EmbeddedChannel(
                ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));

            // initialize
            var payload1 = new byte[100];

            _random.NextBytes(payload1);
            var payload2 = new byte[100];

            _random.NextBytes(payload2);
            var payload3 = new byte[100];

            _random.NextBytes(payload3);

            var frame1 = new BinaryWebSocketFrame(false,
                                                  WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload1));
            var frame2 = new ContinuationWebSocketFrame(false,
                                                        WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload2));
            var frame3 = new ContinuationWebSocketFrame(true,
                                                        WebSocketRsv.Rsv3, Unpooled.WrappedBuffer(payload3));

            // execute
            Assert.True(encoderChannel.WriteOutbound(frame1));
            Assert.True(encoderChannel.WriteOutbound(frame2));
            Assert.True(encoderChannel.WriteOutbound(frame3));
            var compressedFrame1 = encoderChannel.ReadOutbound <BinaryWebSocketFrame>();
            var compressedFrame2 = encoderChannel.ReadOutbound <ContinuationWebSocketFrame>();
            var compressedFrame3 = encoderChannel.ReadOutbound <ContinuationWebSocketFrame>();

            // test
            Assert.NotNull(compressedFrame1);
            Assert.NotNull(compressedFrame2);
            Assert.NotNull(compressedFrame3);
            Assert.Equal(WebSocketRsv.Rsv1 | WebSocketRsv.Rsv3, compressedFrame1.Rsv);
            Assert.Equal(WebSocketRsv.Rsv3, compressedFrame2.Rsv);
            Assert.Equal(WebSocketRsv.Rsv3, compressedFrame3.Rsv);
            Assert.False(compressedFrame1.IsFinalFragment);
            Assert.False(compressedFrame2.IsFinalFragment);
            Assert.True(compressedFrame3.IsFinalFragment);

            Assert.True(decoderChannel.WriteInbound(compressedFrame1.Content));
            var uncompressedPayload1 = decoderChannel.ReadInbound <IByteBuffer>();
            var finalPayload1        = new byte[100];

            uncompressedPayload1.ReadBytes(finalPayload1);
            Assert.Equal(payload1, finalPayload1);
            uncompressedPayload1.Release();

            Assert.True(decoderChannel.WriteInbound(compressedFrame2.Content));
            var uncompressedPayload2 = decoderChannel.ReadInbound <IByteBuffer>();
            var finalPayload2        = new byte[100];

            uncompressedPayload2.ReadBytes(finalPayload2);
            Assert.Equal(payload2, finalPayload2);
            uncompressedPayload2.Release();

            Assert.True(decoderChannel.WriteInbound(compressedFrame3.Content));
            Assert.True(decoderChannel.WriteInbound(DeflateDecoder.FrameTail.Duplicate()));
            var uncompressedPayload3 = decoderChannel.ReadInbound <IByteBuffer>();
            var finalPayload3        = new byte[100];

            uncompressedPayload3.ReadBytes(finalPayload3);
            Assert.Equal(payload3, finalPayload3);
            uncompressedPayload3.Release();
        }
예제 #11
0
        private IByteBuffer DecompressContent(IChannelHandlerContext ctx, WebSocketFrame msg)
        {
            if (_decoder is null)
            {
                switch (msg.Opcode)
                {
                case Opcode.Text:
                case Opcode.Binary:
                    break;

                default:
                    ThrowHelper.ThrowCodecException_UnexpectedInitialFrameType(msg);
                    break;
                }
                _decoder = new EmbeddedChannel(ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None));
            }

            var readable          = msg.Content.IsReadable();
            var emptyDeflateBlock = EmptyDeflateBlock.Equals(msg.Content);

            _ = _decoder.WriteInbound(msg.Content.Retain());
            if (AppendFrameTail(msg))
            {
                _ = _decoder.WriteInbound(FrameTail.Duplicate());
            }

            var compositeDecompressedContent = ctx.Allocator.CompositeBuffer();

            for (; ;)
            {
                var partUncompressedContent = _decoder.ReadInbound <IByteBuffer>();
                if (partUncompressedContent is null)
                {
                    break;
                }
                if (!partUncompressedContent.IsReadable())
                {
                    _ = partUncompressedContent.Release();
                    continue;
                }
                _ = compositeDecompressedContent.AddComponent(true, partUncompressedContent);
            }
            // Correctly handle empty frames
            // See https://github.com/netty/netty/issues/4348
            if (!emptyDeflateBlock && readable && compositeDecompressedContent.NumComponents <= 0)
            {
                // Sometimes after fragmentation the last frame
                // May contain left-over data that doesn't affect decompression
                if (!(msg is ContinuationWebSocketFrame))
                {
                    _ = compositeDecompressedContent.Release();
                    ThrowHelper.ThrowCodecException_CannotReadUncompressedBuf();
                }
            }

            if (msg.IsFinalFragment && _noContext)
            {
                Cleanup();
            }

            return(compositeDecompressedContent);
        }