@@ -40,9 +40,9 @@ public class HttpCallExecutor(IServiceProvider serviceProvider, ILogger<HttpCall
4040 protected ISerializerProvider SerializerProvider { get ; } = serializerProvider ;
4141
4242 /// <summary>
43- /// Gets the service used to perform HTTP requests
43+ /// Gets the service used to create <see cref="HttpClient"/>s
4444 /// </summary>
45- protected HttpClient HttpClient { get ; } = httpClientFactory . CreateClient ( ) ;
45+ protected IHttpClientFactory HttpClientFactory { get ; } = httpClientFactory ;
4646
4747 /// <summary>
4848 /// Gets the definition of the http call to perform
@@ -56,7 +56,8 @@ protected override async Task DoInitializeAsync(CancellationToken cancellationTo
5656 {
5757 this . Http = ( HttpCallDefinition ) this . JsonSerializer . Convert ( this . Task . Definition . With , typeof ( HttpCallDefinition ) ) ! ;
5858 var authentication = this . Http . Endpoint . Authentication == null ? null : await this . Task . Workflow . Expressions . EvaluateAsync < AuthenticationPolicyDefinition > ( this . Http . Endpoint . Authentication , this . Task . Input , this . Task . Arguments , cancellationToken ) . ConfigureAwait ( false ) ;
59- await this . HttpClient . ConfigureAuthenticationAsync ( authentication , this . ServiceProvider , this . Task . Workflow . Definition , cancellationToken ) . ConfigureAwait ( false ) ;
59+ using var httpClient = this . HttpClientFactory . CreateClient ( ) ;
60+ await httpClient . ConfigureAuthenticationAsync ( authentication , this . ServiceProvider , this . Task . Workflow . Definition , cancellationToken ) . ConfigureAwait ( false ) ;
6061 }
6162 catch ( Exception ex )
6263 {
@@ -76,9 +77,7 @@ protected override async Task DoExecuteAsync(CancellationToken cancellationToken
7677 {
7778 if ( this . Http == null ) throw new InvalidOperationException ( "The executor must be initialized before execution" ) ;
7879 ISerializer ? serializer ;
79- var defaultMediaType = this . Http . Body is string
80- ? MediaTypeNames . Text . Plain
81- : MediaTypeNames . Application . Json ;
80+ var defaultMediaType = this . Http . Body is string ? MediaTypeNames . Text . Plain : MediaTypeNames . Application . Json ;
8281 if ( ( this . Http . Headers ? . TryGetValue ( "Content-Type" , out var mediaType ) != true && this . Http . Headers ? . TryGetValue ( "Content-Type" , out mediaType ) != true ) || string . IsNullOrWhiteSpace ( mediaType ) ) mediaType = defaultMediaType ;
8382 else mediaType = mediaType . Split ( ';' , StringSplitOptions . RemoveEmptyEntries ) [ 0 ] . Trim ( ) ;
8483 var requestContent = ( HttpContent ? ) null ;
@@ -133,9 +132,19 @@ protected override async Task DoExecuteAsync(CancellationToken cancellationToken
133132 }
134133 var uri = StringFormatter . NamedFormat ( this . Http . EndpointUri . OriginalString , this . Task . Input . ToDictionary ( ) ) ;
135134 if ( uri . IsRuntimeExpression ( ) ) uri = await this . Task . Workflow . Expressions . EvaluateAsync < string > ( uri , this . Task . Input , this . GetExpressionEvaluationArguments ( ) , cancellationToken ) . ConfigureAwait ( false ) ;
135+ using var httpClient = this . Http . Redirect ? this . HttpClientFactory . CreateClient ( ) : this . HttpClientFactory . CreateClient ( RunnerDefaults . HttpClients . NoRedirect ) ; ;
136136 using var request = new HttpRequestMessage ( new HttpMethod ( this . Http . Method ) , uri ) { Content = requestContent } ;
137- using var response = await this . HttpClient . SendAsync ( request , cancellationToken ) . ConfigureAwait ( false ) ;
138- if ( ! response . IsSuccessStatusCode ) //todo: could be configurable on HTTP call?
137+ if ( this . Http . Headers != null )
138+ {
139+ foreach ( var header in this . Http . Headers )
140+ {
141+ var headerValue = header . Value ;
142+ if ( headerValue . IsRuntimeExpression ( ) ) headerValue = await this . Task . Workflow . Expressions . EvaluateAsync < string > ( headerValue , this . Task . Input , this . GetExpressionEvaluationArguments ( ) , cancellationToken ) . ConfigureAwait ( false ) ;
143+ request . Headers . TryAddWithoutValidation ( header . Key , headerValue ) ;
144+ }
145+ }
146+ using var response = await httpClient . SendAsync ( request , cancellationToken ) . ConfigureAwait ( false ) ;
147+ if ( ! response . IsSuccessStatusCode )
139148 {
140149 var detail = await response . Content . ReadAsStringAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
141150 this . Logger . LogError ( "Failed to request '{method} {uri}'. The remote server responded with a non-success status code '{statusCode}'." , this . Http . Method , uri , response . StatusCode ) ;
@@ -185,18 +194,4 @@ protected override async Task DoExecuteAsync(CancellationToken cancellationToken
185194 await this . SetResultAsync ( result , this . Task . Definition . Then , cancellationToken ) . ConfigureAwait ( false ) ;
186195 }
187196
188- /// <inheritdoc/>
189- protected override async ValueTask DisposeAsync ( bool disposing )
190- {
191- await base . DisposeAsync ( disposing ) . ConfigureAwait ( false ) ;
192- this . HttpClient . Dispose ( ) ;
193- }
194-
195- /// <inheritdoc/>
196- protected override void Dispose ( bool disposing )
197- {
198- base . Dispose ( disposing ) ;
199- this . HttpClient . Dispose ( ) ;
200- }
201-
202197}
0 commit comments