private void InitDotNetty() { _responseHandler = new HttpResponseHandler(); if (_proxyCredentials != null) { NetworkCredential credential = _proxyCredentials.GetCredential(_uri, "Basic"); //TODO 除了Basic的其它实现 string authString = !string.IsNullOrEmpty(credential.Domain) ? credential.Domain + "\\" + credential.UserName + ":" + credential.Password : credential.UserName + ":" + credential.Password; _authenticationString = new StringCharSequence($"Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes(authString))}"); _requestSetupFunc = request => request.Headers.Remove(HttpHeaderNames.ProxyAuthorization).Add(HttpHeaderNames.ProxyAuthorization, _authenticationString); } _group = new SingleThreadEventLoop(); _bootstrap = new Bootstrap(); _bootstrap .Group(_group) .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.SoKeepalive, true) .Option(ChannelOption.Allocator, new UnpooledByteBufferAllocator()) .Channel <TcpSocketChannel>() .Handler(new ActionChannelInitializer <IChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; var aggregatorHandler = new HttpObjectAggregator(_maxLength); var codecHandler = new HttpClientCodec(4096, 8192, 8192, false, false, _useProxy); if (IsHttps) { if (_proxyUri is null) { pipeline.AddTlsHandler(Host, _certificateValidationCallback); pipeline.AddLast(DotNettyHandlerNames.Codec, codecHandler); pipeline.AddLast(DotNettyHandlerNames.Aggregator, aggregatorHandler); } else { pipeline.AddLast(DotNettyHandlerNames.Codec, codecHandler); pipeline.AddLast(DotNettyHandlerNames.Aggregator, aggregatorHandler); _connectionUpgradeHandler = new ConnectionUpgradeHandler(Host, _certificateValidationCallback); pipeline.AddLast(DotNettyHandlerNames.ConnectionUpgrade, _connectionUpgradeHandler); } } else { pipeline.AddLast(DotNettyHandlerNames.Codec, codecHandler); pipeline.AddLast(DotNettyHandlerNames.Aggregator, aggregatorHandler); } pipeline.AddLast(DotNettyHandlerNames.Response, _responseHandler); _dotNettyPipelineSetupCallback?.Invoke(pipeline); })); _dotNettyBootstrapSetupCallback?.Invoke(_bootstrap); }