Skip to content

HttpClient.SendAsync Throws Two Exceptions When QUIC Is Not Supported #49918

@brianrob

Description

@brianrob

On first use of HttpClient, there is a check to see if QUIC is supported. On any machine where QUIC hasn't been setup, this code throws two exceptions - a DLLNotFoundException, which is caught, and translated into a NotSupportedException. The NotSupportedException is also caught and translated into IsSupported = true. This is the stack where this happens:

module coreclr   <<coreclr!ProcessCLRException>>
module ntdll   <<ntdll!RtlRaiseException>>
module   kernelbase <<kernelbase!RaiseException>>
module coreclr <<coreclr!IL_Throw>>
system.net.quic!System.Net.Quic.Implementations.MsQuic.Internal.MsQuicApi..ctor()
module coreclr <<coreclr!ProcessCLRException>>
module ntdll <<ntdll!RtlUnwind>>
module coreclr <<coreclr!ProcessCLRException>>
module ntdll <<ntdll!RtlRaiseException>>
module kernelbase <<kernelbase!RaiseException>>
module coreclr <<coreclr!ThePreStub>>
system.net.quic!System.Net.Quic.Implementations.MsQuic.Internal.MsQuicApi..ctor()
system.net.quic!System.Net.Quic.Implementations.MsQuic.Internal.MsQuicApi..cctor()
module coreclr <<coreclr!DelayLoad_Helper>>
system.net.quic!MsQuicImplementationProvider.get_IsSupported
system.net.http!System.Net.Http.HttpConnectionPool..ctor(System.Net.Http.HttpConnectionPoolManager,   System.Net.Http.HttpConnectionKind, System.String, Int32, System.String,   System.Uri, Int32)
system.net.http!HttpConnectionPoolManager.SendAsyncCore
system.net.http!HttpConnectionPoolManager.SendAsync
system.net.http!HttpConnectionHandler.SendAsync
system.net.http!System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
module System.Private.CoreLib.il   <<System.Private.CoreLib.il!System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1[System.__Canon].Start(!!0&)>>
system.net.http!RedirectHandler.SendAsync
system.net.http!HttpMessageHandlerStage.SendAsync
system.net.http!SocketsHttpHandler.SendAsync
system.net.http!DelegatingHandler.SendAsync
system.net.http!System.Net.Http.DiagnosticsHandler+<SendAsyncCore>d__5.MoveNext()
module System.Private.CoreLib.il   <<System.Private.CoreLib.il!System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1[System.__Canon].Start(!!0&)>>
system.net.http!DiagnosticsHandler.SendAsyncCore
system.net.http!DiagnosticsHandler.SendAsync
system.net.http!HttpClientHandler.SendAsync
system.net.http!HttpMessageInvoker.SendAsync
system.net.http!System.Net.Http.HttpClient+<<SendAsync>g__Core\|83_0>d.MoveNext()
module System.Private.CoreLib.il <<System.Private.CoreLib.il!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon].Start(!!0&)>>
system.net.http!System.Net.Http.HttpClient.<SendAsync>g__Core\|83_0(System.Net.Http.HttpRequestMessage,   System.Net.Http.HttpCompletionOption,   System.Threading.CancellationTokenSource, Boolean,   System.Threading.CancellationTokenSource, System.Threading.CancellationToken)
system.net.http!HttpClient.SendAsync

Given that this is a light-up scenario, and in most cases, QUIC won't be supported, we should change this behavior to not throw, but instead, to detect the existence of the native component (e.g. msquic.dll) before attempting to load it.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions