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); }
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()); }
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); }
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(); } }
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(); } }
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()); }
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); }
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()); }
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()); }
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]); } }