コード例 #1
0
        public void AggregateWithTrailer()
        {
            var aggregator = new HttpObjectAggregator(1024 * 1024);
            var ch         = new EmbeddedChannel(aggregator);
            var message    = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Get, "http://localhost");

            message.Headers.Set((AsciiString)"X-Test", true);
            HttpUtil.SetTransferEncodingChunked(message, true);
            var chunk1  = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test")));
            var chunk2  = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test2")));
            var trailer = new DefaultLastHttpContent();

            trailer.TrailingHeaders.Set((AsciiString)"X-Trailer", true);

            Assert.False(ch.WriteInbound(message));
            Assert.False(ch.WriteInbound(chunk1));
            Assert.False(ch.WriteInbound(chunk2));

            // this should trigger a channelRead event so return true
            Assert.True(ch.WriteInbound(trailer));
            Assert.True(ch.Finish());
            var aggregatedMessage = ch.ReadInbound <IFullHttpRequest>();

            Assert.NotNull(aggregatedMessage);

            Assert.Equal(chunk1.Content.ReadableBytes + chunk2.Content.ReadableBytes, HttpUtil.GetContentLength(aggregatedMessage));
            Assert.Equal(bool.TrueString, aggregatedMessage.Headers.Get((AsciiString)"X-Test", null)?.ToString());
            Assert.Equal(bool.TrueString, aggregatedMessage.TrailingHeaders.Get((AsciiString)"X-Trailer", null)?.ToString());
            CheckContentBuffer(aggregatedMessage);
            var last = ch.ReadInbound <object>();

            Assert.Null(last);
        }
コード例 #2
0
        public void OversizedRequest()
        {
            var aggregator = new HttpObjectAggregator(4);
            var ch         = new EmbeddedChannel(aggregator);
            var message    = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Put, "http://localhost");
            var chunk1     = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test")));
            var chunk2     = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test2")));
            EmptyLastHttpContent chunk3 = EmptyLastHttpContent.Default;

            Assert.False(ch.WriteInbound(message));
            Assert.False(ch.WriteInbound(chunk1));
            Assert.False(ch.WriteInbound(chunk2));

            var response = ch.ReadOutbound <IFullHttpResponse>();

            Assert.Equal(HttpResponseStatus.RequestEntityTooLarge, response.Status);
            Assert.Equal("0", response.Headers.Get(HttpHeaderNames.ContentLength, null));
            Assert.False(ch.Open);

            try
            {
                Assert.False(ch.WriteInbound(chunk3));
                Assert.True(false, "Shoud not get here, expecting exception thrown.");
            }
            catch (Exception e)
            {
                Assert.True(e is ClosedChannelException);
            }

            Assert.False(ch.Finish());
        }
コード例 #3
0
        public void ChunkCorrect()
        {
            const string Payload = "town=794649819&town=784444184&town=794649672&town=794657800&town=" +
                                   "794655734&town=794649377&town=794652136&town=789936338&town=789948986&town=" +
                                   "789949643&town=786358677&town=794655880&town=786398977&town=789901165&town=" +
                                   "789913325&town=789903418&town=789903579&town=794645251&town=794694126&town=" +
                                   "794694831&town=794655274&town=789913656&town=794653956&town=794665634&town=" +
                                   "789936598&town=789904658&town=789899210&town=799696252&town=794657521&town=" +
                                   "789904837&town=789961286&town=789958704&town=789948839&town=789933899&town=" +
                                   "793060398&town=794659180&town=794659365&town=799724096&town=794696332&town=" +
                                   "789953438&town=786398499&town=794693372&town=789935439&town=794658041&town=" +
                                   "789917595&town=794655427&town=791930372&town=794652891&town=794656365&town=" +
                                   "789960339&town=794645586&town=794657688&town=794697211&town=789937427&town=" +
                                   "789902813&town=789941130&town=794696907&town=789904328&town=789955151&town=" +
                                   "789911570&town=794655074&town=789939531&town=789935242&town=789903835&town=" +
                                   "789953800&town=794649962&town=789939841&town=789934819&town=789959672&town=" +
                                   "794659043&town=794657035&town=794658938&town=794651746&town=794653732&town=" +
                                   "794653881&town=786397909&town=794695736&town=799724044&town=794695926&town=" +
                                   "789912270&town=794649030&town=794657946&town=794655370&town=794659660&town=" +
                                   "794694617&town=799149862&town=789953234&town=789900476&town=794654995&town=" +
                                   "794671126&town=789908868&town=794652942&town=789955605&town=789901934&town=" +
                                   "789950015&town=789937922&town=789962576&town=786360170&town=789954264&town=" +
                                   "789911738&town=789955416&town=799724187&town=789911879&town=794657462&town=" +
                                   "789912561&town=789913167&town=794655195&town=789938266&town=789952099&town=" +
                                   "794657160&town=789949414&town=794691293&town=794698153&town=789935636&town=" +
                                   "789956374&town=789934635&town=789935475&town=789935085&town=794651425&town=" +
                                   "794654936&town=794655680&town=789908669&town=794652031&town=789951298&town=" +
                                   "789938382&town=794651503&town=794653330&town=817675037&town=789951623&town=" +
                                   "789958999&town=789961555&town=794694050&town=794650241&town=794656286&town=" +
                                   "794692081&town=794660090&town=794665227&town=794665136&town=794669931";

            var defaultHttpRequest = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Post, "/");

            var decoder = new HttpPostRequestDecoder(defaultHttpRequest);

            const int FirstChunk  = 10;
            const int MiddleChunk = 1024;

            var part1 = new DefaultHttpContent(Unpooled.WrappedBuffer(
                                                   Encoding.UTF8.GetBytes(Payload.Substring(0, FirstChunk))));
            var part2 = new DefaultHttpContent(Unpooled.WrappedBuffer(
                                                   Encoding.UTF8.GetBytes(Payload.Substring(FirstChunk, MiddleChunk))));
            var part3 = new DefaultHttpContent(Unpooled.WrappedBuffer(
                                                   Encoding.UTF8.GetBytes(Payload.Substring(FirstChunk + MiddleChunk, MiddleChunk))));
            var part4 = new DefaultHttpContent(Unpooled.WrappedBuffer(
                                                   Encoding.UTF8.GetBytes(Payload.Substring(FirstChunk + MiddleChunk * 2))));

            decoder.Offer(part1);
            decoder.Offer(part2);
            decoder.Offer(part3);
            decoder.Offer(part4);
        }
コード例 #4
0
        public void SelectiveResponseAggregation()
        {
            EmbeddedChannel channel = new EmbeddedChannel(new TestTextHttpObjectAggregator(1024 * 1024));

            try
            {
                // Aggregate: text/plain
                IHttpResponse response1 = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus.OK);
                IHttpContent  content1  = new DefaultHttpContent(Unpooled.CopiedBuffer("Hello, World!", Encoding.UTF8));
                response1.Headers.Set(HttpHeaderNames.ContentType, HttpHeaderValues.TextPlain);

                Assert.True(channel.WriteInbound(response1, content1, EmptyLastHttpContent.Default));

                // Getting an aggregated response out
                var msg1 = channel.ReadInbound();
                try
                {
                    Assert.True(msg1 is IFullHttpResponse);
                }
                finally
                {
                    ReferenceCountUtil.Release(msg1);
                }

                // Don't aggregate: application/json
                IHttpResponse response2 = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus.OK);
                IHttpContent  content2  = new DefaultHttpContent(Unpooled.CopiedBuffer("{key: 'value'}", Encoding.UTF8));
                response2.Headers.Set(HttpHeaderNames.ContentType, HttpHeaderValues.ApplicationJson);

                try
                {
                    Assert.True(channel.WriteInbound(response2, content2, EmptyLastHttpContent.Default));

                    // Getting the same response objects out
                    Assert.Same(response2, channel.ReadInbound <IHttpResponse>());
                    Assert.Same(content2, channel.ReadInbound <IHttpContent>());
                    Assert.Same(EmptyLastHttpContent.Default, channel.ReadInbound <EmptyLastHttpContent>());
                }
                finally
                {
                    ReferenceCountUtil.Release(response2);
                    ReferenceCountUtil.Release(content2);
                }

                Assert.False(channel.Finish());
            }
            finally
            {
                channel.CloseAsync();
            }
        }
コード例 #5
0
        public void SelectiveRequestAggregation()
        {
            EmbeddedChannel channel = new EmbeddedChannel(new TestPostHttpObjectAggregator(1024 * 1024));

            try
            {
                // Aggregate: POST
                IHttpRequest request1 = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Post, "/");
                IHttpContent content1 = new DefaultHttpContent(Unpooled.CopiedBuffer("Hello, World!", Encoding.UTF8));
                request1.Headers.Set(HttpHeaderNames.ContentType, HttpHeaderValues.TextPlain);

                Assert.True(channel.WriteInbound(request1, content1, EmptyLastHttpContent.Default));

                // Getting an aggregated response out
                var msg1 = channel.ReadInbound();
                try
                {
                    Assert.True(msg1 is IFullHttpRequest);
                }
                finally
                {
                    ReferenceCountUtil.Release(msg1);
                }

                // Don't aggregate: non-POST
                IHttpRequest request2 = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Put, "/");
                IHttpContent content2 = new DefaultHttpContent(Unpooled.CopiedBuffer("Hello, World!", Encoding.UTF8));
                request2.Headers.Set(HttpHeaderNames.ContentType, HttpHeaderValues.TextPlain);

                try
                {
                    Assert.True(channel.WriteInbound(request2, content2, EmptyLastHttpContent.Default));

                    // Getting the same response objects out
                    Assert.Same(request2, channel.ReadInbound <IHttpRequest>());
                    Assert.Same(content2, channel.ReadInbound <IHttpContent>());
                    Assert.Same(EmptyLastHttpContent.Default, channel.ReadInbound <EmptyLastHttpContent>());
                }
                finally
                {
                    ReferenceCountUtil.Release(request2);
                    ReferenceCountUtil.Release(content2);
                }

                Assert.False(channel.Finish());
            }
            finally
            {
                channel.CloseAsync();
            }
        }
コード例 #6
0
        public void OversizedResponse()
        {
            var aggregator = new HttpObjectAggregator(4);
            var ch         = new EmbeddedChannel(aggregator);
            var message    = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus.OK);
            var chunk1     = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test")));
            var chunk2     = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test2")));

            Assert.False(ch.WriteInbound(message));
            Assert.False(ch.WriteInbound(chunk1));
            Assert.Throws <TooLongFrameException>(() => ch.WriteInbound(chunk2));

            Assert.False(ch.Open);
            Assert.False(ch.Finish());
        }
コード例 #7
0
        public void CleanupThrows()
        {
            var decoder        = new CleanupDecoder();
            var inboundHandler = new InboundHandler();
            var channel        = new EmbeddedChannel(decoder, inboundHandler);

            Assert.True(channel.WriteInbound(new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/")));
            var content = new DefaultHttpContent(Unpooled.Buffer().WriteZero(10));

            Assert.True(channel.WriteInbound(content));
            Assert.Equal(1, content.ReferenceCount);

            Assert.Throws <DecoderException>(() => channel.FinishAndReleaseAll());
            Assert.Equal(1, inboundHandler.ChannelInactiveCalled);
            Assert.Equal(0, content.ReferenceCount);
        }
コード例 #8
0
        public void RequestAfterOversized100ContinueAndDecoder()
        {
            var ch = new EmbeddedChannel(new HttpRequestDecoder(), new HttpObjectAggregator(15));

            // Write first request with Expect: 100-continue.
            var message = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Put, "http://localhost");

            HttpUtil.Set100ContinueExpected(message, true);
            HttpUtil.SetContentLength(message, 16);

            var chunk1 = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("some")));
            var chunk2 = new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("test")));
            EmptyLastHttpContent chunk3 = EmptyLastHttpContent.Default;

            // Send a request with 100-continue + large Content-Length header value.
            Assert.False(ch.WriteInbound(message));

            // The aggregator should respond with '413'.
            var response = ch.ReadOutbound <IFullHttpResponse>();

            Assert.Equal(HttpResponseStatus.RequestEntityTooLarge, response.Status);
            Assert.Equal((AsciiString)"0", response.Headers.Get(HttpHeaderNames.ContentLength, null));

            // An ill-behaving client could continue to send data without a respect, and such data should be discarded.
            Assert.False(ch.WriteInbound(chunk1));

            // The aggregator should not close the connection because keep-alive is on.
            Assert.True(ch.Open);

            // Now send a valid request.
            var message2 = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Put, "http://localhost");

            Assert.False(ch.WriteInbound(message2));
            Assert.False(ch.WriteInbound(chunk2));
            Assert.True(ch.WriteInbound(chunk3));

            var fullMsg = ch.ReadInbound <IFullHttpRequest>();

            Assert.NotNull(fullMsg);

            Assert.Equal(chunk2.Content.ReadableBytes + chunk3.Content.ReadableBytes, HttpUtil.GetContentLength(fullMsg));
            Assert.Equal(HttpUtil.GetContentLength(fullMsg), fullMsg.Content.ReadableBytes);

            fullMsg.Release();
            Assert.False(ch.Finish());
        }
コード例 #9
0
        public void TestEncodeChunkAsClient()
        {
            EmbeddedChannel ch      = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(false));
            IByteBuffer     hello   = Unpooled.CopiedBuffer("hello world", Encoding.UTF8);
            IHttpContent    content = new DefaultHttpContent(hello);

            Assert.True(ch.WriteOutbound(content));

            var dataFrame = ch.ReadOutbound <IHttp2DataFrame>();

            try
            {
                Assert.Equal("hello world", dataFrame.Content.ToString(Encoding.UTF8));
                Assert.False(dataFrame.IsEndStream);
            }
            finally
            {
                dataFrame.Release();
            }

            Assert.Null(ch.ReadOutbound <object>());
            Assert.False(ch.Finish());
        }
コード例 #10
0
        public void ChunkedRequestWithBodyAndTrailingHeaders()
        {
            string        text            = "foooooo";
            string        text2           = "goooo";
            List <string> receivedBuffers = new List <string>();

            this.serverListener
            .Setup(x => x.OnDataRead(
                       It.IsAny <IChannelHandlerContext>(),
                       It.Is <int>(v => v == 3),
                       It.IsAny <IByteBuffer>(),
                       It.Is <int>(v => v == 0),
                       It.Is <bool>(v => v == false)))
            .Returns <IChannelHandlerContext, int, IByteBuffer, int, bool>((ctx, id, buf, p, e) =>
            {
                lock (receivedBuffers)
                {
                    receivedBuffers.Add(buf.ToString(Encoding.UTF8));
                }
                return(0);
            });
            this.BootstrapEnv(4, 1, 1);
            IHttpRequest request = new DefaultHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Post,
                                                          "http://[email protected]:5555/example");
            HttpHeaders httpHeaders = request.Headers;

            httpHeaders.Set(HttpHeaderNames.Host, "www.example.org:5555");
            httpHeaders.Add(HttpHeaderNames.TransferEncoding, "chunked");
            httpHeaders.Add(AsciiString.Of("foo"), AsciiString.Of("goo"));
            httpHeaders.Add(AsciiString.Of("foo"), AsciiString.Of("goo2"));
            httpHeaders.Add(AsciiString.Of("foo2"), AsciiString.Of("goo2"));
            var http2Headers = new DefaultHttp2Headers()
            {
                Method    = new AsciiString("POST"),
                Path      = new AsciiString("/example"),
                Authority = new AsciiString("www.example.org:5555"),
                Scheme    = new AsciiString("http")
            };

            http2Headers.Add(new AsciiString("foo"), new AsciiString("goo"));
            http2Headers.Add(new AsciiString("foo"), new AsciiString("goo2"));
            http2Headers.Add(new AsciiString("foo2"), new AsciiString("goo2"));

            DefaultHttpContent httpContent     = new DefaultHttpContent(Unpooled.CopiedBuffer(text, Encoding.UTF8));
            ILastHttpContent   lastHttpContent = new DefaultLastHttpContent(Unpooled.CopiedBuffer(text2, Encoding.UTF8));

            lastHttpContent.TrailingHeaders.Add(AsciiString.Of("trailing"), AsciiString.Of("bar"));

            IHttp2Headers http2TrailingHeaders = new DefaultHttp2Headers
            {
                { new AsciiString("trailing"), new AsciiString("bar") }
            };

            var writePromise       = this.NewPromise();
            var writeFuture        = this.clientChannel.WriteAsync(request, writePromise);
            var contentPromise     = this.NewPromise();
            var contentFuture      = this.clientChannel.WriteAsync(httpContent, contentPromise);
            var lastContentPromise = this.NewPromise();
            var lastContentFuture  = this.clientChannel.WriteAsync(lastHttpContent, lastContentPromise);

            this.clientChannel.Flush();

            Assert.True(writePromise.Task.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
            Assert.True(writePromise.IsSuccess);
            Assert.True(writeFuture.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
            Assert.True(writeFuture.IsSuccess());

            Assert.True(contentPromise.Task.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
            Assert.True(contentPromise.IsSuccess);
            Assert.True(contentFuture.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
            Assert.True(contentFuture.IsSuccess());

            Assert.True(lastContentPromise.Task.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
            Assert.True(lastContentPromise.IsSuccess);
            Assert.True(lastContentFuture.Wait(TimeSpan.FromSeconds(WAIT_TIME_SECONDS)));
            Assert.True(lastContentFuture.IsSuccess());

            this.AwaitRequests();
            this.serverListener.Verify(
                x => x.OnHeadersRead(
                    It.IsAny <IChannelHandlerContext>(),
                    It.Is <int>(v => v == 3),
                    It.Is <IHttp2Headers>(v => v.Equals(http2Headers)),
                    It.Is <int>(v => v == 0),
                    It.IsAny <short>(),
                    It.IsAny <bool>(),
                    It.Is <int>(v => v == 0),
                    It.Is <bool>(v => v == false)));
            this.serverListener.Verify(
                x => x.OnDataRead(
                    It.IsAny <IChannelHandlerContext>(),
                    It.Is <int>(v => v == 3),
                    It.IsAny <IByteBuffer>(),
                    It.Is <int>(v => v == 0),
                    It.Is <bool>(v => v == false)));
            this.serverListener.Verify(
                x => x.OnHeadersRead(
                    It.IsAny <IChannelHandlerContext>(),
                    It.Is <int>(v => v == 3),
                    It.Is <IHttp2Headers>(v => v.Equals(http2TrailingHeaders)),
                    It.Is <int>(v => v == 0),
                    It.IsAny <short>(),
                    It.IsAny <bool>(),
                    It.Is <int>(v => v == 0),
                    It.Is <bool>(v => v == true)));
            lock (receivedBuffers)
            {
                Assert.Single(receivedBuffers);
                Assert.Equal(text + text2, receivedBuffers[0]);
            }
        }