2626using System . Net ;
2727using System . Net . Http ;
2828using System . Net . Http . Headers ;
29+ using System . Runtime . CompilerServices ;
2930using System . Text ;
3031using System . Threading ;
3132using System . Threading . Tasks ;
@@ -49,8 +50,7 @@ public class HttpCommandExecutor : ICommandExecutor
4950 private readonly TimeSpan serverResponseTimeout ;
5051 private bool isDisposed ;
5152 private CommandInfoRepository commandInfoRepository = new W3CWireProtocolCommandInfoRepository ( ) ;
52- private HttpClient ? client ;
53- private readonly object _createClientLock = new ( ) ;
53+ private readonly Lazy < HttpClient > client ;
5454
5555 private static readonly ILogger _logger = Log . GetLogger < HttpCommandExecutor > ( ) ;
5656
@@ -89,6 +89,7 @@ public HttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, bool ena
8989 this . remoteServerUri = addressOfRemoteServer ;
9090 this . serverResponseTimeout = timeout ;
9191 this . IsKeepAliveEnabled = enableKeepAlive ;
92+ this . client = new Lazy < HttpClient > ( CreateHttpClient ) ;
9293 }
9394
9495 /// <summary>
@@ -218,54 +219,37 @@ protected virtual void OnSendingRemoteHttpRequest(SendingRemoteHttpRequestEventA
218219 this . SendingRemoteHttpRequest ? . Invoke ( this , eventArgs ) ;
219220 }
220221
221- private HttpClient Client
222+ private HttpClient CreateHttpClient ( )
222223 {
223- get
224+ HttpClientHandler httpClientHandler = new HttpClientHandler ( ) ;
225+ string userInfo = this . remoteServerUri . UserInfo ;
226+ if ( ! string . IsNullOrEmpty ( userInfo ) && userInfo . Contains ( ":" ) )
224227 {
225- if ( this . client is null )
226- {
227- lock ( _createClientLock )
228- {
229- if ( this . client is null )
230- {
231- HttpClientHandler httpClientHandler = new HttpClientHandler ( ) ;
232- string userInfo = this . remoteServerUri . UserInfo ;
233- if ( ! string . IsNullOrEmpty ( userInfo ) && userInfo . Contains ( ":" ) )
234- {
235- string [ ] userInfoComponents = this . remoteServerUri . UserInfo . Split ( new char [ ] { ':' } , 2 ) ;
236- httpClientHandler . Credentials = new NetworkCredential ( userInfoComponents [ 0 ] , userInfoComponents [ 1 ] ) ;
237- httpClientHandler . PreAuthenticate = true ;
238- }
239-
240- httpClientHandler . Proxy = this . Proxy ;
241-
242- HttpMessageHandler handler = httpClientHandler ;
243-
244- if ( _logger . IsEnabled ( LogEventLevel . Trace ) )
245- {
246- handler = new DiagnosticsHttpHandler ( httpClientHandler , _logger ) ;
247- }
248-
249- var client = new HttpClient ( handler ) ;
250- client . DefaultRequestHeaders . UserAgent . ParseAdd ( this . UserAgent ) ;
251- client . DefaultRequestHeaders . Accept . ParseAdd ( RequestAcceptHeader ) ;
252- client . DefaultRequestHeaders . ExpectContinue = false ;
253- if ( ! this . IsKeepAliveEnabled )
254- {
255- client . DefaultRequestHeaders . Connection . ParseAdd ( "close" ) ;
256- }
257-
258- client . Timeout = this . serverResponseTimeout ;
259-
260- this . client = client ;
261- }
262- }
263- }
228+ string [ ] userInfoComponents = this . remoteServerUri . UserInfo . Split ( new char [ ] { ':' } , 2 ) ;
229+ httpClientHandler . Credentials = new NetworkCredential ( userInfoComponents [ 0 ] , userInfoComponents [ 1 ] ) ;
230+ httpClientHandler . PreAuthenticate = true ;
231+ }
232+
233+ httpClientHandler . Proxy = this . Proxy ;
264234
265- return this . client ;
235+ HttpMessageHandler handler = httpClientHandler ;
236+
237+ if ( _logger . IsEnabled ( LogEventLevel . Trace ) )
238+ {
239+ handler = new DiagnosticsHttpHandler ( httpClientHandler , _logger ) ;
266240 }
267- }
268241
242+ var client = new HttpClient ( handler ) ;
243+ client . DefaultRequestHeaders . UserAgent . ParseAdd ( this . UserAgent ) ;
244+ client . DefaultRequestHeaders . Accept . ParseAdd ( RequestAcceptHeader ) ;
245+ client . DefaultRequestHeaders . ExpectContinue = false ;
246+ if ( ! this . IsKeepAliveEnabled )
247+ {
248+ client . DefaultRequestHeaders . Connection . ParseAdd ( "close" ) ;
249+ }
250+ return client ;
251+
252+ }
269253 private async Task < HttpResponseInfo > MakeHttpRequest ( HttpRequestInfo requestInfo )
270254 {
271255 SendingRemoteHttpRequestEventArgs eventArgs = new SendingRemoteHttpRequestEventArgs ( requestInfo . HttpMethod , requestInfo . FullUri . ToString ( ) , requestInfo . RequestBody ) ;
@@ -300,7 +284,7 @@ private async Task<HttpResponseInfo> MakeHttpRequest(HttpRequestInfo requestInfo
300284 requestMessage . Content . Headers . ContentType = contentTypeHeader ;
301285 }
302286
303- using ( HttpResponseMessage responseMessage = await this . Client . SendAsync ( requestMessage ) . ConfigureAwait ( false ) )
287+ using ( HttpResponseMessage responseMessage = await this . client . Value . SendAsync ( requestMessage ) . ConfigureAwait ( false ) )
304288 {
305289 var responseBody = await responseMessage . Content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ;
306290 var responseContentType = responseMessage . Content . Headers . ContentType ? . ToString ( ) ;
@@ -362,7 +346,10 @@ protected virtual void Dispose(bool disposing)
362346 {
363347 if ( ! this . isDisposed )
364348 {
365- this . client ? . Dispose ( ) ;
349+ if ( this . client . IsValueCreated )
350+ {
351+ this . client . Value . Dispose ( ) ;
352+ }
366353
367354 this . isDisposed = true ;
368355 }
0 commit comments