Пример #1
0
        public void DecodeContentDispositionFieldParameters()
        {
            const string Boundary        = "74e78d11b0214bdcbc2f86491eeb4902";
            const string Charset         = "utf-8";
            const string Filename        = "attached_файл.txt";
            string       filenameEncoded = HttpUtility.UrlEncode(Filename, Encoding.UTF8);

            string body = "--" + Boundary + "\r\n" +
                          "Content-Disposition: form-data; name=\"file\"; filename*=" + Charset + "''" + filenameEncoded +
                          "\r\n\r\n" +
                          "foo\r\n" +
                          "\r\n" +
                          "--" + Boundary + "--";

            var req = new DefaultFullHttpRequest(HttpVersion.Http11,
                                                 HttpMethod.Post,
                                                 "http://localhost",
                                                 Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(body)));

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            var inMemoryFactory = new DefaultHttpDataFactory(false);
            var decoder         = new HttpPostRequestDecoder(inMemoryFactory, req);

            Assert.False(decoder.GetBodyHttpDatas().Count == 0);
            IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0];

            Assert.IsAssignableFrom <IFileUpload>(part1);

            var fileUpload = (IFileUpload)part1;

            Assert.Equal(Filename, fileUpload.FileName);
            decoder.Destroy();
            req.Release();
        }
Пример #2
0
        public void MultipartRequestWithoutContentTypeBody()
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";

            var req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");

            req.Result = DecoderResult.Success;
            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            req.Headers.Add(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked);

            // Force to use memory-based data.
            var inMemoryFactory = new DefaultHttpDataFactory(false);

            var values = new[] { "", "\r", "\r\r", "\r\r\r" };

            foreach (string data in values)
            {
                string body =
                    "--" + Boundary + "\r\n" +
                    "Content-Disposition: form-data; name=\"file\"; filename=\"tmp-0.txt\"\r\n" +
                    "\r\n" +
                    data + "\r\n" +
                    "--" + Boundary + "--\r\n";

                req.Content.WriteBytes(Encoding.UTF8.GetBytes(body));
            }

            // Create decoder instance to test without any exception.
            var decoder = new HttpPostRequestDecoder(inMemoryFactory, req);
            List <IInterfaceHttpData> list = decoder.GetBodyHttpDatas();

            Assert.NotNull(list);
            Assert.False(list.Count == 0);
            decoder.Destroy();
        }
Пример #3
0
        public void MultipartRequestWithFieldInvalidCharset()
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
            var          req      = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            // Force to use memory-based data.
            var inMemoryFactory = new DefaultHttpDataFactory(false);

            const string BodyData = "some data would be here. the data should be long enough that it " +
                                    "will be longer than the original buffer length of 256 bytes in " +
                                    "the HttpPostRequestDecoder in order to trigger the issue. Some more " +
                                    "data just to be on the safe side.";

            const string Body = "--" + Boundary + "\r\n" +
                                "Content-Disposition: form-data; name=\"root\"\r\n" +
                                "Content-Type: text/plain; charset=ABCD\r\n" +
                                "\r\n" +
                                BodyData +
                                "\r\n" +
                                "--" + Boundary + "--\r\n";

            req.Content.WriteBytes(Encoding.UTF8.GetBytes(Body));
            Assert.Throws <ErrorDataDecoderException>(() => new HttpPostRequestDecoder(inMemoryFactory, req));
        }
Пример #4
0
        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");
        }
Пример #5
0
        public void DecodeMalformedEmptyContentTypeFieldParameters()
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
            var          req      = new DefaultFullHttpRequest(
                HttpVersion.Http11,
                HttpMethod.Post,
                "http://localhost");

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            // Force to use memory-based data.
            var          inMemoryFactory = new DefaultHttpDataFactory(false);
            const string Data            = "asdf";
            const string Filename        = "tmp-0.txt";
            const string Body            = "--" + Boundary + "\r\n" +
                                           "Content-Disposition: form-data; name=\"file\"; filename=\"" + Filename + "\"\r\n" +
                                           "Content-Type: \r\n" +
                                           "\r\n" +
                                           Data + "\r\n" +
                                           "--" + Boundary + "--\r\n";

            req.Content.WriteBytes(Encoding.UTF8.GetBytes(Body));
            // Create decoder instance to test.
            var decoder = new HttpPostRequestDecoder(inMemoryFactory, req);

            Assert.False(decoder.GetBodyHttpDatas().Count == 0);
            IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0];

            Assert.IsAssignableFrom <IFileUpload>(part1);
            var fileUpload = (IFileUpload)part1;

            Assert.Equal(Filename, fileUpload.FileName);
            decoder.Destroy();
        }
Пример #6
0
        public void FilenameContainingSemicolon2()
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
            var          req      = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);

            // Force to use memory-based data.
            var          inMemoryFactory = new DefaultHttpDataFactory(false);
            const string Data            = "asdf";
            const string Filename        = "tmp;0.txt";
            const string Body            = "--" + Boundary + "\r\n" +
                                           "Content-Disposition: form-data; name=\"file\"; filename=\"" + Filename + "\"\r\n" +
                                           "Content-Type: image/gif\r\n" +
                                           "\r\n" +
                                           Data + "\r\n" +
                                           "--" + Boundary + "--\r\n";

            req.Content.WriteBytes(Encoding.UTF8.GetBytes(Body));
            var decoder = new HttpPostRequestDecoder(inMemoryFactory, req);
            List <IInterfaceHttpData> list = decoder.GetBodyHttpDatas();

            Assert.NotNull(list);
            Assert.False(list.Count == 0);

            IInterfaceHttpData part1 = list[0];

            Assert.IsAssignableFrom <IFileUpload>(part1);
            var fileUpload = (IFileUpload)part1;

            Assert.Equal("tmp 0.txt", fileUpload.FileName);
            decoder.Destroy();
        }
Пример #7
0
        public DefaultHttpDataFactoryTest()
        {
            // Before doing anything, assert that the requests are equal
            Assert.Equal(_req1.GetHashCode(), _req2.GetHashCode());
            Assert.True(_req1.Equals(_req2));

            _factory = new DefaultHttpDataFactory();
        }
Пример #8
0
        public void BinaryStreamUpload(bool withSpace)
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
            string       contentTypeValue;

            if (withSpace)
            {
                contentTypeValue = "multipart/form-data; boundary=" + Boundary;
            }
            else
            {
                contentTypeValue = "multipart/form-data;boundary=" + Boundary;
            }
            var req = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");

            req.Result = DecoderResult.Success;
            req.Headers.Add(HttpHeaderNames.ContentType, contentTypeValue);
            req.Headers.Add(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked);

            // Force to use memory-based data.
            var inMemoryFactory = new DefaultHttpDataFactory(false);

            var values = new[] { "", "\r", "\r\r", "\r\r\r" };

            foreach (string data in values)
            {
                string body =
                    "--" + Boundary + "\r\n" +
                    "Content-Disposition: form-data; name=\"file\"; filename=\"tmp-0.txt\"\r\n" +
                    "Content-Type: image/gif\r\n" +
                    "\r\n" +
                    data + "\r\n" +
                    "--" + Boundary + "--\r\n";

                // Create decoder instance to test.
                var decoder = new HttpPostRequestDecoder(inMemoryFactory, req);

                decoder.Offer(new DefaultHttpContent(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(body))));
                decoder.Offer(new DefaultHttpContent(Unpooled.Empty));

                // Validate it's enough chunks to decode upload.
                Assert.True(decoder.HasNext);

                // Decode binary upload.
                IInterfaceHttpData next = decoder.Next();
                Assert.IsType <MemoryFileUpload>(next);
                var upload = (MemoryFileUpload)next;

                // Validate data has been parsed correctly as it was passed into request.
                Assert.Equal(data, upload.GetString(Encoding.UTF8));
                upload.Release();
                decoder.Destroy();
            }
        }
Пример #9
0
        public void MultipartCodecWithCRasEndOfAttribute()
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";

            // Force to use memory-based data.
            var inMemoryFactory = new DefaultHttpDataFactory(false);

            const string Extradata = "aaaa";
            var          strings   = new string[5];

            for (int i = 0; i < 4; i++)
            {
                strings[i] = Extradata;
                for (int j = 0; j < i; j++)
                {
                    strings[i] += '\r';
                }
            }

            for (int i = 0; i < 4; i++)
            {
                var req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");
                req.Result = DecoderResult.Success;
                req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
                req.Headers.Add(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked);
                string body =
                    "--" + Boundary + "\r\n" +
                    "Content-Disposition: form-data; name=\"file" + i + "\"\r\n" +
                    "Content-Type: image/gif\r\n" +
                    "\r\n" +
                    strings[i] + "\r\n" +
                    "--" + Boundary + "--\r\n";

                req.Content.WriteBytes(Encoding.UTF8.GetBytes(body));
                // Create decoder instance to test.
                var decoder = new HttpPostRequestDecoder(inMemoryFactory, req);
                List <IInterfaceHttpData> list = decoder.GetBodyHttpDatas();
                Assert.NotNull(list);
                Assert.False(list.Count == 0);

                // Check correctness: data size
                IInterfaceHttpData httpData = decoder.GetBodyHttpData($"file{i}");
                Assert.NotNull(httpData);
                var attribute = httpData as IAttribute;
                Assert.NotNull(attribute);

                byte[] data = attribute.GetBytes();
                Assert.NotNull(data);
                Assert.Equal(Encoding.UTF8.GetBytes(strings[i]).Length, data.Length);

                decoder.Destroy();
            }
        }
Пример #10
0
        public void NoZeroOut()
        {
            const string Boundary = "E832jQp_Rq2ErFmAduHSR8YlMSm0FCY";

            var aMemFactory = new DefaultHttpDataFactory(false);
            var aRequest    = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");

            aRequest.Headers.Set(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            aRequest.Headers.Set(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked);

            var aDecoder = new HttpPostRequestDecoder(aMemFactory, aRequest);

            const string BodyData = "some data would be here. the data should be long enough that it " +
                                    "will be longer than the original buffer length of 256 bytes in " +
                                    "the HttpPostRequestDecoder in order to trigger the issue. Some more " +
                                    "data just to be on the safe side.";

            const string Body = "--" + Boundary + "\r\n" +
                                "Content-Disposition: form-data; name=\"root\"\r\n" +
                                "Content-Type: text/plain\r\n" +
                                "\r\n" +
                                BodyData +
                                "\r\n" +
                                "--" + Boundary + "--\r\n";

            byte[]    aBytes = Encoding.UTF8.GetBytes(Body);
            const int Split  = 125;

            UnpooledByteBufferAllocator aAlloc = UnpooledByteBufferAllocator.Default;
            IByteBuffer aSmallBuf = aAlloc.Buffer(Split, Split);
            IByteBuffer aLargeBuf = aAlloc.Buffer(aBytes.Length - Split, aBytes.Length - Split);

            aSmallBuf.WriteBytes(aBytes, 0, Split);
            aLargeBuf.WriteBytes(aBytes, Split, aBytes.Length - Split);

            aDecoder.Offer(new DefaultHttpContent(aSmallBuf));
            aDecoder.Offer(new DefaultHttpContent(aLargeBuf));
            aDecoder.Offer(EmptyLastHttpContent.Default);

            Assert.True(aDecoder.HasNext);
            IInterfaceHttpData aDecodedData = aDecoder.Next();

            Assert.Equal(HttpDataType.Attribute, aDecodedData.DataType);

            var aAttr = (IAttribute)aDecodedData;

            Assert.Equal(BodyData, aAttr.Value);

            aDecodedData.Release();
            aDecoder.Destroy();
        }
Пример #11
0
        public void SingleFileUploadInHtml5Mode()
        {
            var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");
            var factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MinSize);
            var encoder = new HttpPostRequestEncoder(
                factory,
                request,
                true,
                //Encoding.UTF8,
                HttpPostRequestEncoder.EncoderMode.HTML5);

            FileStream fileStream1 = File.Open("./Multipart/file-01.txt", FileMode.Open, FileAccess.Read);

            this.files.Add(fileStream1);
            FileStream fileStream2 = File.Open("./Multipart/file-02.txt", FileMode.Open, FileAccess.Read);

            this.files.Add(fileStream2);

            encoder.AddBodyAttribute("foo", "bar");
            encoder.AddBodyFileUpload("quux", fileStream1, "text/plain", false);
            encoder.AddBodyFileUpload("quux", fileStream2, "text/plain", false);

            string multipartDataBoundary = encoder.MultipartDataBoundary;
            string content = GetRequestBody(encoder);

            string expected = "--" + multipartDataBoundary + "\r\n" +
                              HttpHeaderNames.ContentDisposition + ": form-data; name=\"foo\"" + "\r\n" +
                              HttpHeaderNames.ContentLength + ": 3" + "\r\n" +
                              HttpHeaderNames.ContentType + ": text/plain; charset=utf-8" + "\r\n" +
                              "\r\n" +
                              "bar" + "\r\n" +
                              "--" + multipartDataBoundary + "\r\n" +
                              HttpHeaderNames.ContentDisposition + ": form-data; name=\"quux\"; filename=\"file-01.txt\"" + "\r\n" +
                              HttpHeaderNames.ContentLength + ": " + fileStream1.Length + "\r\n" +
                              HttpHeaderNames.ContentType + ": text/plain" + "\r\n" +
                              HttpHeaderNames.ContentTransferEncoding + ": binary" + "\r\n" +
                              "\r\n" +
                              "File 01" + /*StringUtil.*/ Newline + "\r\n" +
                              "--" + multipartDataBoundary + "\r\n" +
                              HttpHeaderNames.ContentDisposition + ": form-data; name=\"quux\"; filename=\"file-02.txt\"" + "\r\n" +
                              HttpHeaderNames.ContentLength + ": " + fileStream2.Length + "\r\n" +
                              HttpHeaderNames.ContentType + ": text/plain" + "\r\n" +
                              HttpHeaderNames.ContentTransferEncoding + ": binary" + "\r\n" +
                              "\r\n" +
                              "File 02" + /*StringUtil.*/ Newline +
                              "\r\n" +
                              "--" + multipartDataBoundary + "--" + "\r\n";

            Assert.Equal(expected, content);
        }
Пример #12
0
        public void CustomBaseDirAndDeleteOnExit()
        {
            DefaultHttpDataFactory defaultHttpDataFactory = new DefaultHttpDataFactory(true);
            string dir = "target/DefaultHttpDataFactoryTest/customBaseDirAndDeleteOnExit";

            defaultHttpDataFactory.SetBaseDir(dir);
            defaultHttpDataFactory.SetDeleteOnExit(true);
            IAttribute  attr = defaultHttpDataFactory.CreateAttribute(_req1, "attribute1");
            IFileUpload fu   = defaultHttpDataFactory.CreateFileUpload(
                _req1, "attribute1", "f.txt", "text/plain", null, null, 0);

            Assert.Equal(dir, ((DiskAttribute)attr).BaseDirectory);
            Assert.Equal(dir, ((DiskFileUpload)fu).BaseDirectory);
            Assert.True(((DiskAttribute)attr).DeleteOnExit);
            Assert.True(((DiskFileUpload)fu).DeleteOnExit);
        }
Пример #13
0
        public void MultipartRequestWithFileInvalidCharset()
        {
            const string Boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
            var          req      = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost");

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            // Force to use memory-based data.
            var inMemoryFactory = new DefaultHttpDataFactory(false);

            const string Data     = "asdf";
            const string FileName = "tmp;0.txt";
            string       body     =
                "--" + Boundary + "\r\n" +
                "Content-Disposition: form-data; name=\"file\"; filename=\"" + FileName + "\"\r\n" +
                "Content-Type: image/gif; charset=ABCD\r\n" +
                "\r\n" +
                Data + "\r\n" +
                "--" + Boundary + "--\r\n";

            req.Content.WriteBytes(Encoding.UTF8.GetBytes(body));
            Assert.Throws <ErrorDataDecoderException>(() => new HttpPostRequestDecoder(inMemoryFactory, req));
        }
Пример #14
0
        public void DecodeMalformedNotEncodedContentDispositionFieldParameters()
        {
            const string Boundary = "74e78d11b0214bdcbc2f86491eeb4902";

            const string Body = "--" + Boundary + "\r\n" +
                                "Content-Disposition: form-data; name=\"file\"; filename*=not-encoded\r\n" +
                                "\r\n" +
                                "foo\r\n" +
                                "\r\n" +
                                "--" + Boundary + "--";

            var req = new DefaultFullHttpRequest(
                HttpVersion.Http11,
                HttpMethod.Post,
                "http://localhost",
                Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(Body)));

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary);
            var inMemoryFactory = new DefaultHttpDataFactory(false);

            Assert.Throws <ErrorDataDecoderException>(() => new HttpPostRequestDecoder(inMemoryFactory, req));
            req.Release();
        }
Пример #15
0
        public void DecodeOtherMimeHeaderFields()
        {
            string boundary    = "74e78d11b0214bdcbc2f86491eeb4902";
            string filecontent = "123456";

            string body = "--" + boundary + "\r\n" +
                          "Content-Disposition: form-data; name=\"file\"; filename=" + "\"" + "attached.txt" + "\"" +
                          "\r\n" +
                          "Content-Type: application/octet-stream" + "\r\n" +
                          "Content-Encoding: gzip" + "\r\n" +
                          "\r\n" +
                          filecontent +
                          "\r\n" +
                          "--" + boundary + "--";

            DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http11,
                                                                    HttpMethod.Post,
                                                                    "http://localhost",
                                                                    Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(body)));

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + boundary);
            req.Headers.Add(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked);
            DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false);
            HttpPostRequestDecoder decoder         = new HttpPostRequestDecoder(inMemoryFactory, req);

            Assert.False(decoder.GetBodyHttpDatas().Count == 0);
            IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0];

            Assert.True(part1 is IFileUpload, "the item should be a FileUpload");
            IFileUpload fileUpload = (IFileUpload)part1;

            byte[] fileBytes = fileUpload.GetBytes();
            Assert.True(filecontent.Equals(Encoding.UTF8.GetString(fileBytes)), "the filecontent should not be decoded");
            decoder.Destroy();
            req.Release();
        }
Пример #16
0
        public void DecodeWithLanguageContentDispositionFieldParametersForFix()
        {
            string boundary = "952178786863262625034234";

            string encoding        = "UTF-8";
            string filename        = "测试test.txt";
            string filenameEncoded = UrlEncoder.Default.Encode(filename /*, encoding*/);

            string body = "--" + boundary + "\r\n" +
                          "Content-Disposition: form-data; name=\"file\"; filename*=\"" +
                          encoding + "''" + filenameEncoded + "\"\r\n" +
                          "\r\n" +
                          "foo\r\n" +
                          "\r\n" +
                          "--" + boundary + "--";

            DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http11,
                                                                    HttpMethod.Post,
                                                                    "http://localhost",
                                                                    Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(body)));

            req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + boundary);
            DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false);
            HttpPostRequestDecoder decoder         = new HttpPostRequestDecoder(inMemoryFactory, req);

            Assert.NotEmpty(decoder.GetBodyHttpDatas());
            IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0];

            Assert.True(part1 is IFileUpload); // "the item should be a FileUpload"
            IFileUpload fileUpload = (IFileUpload)part1;

            Assert.Equal(filename, fileUpload.FileName); // "the filename should be decoded"

            decoder.Destroy();
            req.Release();
        }
Пример #17
0
        static async Task Main(string[] args)
        {
            var builder = new UriBuilder
            {
                Scheme = ClientSettings.IsSsl ? "https" : "http",
                Host   = ClientSettings.Host.ToString(),
                Port   = ClientSettings.Port,
            };

            var baseUri = builder.Uri.ToString();

            ExampleHelper.SetConsoleLogger();

            string postSimple, postFile, get;

            if (baseUri.EndsWith("/"))
            {
                postSimple = baseUri + "formpost";
                postFile   = baseUri + "formpostmultipart";
                get        = baseUri + "formget";
            }
            else
            {
                postSimple = baseUri + "/formpost";
                postFile   = baseUri + "/formpostmultipart";
                get        = baseUri + "/formget";
            }
            var uriSimple = new Uri(postSimple);
            var uriFile   = new Uri(postFile);

            bool useLibuv = ClientSettings.UseLibuv;

            Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket"));

            IEventLoopGroup group;

            if (useLibuv)
            {
                group = new EventLoopGroup();
            }
            else
            {
                group = new MultithreadEventLoopGroup();
            }

            X509Certificate2 cert       = null;
            string           targetHost = null;

            if (ClientSettings.IsSsl)
            {
                cert       = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
                targetHost = cert.GetNameInfo(X509NameType.DnsName, false);
            }
            try
            {
                var bootstrap = new Bootstrap();
                bootstrap
                .Group(group)
                .Option(ChannelOption.TcpNodelay, true);
                if (useLibuv)
                {
                    bootstrap.Channel <TcpChannel>();
                }
                else
                {
                    bootstrap.Channel <TcpSocketChannel>();
                }

                bootstrap.Handler(new ActionChannelInitializer <IChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;
                    if (cert != null)
                    {
                        pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost)));
                    }

                    //pipeline.AddLast(new LoggingHandler("CONN"));

                    pipeline.AddLast("codec", new HttpClientCodec());

                    // Remove the following line if you don't want automatic content decompression.
                    pipeline.AddLast("inflater", new HttpContentDecompressor());

                    // to be used since huge file transfer
                    pipeline.AddLast("chunkedWriter", new ChunkedWriteHandler <IHttpContent>());

                    pipeline.AddLast("handler", new HttpUploadClientHandler());
                }));


                // setup the factory: here using a mixed memory/disk based on size threshold
                var factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MinSize); // Disk if MINSIZE exceed

                DiskFileUpload.DeleteOnExitTemporaryFile = true;                          // should delete file on exit (in normal exit)
                DiskFileUpload.FileBaseDirectory         = null;                          // system temp directory
                DiskAttribute.DeleteOnExitTemporaryFile  = true;                          // should delete file on exit (in normal exit)
                DiskAttribute.DiskBaseDirectory          = null;                          // system temp directory

                // Simple Get form: no factory used (not usable)
                var headers = await FormgetAsync(bootstrap, get, uriSimple);

                if (headers == null)
                {
                    factory.CleanAllHttpData();
                    return;
                }

                using (var file = new FileStream("upload.txt", FileMode.Open, FileAccess.Read))
                {
                    // Simple Post form: factory used for big attributes
                    var bodylist = await FormpostAsync(bootstrap, uriSimple, file, factory, headers);

                    if (bodylist == null)
                    {
                        factory.CleanAllHttpData();
                        return;
                    }

                    // Multipart Post form: factory used
                    await FormpostmultipartAsync(bootstrap, uriFile, factory, headers, bodylist);
                }

                Console.WriteLine("按任意键退出");
                Console.ReadKey();
            }
            finally
            {
                await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }