public void DataIsMultipleOfChunkSize1() { var factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MinSize); var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost"); var encoder = new HttpPostRequestEncoder(factory, request, true, HttpPostRequestEncoder.EncoderMode.RFC1738); var first = new MemoryFileUpload("resources", "", "application/json", null, Encoding.UTF8, -1); first.MaxSize = -1; first.SetContent(new MemoryStream(new byte[7955])); encoder.AddBodyHttpData(first); var second = new MemoryFileUpload("resources2", "", "application/json", null, Encoding.UTF8, -1); second.MaxSize = -1; second.SetContent(new MemoryStream(new byte[7928])); encoder.AddBodyHttpData(second); Assert.NotNull(encoder.FinalizeRequest()); CheckNextChunkSize(encoder, 8080); CheckNextChunkSize(encoder, 8055); IHttpContent httpContent = encoder.ReadChunk(default(IByteBufferAllocator)); Assert.True(httpContent is ILastHttpContent, "Expected LastHttpContent is not received"); httpContent.Release(); Assert.True(encoder.IsEndOfInput, "Expected end of input is not receive"); }
public void TestTransferCodingGZIP() { string requestStr = "POST / HTTP/1.1\r\n" + "Content-Length: " + GzHelloWorld.Length + "\r\n" + "Transfer-Encoding: gzip\r\n" + "\r\n"; HttpRequestDecoder decoder = new HttpRequestDecoder(); HttpContentDecoder decompressor = new HttpContentDecompressor(); EmbeddedChannel channel = new EmbeddedChannel(decoder, decompressor); channel.WriteInbound(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes(requestStr))); channel.WriteInbound(Unpooled.CopiedBuffer(GzHelloWorld)); IHttpRequest request = channel.ReadInbound <IHttpRequest>(); Assert.True(request.Result.IsSuccess); Assert.False(request.Headers.Contains(HttpHeaderNames.ContentLength)); IHttpContent content = channel.ReadInbound <IHttpContent>(); Assert.True(content.Result.IsSuccess); Assert.Equal(HelloWorld, content.Content.ToString(Encoding.ASCII)); content.Release(); ILastHttpContent lastHttpContent = channel.ReadInbound <ILastHttpContent>(); Assert.True(lastHttpContent.Result.IsSuccess); lastHttpContent.Release(); AssertHasInboundMessages(channel, false); AssertHasOutboundMessages(channel, false); Assert.False(channel.Finish()); channel.ReleaseInbound(); }
public void ChunkedRequestDecompression() { HttpResponseDecoder decoder = new HttpResponseDecoder(); HttpContentDecoder decompressor = new HttpContentDecompressor(); EmbeddedChannel channel = new EmbeddedChannel(decoder, decompressor, null); string headers = "HTTP/1.1 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "Trailer: My-Trailer\r\n" + "Content-Encoding: gzip\r\n\r\n"; channel.WriteInbound(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes(headers))); string chunkLength = GzHelloWorld.Length.ToString("x2"); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(chunkLength + "\r\n", Encoding.ASCII))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(GzHelloWorld))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("\r\n")))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer("0\r\n", Encoding.ASCII))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer("My-Trailer: 42\r\n\r\n\r\n", Encoding.ASCII))); object ob1 = channel.ReadInbound <object>(); Assert.True(ob1 is DefaultHttpResponse); object ob2 = channel.ReadInbound <object>(); Assert.True(ob1 is DefaultHttpResponse); IHttpContent content = (IHttpContent)ob2; Assert.Equal(HelloWorld, content.Content.ToString(Encoding.ASCII)); content.Release(); object ob3 = channel.ReadInbound <object>(); Assert.True(ob1 is DefaultHttpResponse); ILastHttpContent lastContent = (ILastHttpContent)ob3; Assert.NotNull(lastContent.Result); Assert.True(lastContent.Result.IsSuccess); Assert.False(lastContent.TrailingHeaders.IsEmpty); Assert.Equal("42", lastContent.TrailingHeaders.Get((AsciiString)"My-Trailer", null)); AssertHasInboundMessages(channel, false); AssertHasOutboundMessages(channel, false); Assert.False(channel.Finish()); }
static void CheckNextChunkSize(HttpPostRequestEncoder encoder, int sizeWithoutDelimiter) { // 16 bytes as HttpPostRequestEncoder uses Long.toHexString(...) to generate a hex-string which will be between // 2 and 16 bytes. // See https://github.com/netty/netty/blob/4.1/codec-http/src/main/java/io/netty/handler/ // codec/http/multipart/HttpPostRequestEncoder.java#L291 int expectedSizeMin = sizeWithoutDelimiter + (2 + 2); // Two multipar boundary strings int expectedSizeMax = sizeWithoutDelimiter + (16 + 16); // Two multipar boundary strings IHttpContent httpContent = encoder.ReadChunk(default(IByteBufferAllocator)); int readable = httpContent.Content.ReadableBytes; bool expectedSize = readable >= expectedSizeMin && readable <= expectedSizeMax; Assert.True(expectedSize, $"Chunk size is not in expected range ({expectedSizeMin} - {expectedSizeMax}), was: {readable}"); httpContent.Release(); }
public void TestTransferCodingGZIPAndChunked() { string requestStr = "POST / HTTP/1.1\r\n" + "Host: example.com\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Trailer: My-Trailer\r\n" + "Transfer-Encoding: gzip, chunked\r\n" + "\r\n"; HttpRequestDecoder decoder = new HttpRequestDecoder(); HttpContentDecoder decompressor = new HttpContentDecompressor(); EmbeddedChannel channel = new EmbeddedChannel(decoder, decompressor); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(requestStr, Encoding.ASCII))); string chunkLength = GzHelloWorld.Length.ToString("x2"); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(chunkLength + "\r\n", Encoding.ASCII))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(GzHelloWorld))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("\r\n")))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer("0\r\n", Encoding.ASCII))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer("My-Trailer: 42\r\n\r\n", Encoding.ASCII))); IHttpRequest request = channel.ReadInbound <IHttpRequest>(); Assert.True(request.Result.IsSuccess); Assert.True(request.Headers.ContainsValue(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked, true)); Assert.False(request.Headers.Contains(HttpHeaderNames.ContentLength)); IHttpContent chunk1 = channel.ReadInbound <IHttpContent>(); Assert.True(chunk1.Result.IsSuccess); Assert.Equal(HelloWorld, chunk1.Content.ToString(Encoding.ASCII)); chunk1.Release(); ILastHttpContent chunk2 = channel.ReadInbound <ILastHttpContent>(); Assert.True(chunk2.Result.IsSuccess); Assert.Equal("42", chunk2.TrailingHeaders.Get(AsciiString.Of("My-Trailer"), null)); chunk2.Release(); Assert.False(channel.Finish()); channel.ReleaseInbound(); }
public void HttpPostRequestEncoderSlicedBuffer() { var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost"); var encoder = new HttpPostRequestEncoder(request, true); // add Form attribute encoder.AddBodyAttribute("getform", "POST"); encoder.AddBodyAttribute("info", "first value"); encoder.AddBodyAttribute("secondinfo", "secondvalue a&"); encoder.AddBodyAttribute("thirdinfo", "short text"); const int Length = 100000; var array = new char[Length]; array.Fill('a'); string longText = new string(array); encoder.AddBodyAttribute("fourthinfo", longText.Substring(0, 7470)); FileStream fileStream1 = File.Open("./Multipart/file-01.txt", FileMode.Open, FileAccess.Read); this.files.Add(fileStream1); encoder.AddBodyFileUpload("myfile", fileStream1, "application/x-zip-compressed", false); encoder.FinalizeRequest(); while (!encoder.IsEndOfInput) { IHttpContent httpContent = encoder.ReadChunk(null); IByteBuffer content = httpContent.Content; int refCnt = content.ReferenceCount; Assert.True( (ReferenceEquals(content.Unwrap(), content) || content.Unwrap() == null) && refCnt == 1 || !ReferenceEquals(content.Unwrap(), content) && refCnt == 2, "content: " + content + " content.unwrap(): " + content.Unwrap() + " refCnt: " + refCnt); httpContent.Release(); } encoder.CleanFiles(); encoder.Close(); }
public void TestDecodeDataAsClient() { EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(false)); IByteBuffer hello = Unpooled.CopiedBuffer("hello world", Encoding.UTF8); Assert.True(ch.WriteInbound(new DefaultHttp2DataFrame(hello))); IHttpContent content = ch.ReadInbound <IHttpContent>(); try { Assert.Equal("hello world", content.Content.ToString(Encoding.UTF8)); Assert.False(content is ILastHttpContent); } finally { content.Release(); } Assert.Null(ch.ReadInbound <object>()); Assert.False(ch.Finish()); }
public void DataIsMultipleOfChunkSize2() { var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost"); var encoder = new HttpPostRequestEncoder(request, true); const int Length = 7943; var array = new char[Length]; array.Fill('a'); string longText = new string(array); encoder.AddBodyAttribute("foo", longText); Assert.NotNull(encoder.FinalizeRequest()); // In Netty this is 8080 due to random long hex size difference CheckNextChunkSize(encoder, 109 + Length + 8); IHttpContent httpContent = encoder.ReadChunk(default(IByteBufferAllocator)); Assert.True(httpContent is ILastHttpContent, "Expected LastHttpContent is not received"); httpContent.Release(); Assert.True(encoder.IsEndOfInput, "Expected end of input is not receive"); }
public async Task ExecutorPreserveOrdering() { var sb = new ServerBootstrap(); sb.Group(new DefaultEventLoopGroup(1), new DefaultEventLoopGroup()); sb.Channel <LocalServerChannel>(); sb.ChildHandler(new ActionChannelInitializer <IChannel>(ch => { ch.Pipeline .AddLast(new HttpServerCodec()) .AddLast(new HttpObjectAggregator(1024)) .AddLast(/*compressorGroup,*/ new HttpContentCompressor()) .AddLast(new ChannelOutboundHandlerAdapter0()) .AddLast(new ChannelOutboundHandlerAdapter1()); })); var responses = new BlockingCollection <IHttpObject>(); var bs = new Bootstrap(); bs.Group(new DefaultEventLoopGroup()); bs.Channel <LocalChannel>(); bs.Handler(new ActionChannelInitializer <IChannel>(ch => { ch.Pipeline .AddLast(new HttpClientCodec()) .AddLast(new ChannelInboundHandlerAdapter0(responses)); })); IChannel serverChannel = null; IChannel clientChannel = null; try { serverChannel = await sb.BindAsync(new LocalAddress(Guid.NewGuid().ToString("N"))); clientChannel = await bs.ConnectAsync(serverChannel.LocalAddress); await clientChannel.WriteAndFlushAsync(NewRequest()); var result = responses.TryTake(out var item, TimeSpan.FromSeconds(1)); Assert.True(result); AssertEncodedResponse((IHttpResponse)item); result = responses.TryTake(out item, TimeSpan.FromSeconds(1)); Assert.True(result); IHttpContent c = (IHttpContent)item; Assert.NotNull(c); Assert.Equal($"1f8b08000000000000{Platform}f248cdc9c9d75108cf2fca4901000000ffff", ByteBufferUtil.HexDump(c.Content)); c.Release(); result = responses.TryTake(out item, TimeSpan.FromSeconds(1)); Assert.True(result); c = (IHttpContent)item; Assert.NotNull(c); Assert.Equal("0300c6865b260c000000", ByteBufferUtil.HexDump(c.Content)); c.Release(); result = responses.TryTake(out item, TimeSpan.FromSeconds(1)); Assert.True(result); ILastHttpContent last = (ILastHttpContent)item; Assert.NotNull(last); Assert.Equal(0, last.Content.ReadableBytes); last.Release(); Assert.False(responses.TryTake(out _, TimeSpan.FromSeconds(1))); } finally { if (clientChannel != null) { await clientChannel.CloseAsync(); } if (serverChannel != null) { await serverChannel.CloseAsync(); } await Task.WhenAll( sb.Group().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)), sb.ChildGroup().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)), bs.Group().ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5))); } }