@ -9,7 +9,6 @@ using System.ComponentModel;
using System.Diagnostics ;
using System.IO.Compression ;
using System.Net.Http.Headers ;
using System.Net.Mail ;
using Microsoft.Extensions.Logging ;
using Microsoft.Extensions.Options ;
using Microsoft.Extensions.Primitives ;
@ -27,6 +26,47 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
. AddRange ( Exchange . DefaultHandlers )
. AddRange ( Userinfo . DefaultHandlers ) ;
/// <summary>
/// Contains the logic responsible for creating and attaching a <see cref="HttpClient"/>.
/// </summary>
public sealed class CreateHttpClient < TContext > : IOpenIddictClientHandler < TContext > where TContext : BaseExternalContext
{
private readonly IHttpClientFactory _f actory ;
public CreateHttpClient ( IHttpClientFactory factory )
= > _f actory = factory ? ? throw new ArgumentNullException ( nameof ( factory ) ) ;
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get ; }
= OpenIddictClientHandlerDescriptor . CreateBuilder < TContext > ( )
. AddFilter < RequireHttpMetadataUri > ( )
. UseSingletonHandler < CreateHttpClient < TContext > > ( )
. SetOrder ( int . MinValue + 1 0 0 _ 0 0 0 )
. SetType ( OpenIddictClientHandlerType . BuiltIn )
. Build ( ) ;
/// <inheritdoc/>
public ValueTask HandleAsync ( TContext context )
{
if ( context is null )
{
throw new ArgumentNullException ( nameof ( context ) ) ;
}
var assembly = typeof ( OpenIddictClientSystemNetHttpOptions ) . Assembly . GetName ( ) ;
var name = ! string . IsNullOrEmpty ( context . Registration . ProviderName ) ?
$"{assembly.Name}:{context.Registration.ProviderName}" : assembly . Name ! ;
// Create and store the HttpClient in the transaction properties.
context . Transaction . SetProperty ( typeof ( HttpClient ) . FullName ! , _f actory . CreateClient ( name ) ? ?
throw new InvalidOperationException ( SR . GetResourceString ( SR . ID0174 ) ) ) ;
return default ;
}
}
/// <summary>
/// Contains the logic responsible for preparing an HTTP GET request message.
/// </summary>
@ -39,7 +79,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
= OpenIddictClientHandlerDescriptor . CreateBuilder < TContext > ( )
. AddFilter < RequireHttpMetadataUri > ( )
. UseSingletonHandler < PrepareGetHttpRequest < TContext > > ( )
. SetOrder ( int . MinValue + 1 0 0 _ 0 0 0 )
. SetOrder ( CreateHttpClient < TContext > . Descriptor . Order + 1 _ 0 0 0 )
. SetType ( OpenIddictClientHandlerType . BuiltIn )
. Build ( ) ;
@ -91,6 +131,53 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
}
}
/// <summary>
/// Contains the logic responsible for attaching the HTTP version to the HTTP request message.
/// </summary>
public sealed class AttachHttpVersion < TContext > : IOpenIddictClientHandler < TContext > where TContext : BaseExternalContext
{
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get ; }
= OpenIddictClientHandlerDescriptor . CreateBuilder < TContext > ( )
. AddFilter < RequireHttpMetadataUri > ( )
. UseSingletonHandler < AttachHttpVersion < TContext > > ( )
. SetOrder ( PreparePostHttpRequest < TContext > . Descriptor . Order + 1 _ 0 0 0 )
. SetType ( OpenIddictClientHandlerType . BuiltIn )
. Build ( ) ;
/// <inheritdoc/>
public ValueTask HandleAsync ( TContext context )
{
if ( context is null )
{
throw new ArgumentNullException ( nameof ( context ) ) ;
}
#if SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION || SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION_POLICY
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context . Transaction . GetHttpRequestMessage ( ) ? ?
throw new InvalidOperationException ( SR . GetResourceString ( SR . ID0173 ) ) ;
var client = context . Transaction . GetHttpClient ( ) ? ?
throw new InvalidOperationException ( SR . GetResourceString ( SR . ID0372 ) ) ;
#if SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION
// If supported, import the HTTP version from the client instance.
request . Version = client . DefaultRequestVersion ;
#endif
#if SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION_POLICY
// If supported, import the HTTP version policy from the client instance.
request . VersionPolicy = client . DefaultVersionPolicy ;
#endif
#endif
return default ;
}
}
/// <summary>
/// Contains the logic responsible for attaching the appropriate HTTP
/// Accept-* headers to the HTTP request message to receive JSON responses.
@ -104,7 +191,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
= OpenIddictClientHandlerDescriptor . CreateBuilder < TContext > ( )
. AddFilter < RequireHttpMetadataUri > ( )
. UseSingletonHandler < AttachJsonAcceptHeaders < TContext > > ( )
. SetOrder ( PreparePostHttpRequest < TContext > . Descriptor . Order + 1 _ 0 0 0 )
. SetOrder ( AttachHttpVersion < TContext > . Descriptor . Order + 1 _ 0 0 0 )
. SetType ( OpenIddictClientHandlerType . BuiltIn )
. Build ( ) ;
@ -319,11 +406,6 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public sealed class SendHttpRequest < TContext > : IOpenIddictClientHandler < TContext > where TContext : BaseExternalContext
{
private readonly IHttpClientFactory _f actory ;
public SendHttpRequest ( IHttpClientFactory factory )
= > _f actory = factory ? ? throw new ArgumentNullException ( nameof ( factory ) ) ;
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
@ -348,19 +430,10 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
var request = context . Transaction . GetHttpRequestMessage ( ) ? ?
throw new InvalidOperationException ( SR . GetResourceString ( SR . ID0173 ) ) ;
var assembly = typeof ( OpenIddictClientSystemNetHttpOptions ) . Assembly . GetName ( ) ;
using var client = _f actory . CreateClient ( assembly . Name ! ) ? ?
throw new InvalidOperationException ( SR . GetResourceString ( SR . ID0174 ) ) ;
// Note: a "using" statement is deliberately used here to dispose of the client in this handler.
using var client = context . Transaction . GetHttpClient ( ) ? ?
throw new InvalidOperationException ( SR . GetResourceString ( SR . ID0372 ) ) ;
#if SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION
// If supported, import the HTTP version from the client instance.
request . Version = client . DefaultRequestVersion ;
#endif
#if SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION_POLICY
// If supported, import the HTTP version policy from the client instance.
request . VersionPolicy = client . DefaultVersionPolicy ;
#endif
HttpResponseMessage response ;
try