@@ -56,9 +56,10 @@ public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient, b
5656 /// Optional. The delegating handlers to add to the http client pipeline.
5757 /// </param>
5858 public Kubernetes ( KubernetesClientConfiguration config , params DelegatingHandler [ ] handlers )
59- : this ( handlers )
6059 {
60+ Initialize ( ) ;
6161 ValidateConfig ( config ) ;
62+ CreateHttpClient ( handlers ) ;
6263 CaCerts = config . SslCaCerts ;
6364 SkipTlsVerify = config . SkipTlsVerify ;
6465 InitializeFromConfig ( config ) ;
@@ -161,10 +162,15 @@ partial void CustomInitialize()
161162#if NET452
162163 ServicePointManager . SecurityProtocol |= SecurityProtocolType . Tls12 ;
163164#endif
164- AppendDelegatingHandler < WatcherDelegatingHandler > ( ) ;
165165 DeserializationSettings . Converters . Add ( new V1Status . V1StatusObjectViewConverter ( ) ) ;
166166 }
167167
168+ /// <summary>A <see cref="DelegatingHandler"/> that simply forwards a request with no further processing.</summary>
169+ private sealed class ForwardingHandler : DelegatingHandler
170+ {
171+ public ForwardingHandler ( HttpMessageHandler handler ) : base ( handler ) { }
172+ }
173+
168174 private void AppendDelegatingHandler < T > ( ) where T : DelegatingHandler , new ( )
169175 {
170176 var cur = FirstMessageHandler as DelegatingHandler ;
@@ -188,6 +194,32 @@ partial void CustomInitialize()
188194 }
189195 }
190196
197+ // NOTE: this method replicates the logic that the base ServiceClient uses except that it doesn't insert the RetryDelegatingHandler
198+ // and it does insert the WatcherDelegatingHandler. we don't want the RetryDelegatingHandler because it has a very broad definition
199+ // of what requests have failed. it considers everything outside 2xx to be failed, including 1xx (e.g. 101 Switching Protocols) and
200+ // 3xx. in particular, this prevents upgraded connections and certain generic/custom requests from working.
201+ private void CreateHttpClient ( DelegatingHandler [ ] handlers )
202+ {
203+ FirstMessageHandler = HttpClientHandler = CreateRootHandler ( ) ;
204+ if ( handlers == null || handlers . Length == 0 )
205+ {
206+ // ensure we have at least one DelegatingHandler so AppendDelegatingHandler will work
207+ FirstMessageHandler = new ForwardingHandler ( HttpClientHandler ) ;
208+ }
209+ else
210+ {
211+ for ( int i = handlers . Length - 1 ; i >= 0 ; i -- )
212+ {
213+ DelegatingHandler handler = handlers [ i ] ;
214+ while ( handler . InnerHandler is DelegatingHandler d ) handler = d ;
215+ handler . InnerHandler = FirstMessageHandler ;
216+ FirstMessageHandler = handlers [ i ] ;
217+ }
218+ }
219+ AppendDelegatingHandler < WatcherDelegatingHandler > ( ) ;
220+ HttpClient = new HttpClient ( FirstMessageHandler , false ) ;
221+ }
222+
191223 /// <summary>
192224 /// Set credentials for the Client
193225 /// </summary>
0 commit comments