public void MultipleWritesToActiveStream()
        {
            _encoder.WriteSettingsAckAsync(_ctx.Object, NewPromise());
            EncoderWriteHeaders(3, NewPromise());
            Assert.Equal(0, _encoder.NumBufferedStreams());
            var data          = Data();
            int expectedBytes = data.ReadableBytes * 3;

            _encoder.WriteDataAsync(_ctx.Object, 3, data, 0, false, NewPromise());
            _encoder.WriteDataAsync(_ctx.Object, 3, Data(), 0, false, NewPromise());
            _encoder.WriteDataAsync(_ctx.Object, 3, Data(), 0, false, NewPromise());
            EncoderWriteHeaders(3, NewPromise());

            WriteVerifyWriteHeaders(Times.Exactly(2), 3);
            // Contiguous data writes are coalesced
            var bufCaptor = new ArgumentCaptor <IByteBuffer>();

            _writer.Verify(
                x => x.WriteDataAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == 3),
                    It.Is <IByteBuffer>(v => bufCaptor.Capture(v)),
                    It.Is <int>(v => v == 0),
                    It.Is <bool>(v => v == false),
                    It.IsAny <IPromise>()), Times.Once);
            Assert.Equal(expectedBytes, bufCaptor.GetValue().ReadableBytes);
        }
Пример #2
0
        public void LargeDataFrameShouldMatch()
        {
            // Create a large message to force chunking.
            var originalData    = Data(1024 * 1024);
            int originalPadding = 100;
            var endOfStream     = true;

            writer.WriteDataAsync(this.ctx.Object, STREAM_ID, originalData.Slice(), originalPadding,
                                  endOfStream, this.ctx.Object.NewPromise());
            this.ReadFrames();

            // Verify that at least one frame was sent with eos=false and exactly one with eos=true.
            this.listener.Verify(
                x => x.OnDataRead(
                    It.Is <IChannelHandlerContext>(c => c == this.ctx.Object),
                    It.Is <int>(id => id == STREAM_ID),
                    It.IsAny <IByteBuffer>(),
                    It.IsAny <int>(),
                    It.Is <bool>(v => v == false)),
                Times.AtLeastOnce());
            this.listener.Verify(
                x => x.OnDataRead(
                    It.Is <IChannelHandlerContext>(c => c == this.ctx.Object),
                    It.Is <int>(id => id == STREAM_ID),
                    It.IsAny <IByteBuffer>(),
                    It.IsAny <int>(),
                    It.Is <bool>(v => v == true)));

            // Capture the read data and padding.
            var dataCaptor    = new ArgumentCaptor <IByteBuffer>();
            var paddingCaptor = new ArgumentCaptor <int>();

            this.listener.Verify(
                x => x.OnDataRead(
                    It.Is <IChannelHandlerContext>(c => c == this.ctx.Object),
                    It.Is <int>(id => id == STREAM_ID),
                    It.Is <IByteBuffer>(d => dataCaptor.Capture(d)),
                    It.Is <int>(v => paddingCaptor.Capture(v)),
                    It.IsAny <bool>()),
                Times.AtLeastOnce());

            // Make sure the data matches the original.
            foreach (var chunk in dataCaptor.GetAllValues())
            {
                var originalChunk = originalData.ReadSlice(chunk.ReadableBytes);
                Assert.Equal(originalChunk, chunk);
            }
            Assert.False(originalData.IsReadable());

            // Make sure the padding matches the original.
            int totalReadPadding = 0;

            foreach (int framePadding in paddingCaptor.GetAllValues())
            {
                totalReadPadding += framePadding;
            }
            Assert.Equal(originalPadding, totalReadPadding);
        }
        private int CaptureWrite(int streamId)
        {
            var captor = new ArgumentCaptor <int>();

            this.writer.Verify(
                x => x.Write(
                    It.Is <IHttp2Stream>(v => ReferenceEquals(v, this.Stream(streamId))),
                    It.Is <int>(v => captor.Capture(v))));
            return(captor.GetValue());
        }
        public void ClientRequestStreamDependencyInHttpMessageFlow()
        {
            this.BootstrapEnv(1, 2, 1);
            string           text     = "hello world big time data!";
            IByteBuffer      content  = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text));
            string           text2    = "hello world big time data...number 2!!";
            IByteBuffer      content2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2));
            IFullHttpRequest request  = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put,
                                                                   "/some/path/resource", content, true);
            IFullHttpMessage request2 = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put,
                                                                   "/some/path/resource2", content2, true);

            try
            {
                HttpHeaders httpHeaders = request.Headers;
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length);
                httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);
                HttpHeaders httpHeaders2 = request2.Headers;
                httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 5);
                httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamDependencyId, 3);
                httpHeaders2.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 123);
                httpHeaders2.SetInt(HttpHeaderNames.ContentLength, text2.Length);
                var http2Headers = new DefaultHttp2Headers()
                {
                    Method = new AsciiString("PUT"),
                    Path   = new AsciiString("/some/path/resource"),
                };
                var http2Headers2 = new DefaultHttp2Headers()
                {
                    Method = new AsciiString("PUT"),
                    Path   = new AsciiString("/some/path/resource2"),
                };
                Http2TestUtil.RunInChannel(this.clientChannel, () =>
                {
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient());
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 5, http2Headers2, 3, 123, true, 0, false, this.NewPromiseClient());
                    this.clientChannel.Flush(); // Headers are queued in the flow controller and so flush them.
                    this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, content.RetainedDuplicate(), 0, true, this.NewPromiseClient());
                    this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 5, content2.RetainedDuplicate(), 0, true, this.NewPromiseClient());
                    this.clientChannel.Flush();
                });
                this.AwaitRequests();
                var httpObjectCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => httpObjectCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2));
                this.capturedRequests = httpObjectCaptor.GetAllValues();
                Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]);
                Assert.Equal(request2, this.capturedRequests[1]);
            }
            finally
            {
                request.Release();
                request2.Release();
            }
        }
Пример #5
0
        public void PingAckFrameShouldMatch()
        {
            writer.WritePingAsync(this.ctx.Object, true, 1234567, this.ctx.Object.NewPromise());
            this.ReadFrames();

            var captor = new ArgumentCaptor <long>();

            this.listener.Verify(
                x => x.OnPingAckRead(
                    It.Is <IChannelHandlerContext>(c => c == this.ctx.Object),
                    It.Is <long>(v => captor.Capture(v))));
            Assert.Equal(1234567, captor.GetValue());
        }
Пример #6
0
        private IByteBuffer CaptureWrites()
        {
            var captor = new ArgumentCaptor <IByteBuffer>();

            this.ctx.Verify(x => x.WriteAsync(It.Is <IByteBuffer>(t => captor.Capture(t)), It.IsAny <IPromise>()), Times.AtLeastOnce());
            var composite = (CompositeByteBuffer)this.ReleaseLater(Unpooled.CompositeBuffer());

            foreach (var item in captor.GetAllValues())
            {
                var buf = this.ReleaseLater((IByteBuffer)item.Retain());
                composite.AddComponent(true, buf);
            }
            return(composite);
        }
        public void PropagateSettings()
        {
            this.BootstrapEnv(1, 1, 2);
            Http2Settings settings = new Http2Settings().PushEnabled(true);

            Http2TestUtil.RunInChannel(this.clientChannel, () =>
            {
                this.clientHandler.Encoder.WriteSettingsAsync(this.CtxClient(), settings, this.NewPromiseClient());
                this.clientChannel.Flush();
            });
            Assert.True(this.settingsLatch.Wait(TimeSpan.FromSeconds(5)));
            var settingsCaptor = new ArgumentCaptor <Http2Settings>();

            this.settingsListener.Verify(x => x.MessageReceived(It.Is <Http2Settings>(v => settingsCaptor.Capture(v))), Times.Exactly(2));
            Assert.Equal(settings, settingsCaptor.GetValue());
        }
Пример #8
0
        public void ServerReceivingInvalidClientPrefaceStringShouldHandleException()
        {
            _connection.Setup(x => x.IsServer).Returns(true);
            _handler = NewHandler();
            _handler.ChannelRead(_ctx.Object, Unpooled.CopiedBuffer("BAD_PREFACE", Encoding.UTF8));
            var captor = new ArgumentCaptor <IByteBuffer>();

            _frameWriter.Verify(
                x => x.WriteGoAwayAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == 0),
                    It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                    It.Is <IByteBuffer>(v => captor.Capture(v)),
                    It.Is <IPromise>(v => v == _promise)));
            Assert.Equal(0, captor.GetValue().ReferenceCount);
        }
Пример #9
0
        public void ServerReceivingHttp1ClientPrefaceStringShouldIncludePreface()
        {
            _connection.Setup(x => x.IsServer).Returns(true);
            _handler = NewHandler();
            _handler.ChannelRead(_ctx.Object, Unpooled.CopiedBuffer("GET /path HTTP/1.1", Encoding.ASCII));
            var captor = new ArgumentCaptor <IByteBuffer>();

            _frameWriter.Verify(
                x => x.WriteGoAwayAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == 0),
                    It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                    It.Is <IByteBuffer>(v => captor.Capture(v)),
                    It.Is <IPromise>(v => v == _promise)));
            Assert.Equal(0, captor.GetValue().ReferenceCount);
            Assert.Contains("/path", _goAwayDebugCap);
        }
        private int CaptureWrites(IHttp2Stream stream)
        {
            var captor = new ArgumentCaptor <int>();

            this.writer.Verify(
                x => x.Write(
                    It.Is <IHttp2Stream>(v => ReferenceEquals(v, stream)),
                    It.Is <int>(v => captor.Capture(v))),
                Times.AtLeastOnce());
            int total = 0;

            foreach (var x in captor.GetAllValues())
            {
                total += x;
            }
            return(total);
        }
        public void ClientRequestTrailingHeaders()
        {
            this.BootstrapEnv(1, 1, 1);
            string           text    = "some data";
            IByteBuffer      content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text));
            IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get,
                                                                  "/some/path/resource2", content, true);

            try
            {
                HttpHeaders httpHeaders = request.Headers;
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length);
                httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);
                HttpHeaders trailingHeaders = request.TrailingHeaders;
                trailingHeaders.Set(AsciiString.Of("Foo"), AsciiString.Of("goo"));
                trailingHeaders.Set(AsciiString.Of("fOo2"), AsciiString.Of("goo2"));
                trailingHeaders.Add(AsciiString.Of("foO2"), AsciiString.Of("goo3"));
                var http2Headers = new DefaultHttp2Headers()
                {
                    Method = new AsciiString("GET"),
                    Path   = new AsciiString("/some/path/resource2"),
                };
                IHttp2Headers http2Headers2 = new DefaultHttp2Headers();
                http2Headers2.Set(new AsciiString("foo"), new AsciiString("goo"));
                http2Headers2.Set(new AsciiString("foo2"), new AsciiString("goo2"));
                http2Headers2.Add(new AsciiString("foo2"), new AsciiString("goo3"));
                Http2TestUtil.RunInChannel(this.clientChannel, () =>
                {
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient());
                    this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, content.RetainedDuplicate(), 0, false, this.NewPromiseClient());
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers2, 0, true, this.NewPromiseClient());
                    this.clientChannel.Flush();
                });
                this.AwaitRequests();
                var requestCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v))));
                this.capturedRequests = requestCaptor.GetAllValues();
                Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]);
            }
            finally
            {
                request.Release();
            }
        }
Пример #12
0
        public void GoAwayFrameShouldMatch()
        {
            string text = "test";
            var    data = Buf(Encoding.UTF8.GetBytes(text));

            writer.WriteGoAwayAsync(this.ctx.Object, STREAM_ID, ERROR_CODE, data.Slice(), this.ctx.Object.NewPromise());
            this.ReadFrames();

            var captor = new ArgumentCaptor <IByteBuffer>();

            this.listener.Verify(
                x => x.OnGoAwayRead(
                    It.Is <IChannelHandlerContext>(c => c == this.ctx.Object),
                    It.Is <int>(id => id == STREAM_ID),
                    It.Is <Http2Error>(v => v == ERROR_CODE),
                    It.Is <IByteBuffer>(v => captor.Capture(v))));
            Assert.Equal(data, captor.GetValue());
        }
Пример #13
0
        public void ServerShouldSend431OnHeaderSizeErrorWhenDecodingInitialHeaders()
        {
            int padding = 0;

            _handler = NewHandler();
            Http2Exception e = new HeaderListSizeException(STREAM_ID, Http2Error.ProtocolError,
                                                           "Header size exceeded max allowed size 8196", true);

            _stream.Setup(x => x.Id).Returns(STREAM_ID);
            _connection.Setup(x => x.IsServer).Returns(true);
            _stream.Setup(x => x.IsHeadersSent).Returns(false);
            _remote.Setup(x => x.LastStreamCreated).Returns(STREAM_ID);
            _frameWriter
            .Setup(x => x.WriteRstStreamAsync(
                       It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                       It.Is <int>(v => v == STREAM_ID),
                       It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                       It.Is <IPromise>(v => v == _promise)))
            .Returns(_future);

            _handler.ExceptionCaught(_ctx.Object, e);

            var captor = new ArgumentCaptor <IHttp2Headers>();

            _encoder.Verify(
                x => x.WriteHeadersAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == STREAM_ID),
                    It.Is <IHttp2Headers>(v => captor.Capture(v)),
                    It.Is <int>(v => v == padding),
                    It.Is <bool>(v => v == true),
                    It.Is <IPromise>(v => v == _promise)));
            IHttp2Headers headers = captor.GetValue();

            Assert.Equal(HttpResponseStatus.RequestHeaderFieldsTooLarge.CodeAsText, headers.Status);
            _frameWriter.Verify(
                x => x.WriteRstStreamAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == STREAM_ID),
                    It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                    It.Is <IPromise>(v => v == _promise)));
        }
        public void ClientRequestSingleHeaderCookieSplitIntoMultipleEntries()
        {
            this.BootstrapEnv(1, 1, 1);
            IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get,
                                                                  "/some/path/resource2", true);

            try
            {
                HttpHeaders httpHeaders = request.Headers;
                httpHeaders.Set(HttpConversionUtil.ExtensionHeaderNames.Scheme, "https");
                httpHeaders.Set(HttpHeaderNames.Host, "example.org");
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0);
                httpHeaders.Set(HttpHeaderNames.Cookie, "a=b; c=d; e=f");
                httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);
                var http2Headers = new DefaultHttp2Headers()
                {
                    Method    = new AsciiString("GET"),
                    Scheme    = new AsciiString("https"),
                    Authority = new AsciiString("example.org"),
                    Path      = new AsciiString("/some/path/resource2"),
                };
                http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"a=b");
                http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"c=d");
                http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"e=f");
                Http2TestUtil.RunInChannel(this.clientChannel, () =>
                {
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, true, this.NewPromiseClient());
                    this.clientChannel.Flush();
                });
                this.AwaitRequests();
                var requestCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v))));
                this.capturedRequests = requestCaptor.GetAllValues();
                Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]);
            }
            finally
            {
                request.Release();
            }
        }
Пример #15
0
        public void ServerReceivingClientPrefaceStringFollowedByNonSettingsShouldHandleException()
        {
            _connection.Setup(x => x.IsServer).Returns(true);
            _handler = NewHandler();

            // Create a connection preface followed by a bunch of zeros (i.e. not a settings frame).
            IByteBuffer buf = Unpooled.Buffer().WriteBytes(Http2CodecUtil.ConnectionPrefaceBuf()).WriteZero(10);

            _handler.ChannelRead(_ctx.Object, buf);
            var captor = new ArgumentCaptor <IByteBuffer>();

            _frameWriter.Verify(
                x => x.WriteGoAwayAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == 0),
                    It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                    It.Is <IByteBuffer>(v => captor.Capture(v)),
                    It.Is <IPromise>(v => v == _promise)),
                Times.AtLeastOnce);
            Assert.Equal(0, captor.GetValue().ReferenceCount);
        }
Пример #16
0
        public void ConnectionErrorShouldStartShutdown()
        {
            _handler = NewHandler();
            Http2Exception e = new Http2Exception(Http2Error.ProtocolError);

            _remote.Setup(x => x.LastStreamCreated).Returns(STREAM_ID);
            _handler.ExceptionCaught(_ctx.Object, e);
            var captor = new ArgumentCaptor <IByteBuffer>();

            _frameWriter.Verify(
                x => x.WriteGoAwayAsync(
                    It.Is <IChannelHandlerContext>(v => v == _ctx.Object),
                    It.Is <int>(v => v == STREAM_ID),
                    It.Is <Http2Error>(v => v == Http2Error.ProtocolError),
                    It.Is <IByteBuffer>(v => captor.Capture(v)),
                    It.Is <IPromise>(v => v == _promise)));
            var buf = captor.GetValue();

            Assert.Equal(0, buf.ReferenceCount);
            // netty future.addListener 只配置了 ChannelFutureListener 的监听,而且isDone返回的值为false
            // 所以 processGoAwayWriteResult 没有执行
            //Assert.Equal(1, buf.ReferenceCount);
            //buf.Release();
        }
        public void ServerRequestPushPromise()
        {
            this.BootstrapEnv(1, 1, 1);
            string           text     = "hello world big time data!";
            IByteBuffer      content  = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text));
            string           text2    = "hello world smaller data?";
            IByteBuffer      content2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2));
            IFullHttpMessage response = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.OK,
                                                                    content, true);
            IFullHttpMessage response2 = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.Created,
                                                                     content2, true);
            IFullHttpMessage request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/push/test",
                                                                  true);

            try
            {
                HttpHeaders httpHeaders = response.Headers;
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length);
                httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);
                HttpHeaders httpHeaders2 = response2.Headers;
                httpHeaders2.Set(HttpConversionUtil.ExtensionHeaderNames.Scheme, "https");
                httpHeaders2.Set(HttpHeaderNames.Host, "example.org");
                httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 5);
                httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamDependencyId, 3);
                httpHeaders2.SetInt(HttpHeaderNames.ContentLength, text2.Length);

                httpHeaders = request.Headers;
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0);
                httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);
                var http2Headers3 = new DefaultHttp2Headers()
                {
                    Method = new AsciiString("GET"),
                    Path   = new AsciiString("/push/test"),
                };
                Http2TestUtil.RunInChannel(this.clientChannel, () =>
                {
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers3, 0, true, this.NewPromiseClient());
                    this.clientChannel.Flush();
                });
                this.AwaitRequests();
                var requestCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v))));
                this.capturedRequests = requestCaptor.GetAllValues();
                Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]);

                IHttp2Headers http2Headers = new DefaultHttp2Headers()
                {
                    Status = new AsciiString("200")
                };
                // The PUSH_PROMISE frame includes a header block that contains a
                // complete set of request header fields that the server attributes to
                // the request.
                // https://tools.ietf.org/html/rfc7540#section-8.2.1
                // Therefore, we should consider the case where there is no Http response status.
                IHttp2Headers http2Headers2 = new DefaultHttp2Headers()
                {
                    Scheme    = new AsciiString("https"),
                    Authority = new AsciiString("example.org")
                };
                Http2TestUtil.RunInChannel(this.serverConnectedChannel, () =>
                {
                    this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2Headers, 0, false, this.NewPromiseServer());
                    this.serverHandler.Encoder.WritePushPromiseAsync(this.CtxServer(), 3, 2, http2Headers2, 0, this.NewPromiseServer());
                    this.serverHandler.Encoder.WriteDataAsync(this.CtxServer(), 3, content.RetainedDuplicate(), 0, true, this.NewPromiseServer());
                    this.serverHandler.Encoder.WriteDataAsync(this.CtxServer(), 5, content2.RetainedDuplicate(), 0, true, this.NewPromiseServer());
                    this.serverConnectedChannel.Flush();
                });
                this.AwaitResponses();
                var responseCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.clientListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => responseCaptor.Capture((IFullHttpMessage)v))));
                this.capturedResponses = responseCaptor.GetAllValues();
                Assert.Equal(response, this.capturedResponses[0]);
            }
            finally
            {
                request.Release();
                response.Release();
                response2.Release();
            }
        }
Пример #18
0
        public void EntityRequestEntityResponse()
        {
            _frameInboundWriter.WriteInboundHeaders(1, _request, 0, false);

            IHttp2Stream stream = _frameCodec.Connection.Stream(1);

            Assert.NotNull(stream);
            Assert.Equal(Http2StreamState.Open, stream.State);

            IHttp2HeadersFrame inboundHeaders = _inboundHandler.ReadInbound <IHttp2HeadersFrame>();
            IHttp2FrameStream  stream2        = inboundHeaders.Stream;

            Assert.NotNull(stream2);
            Assert.Equal(1, stream2.Id);
            Assert.Equal(new DefaultHttp2HeadersFrame(_request, false)
            {
                Stream = stream2
            }, inboundHeaders);
            Assert.Null(_inboundHandler.ReadInbound());

            IByteBuffer hello = Http2TestUtil.BB("hello");

            _frameInboundWriter.WriteInboundData(1, hello, 31, true);
            IHttp2DataFrame inboundData = _inboundHandler.ReadInbound <IHttp2DataFrame>();
            IHttp2DataFrame expected    = new DefaultHttp2DataFrame(Http2TestUtil.BB("hello"), true, 31)
            {
                Stream = stream2
            };

            Http2TestUtil.AssertEqualsAndRelease(expected, inboundData);

            Assert.Null(_inboundHandler.ReadInbound());

            _channel.WriteOutbound(new DefaultHttp2HeadersFrame(_response, false)
            {
                Stream = stream2
            });
            _frameWriter.Verify(
                x => x.WriteHeadersAsync(
                    It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx),
                    It.Is <int>(v => v == 1),
                    It.Is <IHttp2Headers>(v => v.Equals(_response)),
                    It.Is <int>(v => v == 0),
                    It.Is <bool>(v => v == false),
                    It.IsAny <IPromise>()));

            _channel.WriteOutbound(new DefaultHttp2DataFrame(Http2TestUtil.BB("world"), true, 27)
            {
                Stream = stream2
            });
            var outboundData = new ArgumentCaptor <IByteBuffer>();

            _frameWriter.Verify(
                x => x.WriteDataAsync(
                    It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx),
                    It.Is <int>(v => v == 1),
                    It.Is <IByteBuffer>(v => outboundData.Capture(v)),
                    It.Is <int>(v => v == 27),
                    It.Is <bool>(v => v == true),
                    It.IsAny <IPromise>()));

            IByteBuffer bb = Http2TestUtil.BB("world");

            Assert.Equal(bb, outboundData.GetValue());
            Assert.Equal(1, outboundData.GetValue().ReferenceCount);
            bb.Release();
            outboundData.GetValue().Release();

            _frameWriter.Verify(
                x => x.WriteRstStreamAsync(
                    It.Is <IChannelHandlerContext>(v => v == _frameCodec._ctx),
                    It.IsAny <int>(),
                    It.IsAny <Http2Error>(),
                    It.IsAny <IPromise>()), Times.Never());
            Assert.True(_channel.IsActive);
        }
        public void ServerResponseHeaderInformational()
        {
            this.BootstrapEnv(1, 2, 1, 2, 1);
            IFullHttpMessage request     = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/info/test", true);
            HttpHeaders      httpHeaders = request.Headers;

            httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
            httpHeaders.Set(HttpHeaderNames.Expect, HttpHeaderValues.Continue);
            httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0);
            httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);

            IHttp2Headers http2Headers = new DefaultHttp2Headers()
            {
                Method = new AsciiString("PUT"),
                Path   = new AsciiString("/info/test")
            };

            http2Headers.Set(new AsciiString(HttpHeaderNames.Expect.ToString()), new AsciiString(HttpHeaderValues.Continue.ToString()));
            IFullHttpMessage response  = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.Continue);
            string           text      = "a big payload";
            IByteBuffer      payload   = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text));
            IFullHttpMessage request2  = (IFullHttpMessage)request.Replace(payload);
            IFullHttpMessage response2 = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.OK);

            try
            {
                Http2TestUtil.RunInChannel(this.clientChannel, () =>
                {
                    this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient());
                    this.clientChannel.Flush();
                });

                this.AwaitRequests();
                httpHeaders = response.Headers;
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0);
                IHttp2Headers http2HeadersResponse = new DefaultHttp2Headers()
                {
                    Status = new AsciiString("100")
                };
                Http2TestUtil.RunInChannel(this.serverConnectedChannel, () =>
                {
                    this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2HeadersResponse, 0, false, this.NewPromiseServer());
                    this.serverConnectedChannel.Flush();
                });

                this.AwaitResponses();
                httpHeaders = request2.Headers;
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length);
                httpHeaders.Remove(HttpHeaderNames.Expect);
                Http2TestUtil.RunInChannel(this.clientChannel, () =>
                {
                    this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, payload.RetainedDuplicate(), 0, true, this.NewPromiseClient());
                    this.clientChannel.Flush();
                });

                this.AwaitRequests2();
                httpHeaders = response2.Headers;
                httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3);
                httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0);
                httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16);

                IHttp2Headers http2HeadersResponse2 = new DefaultHttp2Headers()
                {
                    Status = new AsciiString("200")
                };
                Http2TestUtil.RunInChannel(this.serverConnectedChannel, () =>
                {
                    this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2HeadersResponse2, 0, true, this.NewPromiseServer());
                    this.serverConnectedChannel.Flush();
                });

                this.AwaitResponses2();
                var requestCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2));
                this.capturedRequests = requestCaptor.GetAllValues();
                Assert.Equal(2, this.capturedRequests.Count);
                // We do not expect to have this header in the captured request so remove it now.
                Assert.NotNull(request.Headers.Remove((AsciiString)"x-http2-stream-weight"));

                Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]);
                Assert.Equal(request2, this.capturedRequests[1]);

                var responseCaptor = new ArgumentCaptor <IFullHttpMessage>();
                this.clientListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => responseCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2));
                this.capturedResponses = responseCaptor.GetAllValues();
                Assert.Equal(2, this.capturedResponses.Count);
                Assert.Equal(response, this.capturedResponses[0]);
                Assert.Equal(response2, this.capturedResponses[1]);
            }
            finally
            {
                request.Release();
                request2.Release();
                response.Release();
                response2.Release();
            }
        }