-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configure SocketsHttpHandler for HttpClientFactory with IConfiguration #88864
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/ncl Issue DetailsAdds The API is .NET 5.0+ only. Fixes #84075
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I'm not an expert here.
/// </para> | ||
/// </remarks> | ||
[UnsupportedOSPlatform("browser")] | ||
public static IHttpClientBuilder UseSocketsHttpHandler(this IHttpClientBuilder builder, Action<SocketsHttpHandler, IServiceProvider>? configureHandler = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it a Use vs Add/Configure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because then it would have been ConfigurePrimaryHandlerToBeSocketsHttpHandler 😅
Point is, you don't have SocketsHttpHandler in HttpClientFactory by default - you have some PrimaryHandler, so if you'd say ConfigureSocketsHttpHandler, the question is -- where did it come from, so now we're configuring it?
So to me, saying UseSocketsHttpHandler was much clearer in explaining what happens - after you call it, the factory would be using SocketsHttpHandler in this named client (and you might decide not to configure it, if you don't specify a delegate)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ConfigureSocketsHttpHandler
would be a better name. We don't have any other APIs that are Use at this level, I'm not sure why we'd introduce this verb when it's calling a Configure* method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I agree that "Use" is very rarely used, I don't think that ConfigureSocketsHttpHandler
is better, for the reason I described above
when it's calling a Configure* method
It's calling ConfigurePrimaryHttpMessageHandler method. "Primary" is an important piece of information in relation to "Configure" verb, as Primary handler is part of HttpClientFactory's "concept", it's a "property" on an HttpClient's configuration.
Primary handler property is a "left-hand operand" in the assignment, and SocketsHttpHandler value is a "right-hand operand", so to say.
But that's my opinion; I've sent an email to the API review board to discuss this further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the example usage, I'm not sure I like "Configure..." given the nested calls to Configure(
in the builder callback.
services.AddHttpClient("baz")
.ConfigureSocketsHttpHandler(builder =>
builder.Configure(configuration.GetSection("HttpClientSettings:baz"))
.Configure((handler, _) => handler.SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = delegate { return true; },
})
);
@davidfowl During API review, I thought your feedback would be to have it return the ISocketsHttpHandlerBuilder
to reduce nesting. But if we did that, "Use..." would feel more out of place. "Add..." would be far more conventional given things like AddAuthentication
and AddMvc
, but it is a little weird that add really means replace in this case. But for completeness, the builder-returning API would look something like this:
services.AddHttpClient("baz")
.AddSocketsHttpHandler()
.Configure(configuration.GetSection("HttpClientSettings:baz"))
.Configure((handler, _) => handler.SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = delegate { return true; },
});
But as @CarnaViire pointed out in API review, this could be annoying if you need the IHttpClientBuilder
for anything else, you'd need to store the builder in a variable unless AddSocketsHttpHandler
is the last part of the chain, so we decided against it.
var httpClientBuilder = services.AddHttpClient("baz");
httpClientBuilder.AddSocketsHttpHandler()
.Configure(configuration.GetSection("HttpClientSettings:baz"))
.Configure((handler, _) => handler.SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = delegate { return true; },
});
httpClientBuilder.SomethingElseThatReturnsABuilder()
.DoSome()
.MoreThings();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use(this IWebHostBuilder) - Adding a combination of services, logging and configuration
Use(this IApplicationBuilder) - Adding middleware to the pipeline
Map(this IEndpointRouteBuilder) - Adding a route
Add(this IServiceCollection) - Adding services to the DI container
Configure(this IServiceCollecton) - Configuring options for T
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems there is still ongoing naming discussion.
Given the timelines, I asked @CarnaViire to check in current state and then leave potential name change for later once we have consensus.
That way, majority of the work will get into customers' hands in Preview7 and we have a chance to get a feedback. We can easily change the public API name afterwards as P7 is NOT go-live.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a problem with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CarnaViire can you open a follow up issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the CI failures are unrelated Known Issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a few suggestions.
...Extensions.Http/tests/Microsoft.Extensions.Http.Tests/SocketsHttpHandlerConfigurationTest.cs
Show resolved
Hide resolved
...ies/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs
Show resolved
Hide resolved
...ies/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs
Show resolved
Hide resolved
...ies/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs
Show resolved
Hide resolved
@antonfirsov per agreement with @karelz I'm merging this as-is to avoid CI delays; I will address your comments in a separate PR. |
Adds
UseSocketsHttpHandler
extension method forIHttpClientBuilder
to setSocketsHttpHandler
as a primary handler for a namedHttpClient
. AddsISocketsHttpHandlerBuilder
to configure the handler fromIConfiguration
and/or via a callback.The API is .NET 5.0+ only.
Fixes #84075