-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[API Proposal]: HTTP/3 Add QuicConnectCallback #64449
Comments
Tagging subscribers to this area: @dotnet/ncl Issue DetailsBackground and motivationSince 5.0 we provide ability to customize socket-based connections in
For 7.0 milestone, we decided to only allow the second requirement, customizing Also for the callback to make sense we should expand
More details in my notes: https://gist.github.com/ManickaP/7a96748c6789f008e4e0597b9b883487 As a side note, related to this API is API Proposalnamespace System.Net.Http
{
public sealed class SocketsHttpHandler : HttpMessageHandler
{
public Func<SocketsHttpConnectionContext, CancellationToken, ValueTask<Stream>>? ConnectCallback { get; set; }
+ public Func<SocketsHttpConnectionContext, CancellationToken, ValueTask<QuicConnection>>? QuicConnectCallback { get; set; }
}
} API UsagesocketsHandler.QuicConnectCallback = async (context, token) =>
{
// Do custom DNS query: https://gist.github.com/ManickaP/7a96748c6789f008e4e0597b9b883487#custom-name-resolution
// Set up connection differently: https://gist.github.com/ManickaP/7a96748c6789f008e4e0597b9b883487#connection-settings
// Most simple connection creation bellow:
var quicConnection = new QuicConnection(new QuicClientConnectionOptions() {
RemoteEndPoint = context.DnsEndPoint,
ClientAuthenticationOptions = new SslClientAuthenticationOptions() {
ApplicationProtocols = new List<SslApplicationProtocol>() {
SslApplicationProtocol.Http3
}
}
});
await quicConnection.ConnectAsync(token).ConfigureAwait(false);
return quicConnection;
}; Alternative DesignsNot doing anything at the moment. RisksDue to limited usages of HTTP/3 and QUIC, newness of these protocols in our stack, we don't have much feedback yet. The design is based on requirements for previous HTTP versions and sockets. As a result, the need for this callback might be non-existent and we're adding new API with no usefulness. On the other hand, if we do nothing we might never get any feedback and/or adoption and thus will never know how to improve this. Moreover, the API surface is small and the design is conservative with future in mind. Mitigation might be hiding the API behind
|
gRPC uses ConnectCallback for two things:
I believe there are plans for connection management API on SocketsHttpHandler in .NET 7. Tracking active connections might get replaced by that in .NET 7. |
Do I get it right that this is for the load-balancer? How critical the connection counting is for gRPC over HTTP/3? I'd love to understand the use case and necessity for this before we start adding other features on cc: @JamesNK |
Even though it does not have a direct impact on this API, getting notified about |
Without the ability to replace the transport, does it mean impossible to inject a |
Yes, for now, that's the plan for 7.0. For future releases, we'll revisit the abstractions. We want some usage and feedback before going all in. |
I'm not too familiar with quic (and it's SNI), but a scenario I'm planning to use ConnectCallback for is to be able to manually resolve the DnsEnpoint to an IpAddress and put it through a blocklist (make sure it does not target an internal ip address) and then use the validated ip address to setup the connection. This is part of a SSRF prevention mechanism when the application need to be able to connect to addresses provided by an end user. Since this is not possible to be setup for quic, http3 should be disabled. |
Background and motivation
Since 5.0 we provide ability to customize socket-based connections in
HttpClient
viaConnectCallback
. The same functionality was asked for in #48617 for QUIC and HTTP/3. Due to differences between QUIC and sockets/Stream
we cannot reuse the existing callback. So we decided to add a new callback specifically for QUIC connections.ConnectCallback
served 2 different types of requirements:For 7.0 milestone, we decided to only allow the second requirement, customizing
QuicConnection
creation (see usages). For the transport replacement we would need to provide and commit toQuicConnection
/QuicStream
abstractions, which we don't want to do yet. But we do plan to design these classes with potential to become abstract in the future, so we're not closing the door on the transport replacement.Also for the callback to make sense we should expand
QuicClientConnectionOptions
with some useful settings (this will be part of separate API discussion), e.g.:TimeSpan KeepAliveInterval
: turns on and sends PING frames regularly to keep the connection open (Unable to enable TCP KeepAlive in System.Net.HttpClient #31267)IPEndPoint? LocalEndpoint
: to specify interface from which to make the connection (HttpClient specify interface to bind to / make requests from #23267)bool DatagramReceiveEnabled
: enables QUIC datagram which is necessary for WebTransport (QUIC Datagram API #53533)More details in my notes: https://gist.github.com/ManickaP/7a96748c6789f008e4e0597b9b883487
As a side note, related to this API is
PlaintextStreamFilter
callback which operates on streams. Once again, we would needQuicStream
abstraction or enhancement toStream
itself to make it work. So we decided to ignore this callback for now (as we've done so far) and revisit it in later releases.API Proposal
namespace System.Net.Http { public sealed class SocketsHttpHandler : HttpMessageHandler { public Func<SocketsHttpConnectionContext, CancellationToken, ValueTask<Stream>>? ConnectCallback { get; set; } + public Func<SocketsHttpConnectionContext, CancellationToken, ValueTask<QuicConnection>>? QuicConnectCallback { get; set; } } }
API Usage
Alternative Designs
Not doing anything at the moment.
Risks
Due to limited usages of HTTP/3 and QUIC, newness of these protocols in our stack, we don't have much feedback yet. The design is based on requirements for previous HTTP versions and sockets. As a result, the need for this callback might be non-existent and we're adding new API with no usefulness.
On the other hand, if we do nothing we might never get any feedback and/or adoption and thus will never know how to improve this. Moreover, the API surface is small and the design is conservative with future in mind.
Mitigation might be hiding the API behind
RequiresPreviewFeaturesAttribute
which would let us change the API shape in the next release.The text was updated successfully, but these errors were encountered: