public static IHttpClientBuilder UsePrimaryMessageHandlerProvider(this IHttpClientBuilder builder)
 {
     return(builder.ConfigurePrimaryHttpMessageHandler(s =>
     {
         return s.GetRequiredService <IPrimaryMessageHandlerProvider>().GetPrimaryMessageHandler();
     }));
 }
示例#2
0
        public static HttpRequestBuilder WhenRequestMatches(this IHttpClientBuilder builder, Action <HttpRequestMessage> configureAction)
        {
            var requestBuilder = new HttpRequestBuilder(builder, configureAction);

            builder.ConfigurePrimaryHttpMessageHandler(r => new MockHttpHandler(requestBuilder, new HttpClientHandler(), r.GetService <ILogger <MockHttpHandler> >()));
            return(requestBuilder);
        }
示例#3
0
 /// <summary>
 /// Some cloud services like Azure AKS use self-signed certificates not valid for httpclient.
 /// With this method we allow invalid certificates
 /// </summary>
 public static IHttpClientBuilder ConfigureKubernetesMessageHandler(this IHttpClientBuilder builder)
 {
     return(builder.ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler
     {
         ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
     }));
 }
示例#4
0
        public static IHttpClientBuilder ConfigurPrimaryHttpClientHandler(this IHttpClientBuilder httpClientBuilder, IServiceProvider s)
        {
            var options = s.GetRequiredService <IOptions <Configuration.HttpClientOptions> >();

            if (options != null)
            {
                var handler = new HttpClientHandler();

                if (options.Value.CompressionOptions.DecompressionMethods != null && options.Value.CompressionOptions.EnableAutoDecompression)
                {
                    // DecompressionMethods.None should be removed
                    DecompressionMethods decompressionMethods = DecompressionMethods.None;
                    for (int i = 0; i < options.Value.CompressionOptions.DecompressionMethods.Count(); i++)
                    {
                        if (i == 0)
                        {
                            decompressionMethods = options.Value.CompressionOptions.DecompressionMethods.ElementAt(i);
                        }
                        else
                        {
                            decompressionMethods |= options.Value.CompressionOptions.DecompressionMethods.ElementAt(i);
                        }
                    }
                    handler.AutomaticDecompression = decompressionMethods;
                }

                httpClientBuilder.ConfigurePrimaryHttpMessageHandler(h => handler);
            }

            return(httpClientBuilder);
        }
示例#5
0
        public S3Client(S3Config config, HttpMessageHandler messageHandler)
        {
            ServiceCollection services = new ServiceCollection();

            services.AddSingleton(x => Options.Create(config));

            IS3ClientBuilder   builder     = services.AddSimpleS3Core();
            IHttpClientBuilder httpBuilder = builder.UseHttpClientFactory();

            if (messageHandler != null)
            {
                httpBuilder.ConfigurePrimaryHttpMessageHandler(x => messageHandler);
            }

            httpBuilder.SetHandlerLifetime(TimeSpan.FromMinutes(5));

            Random random = new Random();

            // Policy is:
            // Retries: 3
            // Timeout: 2^attempt seconds (2, 4, 8 seconds) + -100 to 100 ms jitter
            httpBuilder.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3,
                                                                             retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
                                                                             + TimeSpan.FromMilliseconds(random.Next(-100, 100))));

            _provider      = services.BuildServiceProvider();
            _objectClient  = _provider.GetRequiredService <IS3ObjectClient>();
            _bucketClient  = _provider.GetRequiredService <IS3BucketClient>();
            _serviceClient = _provider.GetRequiredService <IS3ServiceClient>();
        }
示例#6
0
 /// <summary>
 /// Applies the default configuration to the <see cref="IHttpClientBuilder"/>.
 /// </summary>
 /// <param name="builder">The <see cref="IHttpClientBuilder"/> to apply the default configuration to.</param>
 /// <returns>
 /// The <see cref="IHttpClientBuilder"/> passed as the value of <paramref name="builder"/>.
 /// </returns>
 public static IHttpClientBuilder ApplyDefaultConfiguration(this IHttpClientBuilder builder)
 {
     return(builder
            .ConfigurePrimaryHttpMessageHandler(CreatePrimaryHttpHandler)
            .ConfigureHttpClient(ApplyDefaultConfiguration)
            .AddPolicyHandlerFromRegistry(GetRequestPolicy));
 }
示例#7
0
        private static IHttpClientBuilder AddGrpcClientCore <TClient>(this IServiceCollection services, string name, Action <GrpcClientOptions> configureClient)
            where TClient : ClientBase
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (configureClient == null)
            {
                throw new ArgumentNullException(nameof(configureClient));
            }

            // HttpContextAccessor is used to resolve the cancellation token, deadline and other request details to use with nested gRPC requests
            services.AddHttpContextAccessor();
            services.TryAddSingleton <GrpcClientFactory, DefaultGrpcClientFactory>();

            services.TryAdd(ServiceDescriptor.Transient(typeof(INamedTypedHttpClientFactory <TClient>), typeof(GrpcHttpClientFactory <TClient>)));
            services.TryAdd(ServiceDescriptor.Transient(typeof(GrpcHttpClientFactory <TClient> .Cache), typeof(GrpcHttpClientFactory <TClient> .Cache)));

            Action <IServiceProvider, HttpClient> configureTypedClient = (s, httpClient) =>
            {
                var os            = s.GetRequiredService <IOptionsMonitor <GrpcClientOptions> >();
                var clientOptions = os.Get(name);

                httpClient.BaseAddress = clientOptions.BaseAddress;
            };

            Func <IServiceProvider, HttpMessageHandler> configurePrimaryHttpMessageHandler = s =>
            {
                var os            = s.GetRequiredService <IOptionsMonitor <GrpcClientOptions> >();
                var clientOptions = os.Get(name);

                var handler = new HttpClientHandler();
                if (clientOptions.Certificate != null)
                {
                    handler.ClientCertificates.Add(clientOptions.Certificate);
                }

                return(handler);
            };

            services.Configure(name, configureClient);
            services.Configure <GrpcClientOptions>(name, options => options.ExplicitlySet = true);

            IHttpClientBuilder clientBuilder = services.AddGrpcHttpClient <TClient>(name, configureTypedClient);

            clientBuilder.ConfigurePrimaryHttpMessageHandler(configurePrimaryHttpMessageHandler);

            return(clientBuilder);
        }
示例#8
0
        protected LiveTestBase(ITestOutputHelper outputHelper)
        {
            ConfigurationBuilder configBuilder = new ConfigurationBuilder();

            configBuilder.AddJsonFile("TestConfig.json", false);

            ServiceCollection collection = new ServiceCollection();

            //Set the configuration from the config file
            configBuilder.AddUserSecrets(GetType().Assembly);
            _configRoot = configBuilder.Build();

            IS3ClientBuilder   builder           = collection.AddSimpleS3Core(ConfigureS3);
            IHttpClientBuilder httpClientBuilder = builder.UseHttpClientFactory();

            IConfigurationSection proxySection = _configRoot.GetSection("Proxy");

            if (proxySection != null && proxySection["UseProxy"].Equals("true", StringComparison.OrdinalIgnoreCase))
            {
                httpClientBuilder.ConfigurePrimaryHttpMessageHandler(x => new HttpClientHandler {
                    Proxy = new WebProxy(proxySection["ProxyAddress"])
                });
            }

            collection.AddLogging(x =>
            {
                x.AddConfiguration(_configRoot.GetSection("Logging"));
                x.AddXUnit(outputHelper);
            });

            //A small hack to remove all validators, as we test them separately
            collection.RemoveAll(typeof(IValidator <>));
            collection.RemoveAll <IValidator>();

            Services = collection.BuildServiceProvider();

            //var _bucketClient = Services.GetRequiredService<IS3BucketClient>();

            //var serviceClient = Services.GetRequiredService<IS3ServiceClient>();

            //var enumerator = serviceClient.GetAllAsync().ToListAsync().Result;

            //foreach (S3Bucket bucket in enumerator)
            //{
            //    if (bucket.Name.Contains("test", StringComparison.OrdinalIgnoreCase))
            //        _bucketClient.DeleteBucketRecursiveAsync(bucket.Name).Wait();
            //}

            BucketName = _configRoot["BucketName"] ?? "main-test-bucket-2019";

            Config        = Services.GetRequiredService <IOptions <S3Config> >().Value;
            ObjectClient  = Services.GetRequiredService <IS3ObjectClient>();
            BucketClient  = Services.GetRequiredService <IS3BucketClient>();
            ServiceClient = Services.GetRequiredService <IS3ServiceClient>();
            Transfer      = Services.GetRequiredService <Transfer>();
        }
示例#9
0
        /// <summary>
        /// 添加一个Mock Http消息处理层,用于单元测试
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static MockHttpMessageHandlerOptions AddMockHttpMessageHandler(this IHttpClientBuilder builder)
        {
            MockHttpMessageHandlerOptions options = new MockHttpMessageHandlerOptions();

            builder.ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new MockHttpMessageHandler(options));
            });
            return(options);
        }
        public static IHttpClientBuilder ConfigurePrimaryKafkaMessageHandler(this IHttpClientBuilder builder, Func <IServiceProvider, KafkaOptions> optionProvider)
        {
            builder.Services.AddKafkaClient(optionProvider);
            return(builder.ConfigurePrimaryHttpMessageHandler(provider =>
            {
                var handler = provider.GetRequiredService <KafkaMessageHandler>();

                return handler;
            }));
        }
        /// <summary>
        /// Applies the default configuration to the <see cref="IHttpClientBuilder"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IHttpClientBuilder"/> to apply the default configuration to.</param>
        /// <returns>
        /// The <see cref="IHttpClientBuilder"/> passed as the value of <paramref name="builder"/>.
        /// </returns>
        public static IHttpClientBuilder ApplyDefaultConfiguration(this IHttpClientBuilder builder)
        {
            builder.Services.AddTransient <CorrelationIdHandler>();

            return(builder
                   .ConfigurePrimaryHttpMessageHandler(CreatePrimaryHttpHandler)
                   .ConfigureHttpClient(ApplyDefaultConfiguration)
                   .AddHttpMessageHandler <CorrelationIdHandler>()
                   .AddPolicyHandlerFromRegistry(GetRequestPolicy));
        }
        public static IHttpClientBuilder ConfigurePrimaryNatsMessageHandler(this IHttpClientBuilder builder, Func <IServiceProvider, NatsQueueClientOption> optionProvider)
        {
            builder.Services.AddNatsClient(optionProvider);
            return(builder.ConfigurePrimaryHttpMessageHandler(provider =>
            {
                var handler = provider.GetRequiredService <NatsMessageHandler>();

                return handler;
            }));
        }
示例#13
0
 private static IHttpClientBuilder ConfigureMessageHandlers(this IHttpClientBuilder builder)
 {
     return(builder.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
     {
         ClientCertificateOptions = ClientCertificateOption.Automatic,
         SslProtocols = SslProtocols.Tls12,
         AllowAutoRedirect = false,
         UseDefaultCredentials = true
     }));
 }
示例#14
0
        public static IHttpClientBuilder ConfigurePrimaryRabbitMessageHandler(this IHttpClientBuilder builder, ConnectionFactory factory, Func <IServiceProvider, RabbitClientOptions> optionProvider)
        {
            builder.Services.AddRabbitClient(optionProvider);
            return(builder.ConfigurePrimaryHttpMessageHandler(provider =>
            {
                var handler = provider.GetRequiredService <RabbitMessageHandler>();
                handler.Factory = factory;

                return handler;
            }));
        }
示例#15
0
 private static IHttpClientBuilder ConfigurePodNomsHttpMessageHandler(this IHttpClientBuilder builder, bool isProduction)
 {
     if (!isProduction)
     {
         builder.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
             ClientCertificateOptions = ClientCertificateOption.Manual,
             ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => {
                 return(true);
             }
         });
     }
     return(builder);
 }
        public static IHttpClientBuilder UseDefaultPrimaryMessageHandler(
            this IHttpClientBuilder httpClientBuilder,
            Func <HttpClientHandler, HttpClientHandler> handlerConfigurator)
        {
            if (httpClientBuilder == null)
            {
                throw new ArgumentNullException(nameof(httpClientBuilder));
            }

            return(httpClientBuilder.ConfigurePrimaryHttpMessageHandler(
                       x => handlerConfigurator(new HttpClientHandler())
                       ));
        }
示例#17
0
        public static IHttpClientBuilder WithProxy(this IHttpClientBuilder httpClientBuilder, bool bypassSslCheck = true)
        {
            httpClientBuilder.ConfigurePrimaryHttpMessageHandler(() =>
            {
                var handler = new HttpClientHandler();

                if (bypassSslCheck)
                {
                    handler.ServerCertificateCustomValidationCallback = (message, certificate2, chain, errors) => true;
                }

                return(handler);
            });

            return(httpClientBuilder);
        }
示例#18
0
        public static IHttpClientBuilder ConfigureGoogleApiKeyProvider(
            this IHttpClientBuilder httpClientBuilder
            )
        {
            // Validate parameters.
            if (httpClientBuilder == null)
            {
                throw new ArgumentNullException(nameof(httpClientBuilder));
            }

            // Add the handler.
            httpClientBuilder = httpClientBuilder
                                .ConfigurePrimaryHttpMessageHandler <GoogleApiMessageHandler>();

            // Return.
            return(httpClientBuilder);
        }
示例#19
0
        /// <summary>
        /// Configures the primary HTTP message handler to validate SSL certificates using the specified <paramref name="callback"/>.
        /// </summary>
        /// <param name="builder">The instance of <see cref="IHttpClientBuilder" /> to extend.</param>
        /// <param name="callback">The callback to be used to validate SSL certificates.</param>
        /// <returns>The same instance of <see cref="IHttpClientBuilder" /> passed in <paramref name="builder"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="builder"/> cannot be null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="callback"/> cannot be null.</exception>
        public static IHttpClientBuilder ConfigureSslCertificateValidation(this IHttpClientBuilder builder, Func <HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> callback)
        {
            _ = builder ?? throw new ArgumentNullException(nameof(builder));

            _ = callback ?? throw new ArgumentNullException(nameof(callback));

            _ = builder.ConfigurePrimaryHttpMessageHandler(() =>
            {
                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = callback,
                };

                return(handler);
            });

            return(builder);
        }
        public static S3Client Create(string keyId, string accessKey, string proxyUri)
        {
            ServiceCollection services      = new ServiceCollection();
            IS3ClientBuilder  clientBuilder = services.AddSimpleS3Core(s3Config =>
            {
                s3Config.Credentials = new StringAccessKey(keyId, accessKey);
                s3Config.Region      = AwsRegion.EUWest1;
            });

            IHttpClientBuilder httpBuilder = clientBuilder.UseHttpClientFactory();

            httpBuilder.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
                Proxy = new WebProxy(proxyUri)
            });

            IServiceProvider serviceProvider = services.BuildServiceProvider();

            return(serviceProvider.GetRequiredService <S3Client>());
        }
示例#21
0
        /// <summary>
        /// Configure proxy connection for HTTP client (if enabled)
        /// </summary>
        /// <param name="httpClientBuilder">A builder for configuring HttpClient</param>
        public static void WithProxy(this IHttpClientBuilder httpClientBuilder)
        {
            httpClientBuilder.ConfigurePrimaryHttpMessageHandler(() =>
            {
                var handler = new HttpClientHandler();

                //whether proxy is enabled
                var proxySettings = EngineContext.Current.Resolve <ProxySettings>();
                if (!proxySettings.Enabled)
                {
                    return(handler);
                }

                //configure proxy connection
                var webProxy = new WebProxy($"{proxySettings.Address}:{proxySettings.Port}", proxySettings.BypassOnLocal);
                if (!string.IsNullOrEmpty(proxySettings.Username) && !string.IsNullOrEmpty(proxySettings.Password))
                {
                    webProxy.UseDefaultCredentials = false;
                    webProxy.Credentials           = new NetworkCredential
                    {
                        UserName = proxySettings.Username,
                        Password = proxySettings.Password
                    };
                }
                else
                {
                    webProxy.UseDefaultCredentials = true;
                    webProxy.Credentials           = CredentialCache.DefaultCredentials;
                }

                //configure HTTP client handler
                handler.UseDefaultCredentials = webProxy.UseDefaultCredentials;
                handler.Proxy           = webProxy;
                handler.PreAuthenticate = proxySettings.PreAuthenticate;

                return(handler);
            });
        }
 public static IHttpClientBuilder AddCompression(this IHttpClientBuilder builder)
 {
     return(builder.ConfigurePrimaryHttpMessageHandler(() => new DefaultClientHandler()));
 }
 /// <summary>
 /// Require register AddRabbitClient.
 /// </summary>
 /// <param name="builder">IHttpClientBuilder replace send request to rabbitmq</param>
 /// <returns></returns>
 public static IHttpClientBuilder ConfigurePrimaryNatsMessageHandler(this IHttpClientBuilder builder) => builder.ConfigurePrimaryHttpMessageHandler(provider => provider.GetRequiredService <NatsMessageHandler>());
示例#24
0
        /// <summary>
        /// Applies configuration from <see cref="HttpClientOptions"/> <typeparamref name="TOptions"/>
        /// to the current <see cref="HttpClient"/> registration.
        /// Options are automatically registered as well.
        /// </summary>
        /// <typeparam name="TOptions">The type of <see cref="HttpClientOptions"/> to register and use.</typeparam>
        /// <param name="builder">The <see cref="IHttpClientBuilder"/>.</param>
        /// <param name="configuration">The <see cref="IConfiguration"/>.</param>
        /// <param name="key">
        /// The configuration section key name to use.
        /// If not provided, it will be the <typeparamref name="T"/> type name without the -Options prefix.
        /// (see <see cref="ConfigurationExtensions.DefaultOptionsName(Type)"/>.
        /// </param>
        public static IHttpClientBuilder ConfigureWithOptions <TOptions>(
            this IHttpClientBuilder builder,
            IConfiguration configuration,
            string?key = null)
            where TOptions : HttpClientOptions, new()
        {
            builder.ConfigureHttpClient((sp, client) =>
            {
                var options = sp.GetRequiredService <IOptionsMonitor <TOptions> >().CurrentValue;
                if (options.BaseAddress != null)
                {
                    client.BaseAddress = options.BaseAddress;
                }

                if (options.Headers != null)
                {
                    foreach (var header in options.Headers.Where(x => !string.IsNullOrEmpty(x.Value)))
                    {
                        client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
                    }
                }

                if (client.DefaultRequestHeaders.UserAgent.Count == 0)
                {
                    var appInfo = sp.GetRequiredService <IApplicationInfo>();
                    client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", $"{appInfo.Name}/{appInfo.Version} ({appInfo.Environment})");
                }
            });

            var options = configuration.ReadOptionsAndValidate <TOptions>(key);

            if (options.Timeout != TimeSpan.Zero)
            {
                builder = builder.AddPolicyHandler(
                    Policy.TimeoutAsync(options.Timeout).AsAsyncPolicy <HttpResponseMessage>());
            }

            if (options.ErrorsAllowedBeforeBreaking > 0)
            {
                builder = builder.AddTransientHttpErrorPolicy(p => p.CircuitBreakerAsync(options.ErrorsAllowedBeforeBreaking, options.BreakDuration));
            }

            if (options.NumberOfRetries > 0)
            {
                if (options.RetriesMaximumSleepDuration == TimeSpan.FromTicks(0))
                {
                    builder = builder.AddTransientHttpErrorPolicy(
                        p => p.WaitAndRetryAsync(options.NumberOfRetries, _ => options.RetriesSleepDuration));
                }
                else
                {
                    builder = builder.AddTransientHttpErrorPolicy(
                        p => p.WaitAndRetryAsync(
                            DecorrelatedJitter(options.NumberOfRetries, options.RetriesSleepDuration, options.RetriesMaximumSleepDuration)));
                }
            }

            if (options.MaxParallelization > 0)
            {
                builder = builder.AddPolicyHandler(
                    Policy.BulkheadAsync(options.MaxParallelization).AsAsyncPolicy <HttpResponseMessage>());
            }

            if (options.IgnoreCertificateValidation)
            {
                builder.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
                });
            }

            return(builder);
        }
 public static IHttpClientBuilder UseProxy(this IHttpClientBuilder builder, IWebProxy proxy)
 {
     return(builder.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
         Proxy = proxy
     }));
 }
示例#26
0
        /// <summary>
        /// Given the <see cref="HttpHandlerMode"/>, adds the specified <typeparamref name="THandler"/> to the beginning or end of the pipeline.
        /// </summary>
        /// <typeparam name="THandler">The <see cref="DelegatingHandler"/> type to pull from the scoped <see cref="ServiceProvider"/>.</typeparam>
        /// <param name="builder">The <see cref="IHttpClientBuilder"/> instance to extend.</param>
        /// <param name="mode">A <see cref="HttpHandlerMode"/> specifying whether we are making this handler the first one in the pipeline, or the last.</param>
        /// <returns></returns>
        public static IHttpClientBuilder AddHttpMessageHandler <THandler>(this IHttpClientBuilder builder, HttpHandlerMode mode)
            where THandler : DelegatingHandler

        {
            if (mode == HttpHandlerMode.None)
            {
                return(builder);
            }
            return(mode == HttpHandlerMode.Add ? builder.AddHttpMessageHandler <THandler>() : builder.ConfigurePrimaryHttpMessageHandler <THandler>());
        }
 private static IHttpClientBuilder AddConfigureClientBuilder(this IHttpClientBuilder builder)
 {
     return(builder.ConfigurePrimaryHttpMessageHandler(HttpClientHelper.CreateHttpClientHandlerIgnoreSSLCertificatesError));
 }
示例#28
0
 public static IHttpClientBuilder AddAllowUnsignedPrimaryHandler(this IHttpClientBuilder clientBuilder)
 {
     clientBuilder.ConfigurePrimaryHttpMessageHandler(sp => sp.GetService <UnsignedHttpClientHandler>());
     return(clientBuilder);
 }