/// <inheritdoc/> public HttpMessageInvoker CreateClient(ForwarderHttpClientContext context) { if (CanReuseOldClient(context)) { Log.ClientReused(_logger, context.ClusterId); return(context.OldClient !); } var handler = new SocketsHttpHandler { UseProxy = false, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.None, UseCookies = false, #if NET6_0_OR_GREATER ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current) #endif // NOTE: MaxResponseHeadersLength = 64, which means up to 64 KB of headers are allowed by default as of .NET Core 3.1. }; ConfigureHandler(context, handler); var middleware = WrapHandler(context, handler); Log.ClientCreated(_logger, context.ClusterId); return(new HttpMessageInvoker(middleware, disposeHandler: true)); }
/// <summary> /// Allows configuring the <see cref="SocketsHttpHandler"/> instance. The base implementation /// applies settings from <see cref="ForwarderHttpClientContext.NewConfig"/>. /// <see cref="SocketsHttpHandler.UseProxy"/>, <see cref="SocketsHttpHandler.AllowAutoRedirect"/>, /// <see cref="SocketsHttpHandler.AutomaticDecompression"/>, and <see cref="SocketsHttpHandler.UseCookies"/> /// are disabled prior to this call. /// </summary> protected virtual void ConfigureHandler(ForwarderHttpClientContext context, SocketsHttpHandler handler) { var newConfig = context.NewConfig; if (newConfig.SslProtocols.HasValue) { handler.SslOptions.EnabledSslProtocols = newConfig.SslProtocols.Value; } if (newConfig.MaxConnectionsPerServer is not null) { handler.MaxConnectionsPerServer = newConfig.MaxConnectionsPerServer.Value; } if (newConfig.DangerousAcceptAnyServerCertificate ?? false) { handler.SslOptions.RemoteCertificateValidationCallback = delegate { return(true); }; } #if NET handler.EnableMultipleHttp2Connections = newConfig.EnableMultipleHttp2Connections.GetValueOrDefault(true); if (newConfig.RequestHeaderEncoding is not null) { var encoding = Encoding.GetEncoding(newConfig.RequestHeaderEncoding); handler.RequestHeaderEncodingSelector = (_, _) => encoding; } #endif var webProxy = TryCreateWebProxy(newConfig.WebProxy); if (webProxy is not null) { handler.Proxy = webProxy; handler.UseProxy = true; } }
/// <summary> /// Checks if the options have changed since the old client was created. If not then the /// old client will be re-used. Re-use can avoid the latency of creating new connections. /// </summary> protected virtual bool CanReuseOldClient(ForwarderHttpClientContext context) { return(context.OldClient is not null && context.NewConfig == context.OldConfig); }
/// <summary> /// Adds any wrapping middleware around the <see cref="HttpMessageHandler"/>. /// </summary> protected virtual HttpMessageHandler WrapHandler(ForwarderHttpClientContext context, HttpMessageHandler handler) { return(handler); }
public HttpMessageInvoker CreateClient(ForwarderHttpClientContext context) { return(new HttpMessageInvoker(new MockHandler(_sendAsync))); }
protected override void ConfigureHandler(ForwarderHttpClientContext context, SocketsHttpHandler handler) { base.ConfigureHandler(context, handler); handler.Expect100ContinueTimeout = TimeSpan.FromSeconds(60); }
protected override void ConfigureHandler(ForwarderHttpClientContext context, SocketsHttpHandler handler) { base.ConfigureHandler(context, handler); _configureClient(context, handler); }