11using Polly ;
2- using Simple . HttpClientFactory . Polly ;
32using System ;
43using System . Collections . Generic ;
54using System . Linq ;
98using System . Net . Security ;
109#endif
1110using System . Security . Cryptography . X509Certificates ;
11+ using Simple . HttpClientFactory . MessageHandlers ;
1212
1313namespace Simple . HttpClientFactory
1414{
@@ -71,10 +71,13 @@ public IHttpClientBuilder WithTimeout(in TimeSpan timeout)
7171 public IHttpClientBuilder WithMessageExceptionHandler (
7272 Func < HttpRequestException , bool > exceptionHandlingPredicate ,
7373 Func < HttpRequestException , Exception > exceptionHandler ) =>
74- WithMessageHandler ( new MessageExceptionHandler ( exceptionHandlingPredicate , exceptionHandler , null ) ) ;
74+ WithMessageHandler ( new ExceptionTranslatorRequestMiddleware ( exceptionHandlingPredicate , exceptionHandler , null ) ) ;
7575
76+ /// <exception cref="T:System.ArgumentNullException"><paramref name="handler"/> is <see langword="null"/></exception>
7677 public IHttpClientBuilder WithMessageHandler ( DelegatingHandler handler )
7778 {
79+ if ( handler == null )
80+ throw new ArgumentNullException ( nameof ( handler ) ) ;
7881 if ( _middlewareHandlers . Count > 0 )
7982 _middlewareHandlers . Last ( ) . InnerHandler = handler ;
8083 _middlewareHandlers . Add ( handler ) ;
@@ -94,7 +97,7 @@ public IHttpClientBuilder WithMessageHandlers(IEnumerable<DelegatingHandler> han
9497 //see https://github.com/dotnet/extensions/issues/1345#issuecomment-607490721
9598 public HttpClient Build ( Action < SocketsHttpHandler > clientHandlerConfigurator = null )
9699 {
97- PolicyHttpMessageHandler policyHandler = null ;
100+ PollyMessageMiddleware rootPolicyHandler = null ;
98101
99102 var clientHandler = new SocketsHttpHandler
100103 {
@@ -119,16 +122,16 @@ public HttpClient Build(Action<SocketsHttpHandler> clientHandlerConfigurator = n
119122
120123 for ( int i = 0 ; i < _policies . Count ; i ++ )
121124 {
122- if ( policyHandler == null )
123- policyHandler = new PolicyHttpMessageHandler ( _policies [ i ] , clientHandler ) ;
125+ if ( rootPolicyHandler == null )
126+ rootPolicyHandler = new PollyMessageMiddleware ( _policies [ i ] , clientHandler ) ;
124127 else
125128 {
126- var @new = new PolicyHttpMessageHandler ( _policies [ i ] , policyHandler ) ;
127- policyHandler = @new ;
129+ var @new = new PollyMessageMiddleware ( _policies [ i ] , rootPolicyHandler ) ;
130+ rootPolicyHandler = @new ;
128131 }
129132 }
130133
131- var client = ConstructClientWithMiddleware ( clientHandler , policyHandler ) ;
134+ var client = ConstructClientWithMiddleware ( clientHandler , rootPolicyHandler ) ;
132135
133136 if ( _timeout . HasValue )
134137 client . Timeout = _timeout . Value ;
@@ -138,68 +141,100 @@ public HttpClient Build(Action<SocketsHttpHandler> clientHandlerConfigurator = n
138141
139142 #else
140143
144+ /// <exception cref="T:System.Exception">A <paramref name="clientHandlerConfigurator"/> throws an exception.</exception>
141145 public HttpClient Build ( Action < HttpClientHandler > clientHandlerConfigurator = null )
142146 {
143147
144148 var clientHandler = new HttpClientHandlerEx ( ) ;
145149
146150 if ( _certificates . Count > 0 )
147- clientHandler . ClientCertificates . AddRange ( _certificates . ToArray ( ) ) ;
151+ {
152+ for ( int i = 0 ; i < _certificates . Count ; i ++ )
153+ clientHandler . ClientCertificates . Add ( _certificates [ i ] ) ;
154+ }
148155
149156 clientHandlerConfigurator ? . Invoke ( clientHandler ) ;
150157
151- PolicyHttpMessageHandler policyHandler = null ;
158+ PollyMessageMiddleware rootPolicyHandler = null ;
152159 for ( int i = 0 ; i < _policies . Count ; i ++ )
153160 {
154- if ( policyHandler == null )
155- policyHandler = new PolicyHttpMessageHandler ( _policies [ i ] , clientHandler ) ;
161+ if ( rootPolicyHandler == null )
162+ rootPolicyHandler = new PollyMessageMiddleware ( _policies [ i ] , clientHandler ) ;
156163 else
157164 {
158- var @new = new PolicyHttpMessageHandler ( _policies [ i ] , policyHandler ) ;
159- policyHandler = @new ;
165+ var @new = new PollyMessageMiddleware ( _policies [ i ] , rootPolicyHandler ) ;
166+ rootPolicyHandler = @new ;
160167 }
161168 }
162169
163- var client = ConstructClientWithMiddleware ( clientHandler , policyHandler ) ;
170+ var client = ConstructClientWithMiddleware ( clientHandler , rootPolicyHandler ) ;
164171
165172 if ( _timeout . HasValue )
166173 client . Timeout = _timeout . Value ;
167174
168175 return client ;
169176 }
170177#endif
171- private HttpClient ConstructClientWithMiddleware < TClientHandler > ( TClientHandler clientHandler , PolicyHttpMessageHandler policyHandler )
178+ private HttpClient ConstructClientWithMiddleware < TClientHandler > ( TClientHandler clientHandler , PollyMessageMiddleware rootPolicyHandler )
172179 where TClientHandler : HttpMessageHandler
173180 {
174181 HttpClient client ;
175- if ( policyHandler != null )
182+ client = CreateClientInternal ( clientHandler , rootPolicyHandler , _middlewareHandlers . LastOrDefault ( ) ) ;
183+
184+ InitializeDefaultHeadersIfNeeded ( ) ;
185+
186+ return client ;
187+
188+
189+ void InitializeDefaultHeadersIfNeeded ( )
190+ {
191+ if ( _defaultHeaders . Count > 0 )
192+ {
193+ foreach ( var header in _defaultHeaders )
194+ {
195+ if ( ! client . DefaultRequestHeaders . Contains ( header . Key ) )
196+ client . DefaultRequestHeaders . Add ( header . Key , header . Value ) ;
197+ }
198+ }
199+ }
200+ }
201+
202+ private HttpClient CreateClientInternal < TClientHandler > ( TClientHandler clientHandler ,
203+ PollyMessageMiddleware rootPolicyHandler , DelegatingHandler lastMiddleware ) where TClientHandler : HttpMessageHandler
204+ {
205+ HttpClient InitializeClientWithPoliciesAndMiddleware ( )
176206 {
207+ HttpClient client ;
177208 if ( _middlewareHandlers . Count > 0 )
178209 {
179- _middlewareHandlers . LastOrDefault ( ) . InnerHandler = policyHandler ;
210+ if ( lastMiddleware == null )
211+ throw new InvalidOperationException ( "One or more middleware handlers is null. This is not supposed to happen!" ) ;
212+
213+ lastMiddleware . InnerHandler = rootPolicyHandler ;
180214 client = new HttpClient ( _middlewareHandlers . FirstOrDefault ( ) , true ) ;
181215 }
182216 else
183- client = new HttpClient ( policyHandler , true ) ;
184- }
185- else if ( _middlewareHandlers . Count > 0 )
186- {
187- _middlewareHandlers . LastOrDefault ( ) . InnerHandler = clientHandler ;
188- client = new HttpClient ( _middlewareHandlers . FirstOrDefault ( ) , true ) ;
217+ client = new HttpClient ( rootPolicyHandler , true ) ;
218+
219+ return client ;
189220 }
190- else
191- client = new HttpClient ( clientHandler , true ) ;
192221
193- if ( _defaultHeaders . Count > 0 )
222+ HttpClient InitializeClientOnlyWithMiddleware ( )
194223 {
195- foreach ( var header in _defaultHeaders )
196- {
197- if ( ! client . DefaultRequestHeaders . Contains ( header . Key ) )
198- client . DefaultRequestHeaders . Add ( header . Key , header . Value ) ;
199- }
224+ lastMiddleware . InnerHandler = clientHandler ;
225+ var client = new HttpClient ( _middlewareHandlers . FirstOrDefault ( ) , true ) ;
226+ return client ;
200227 }
201228
202- return client ;
229+ HttpClient createdClient ;
230+ if ( rootPolicyHandler != null )
231+ createdClient = InitializeClientWithPoliciesAndMiddleware ( ) ;
232+ else if ( _middlewareHandlers . Count > 0 )
233+ createdClient = InitializeClientOnlyWithMiddleware ( ) ;
234+ else
235+ createdClient = new HttpClient ( clientHandler , true ) ;
236+
237+ return createdClient ;
203238 }
204239 }
205240}
0 commit comments