|
| 1 | +using k8s.Models; |
1 | 2 | using Microsoft.AspNetCore.WebUtilities;
|
2 | 3 | using Microsoft.Rest;
|
| 4 | +using Microsoft.Rest.Serialization; |
3 | 5 | using System;
|
4 | 6 | using System.Collections.Generic;
|
5 | 7 | using System.Linq;
|
| 8 | +using System.Net; |
6 | 9 | using System.Net.Http;
|
7 | 10 | using System.Net.WebSockets;
|
8 | 11 | using System.Security.Cryptography.X509Certificates;
|
@@ -270,6 +273,46 @@ public partial class Kubernetes
|
270 | 273 | {
|
271 | 274 | webSocket = await webSocketBuilder.BuildAndConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
|
272 | 275 | }
|
| 276 | + catch (WebSocketException wse) when (wse.WebSocketErrorCode == WebSocketError.HeaderError || (wse.InnerException is WebSocketException && ((WebSocketException)wse.InnerException).WebSocketErrorCode == WebSocketError.HeaderError)) |
| 277 | + { |
| 278 | + // This usually indicates the server sent an error message, like 400 Bad Request. Unfortunately, the WebSocket client |
| 279 | + // class doesn't give us a lot of information about what went wrong. So, retry the connection. |
| 280 | + var uriBuilder = new UriBuilder(uri); |
| 281 | + uriBuilder.Scheme = uri.Scheme == "wss" ? "https" : "http"; |
| 282 | + |
| 283 | + var response = await this.HttpClient.GetAsync(uriBuilder.Uri, cancellationToken).ConfigureAwait(false); |
| 284 | + |
| 285 | + if (response.StatusCode == HttpStatusCode.SwitchingProtocols) |
| 286 | + { |
| 287 | + // This should never happen - the server just allowed us to switch to WebSockets but the previous call didn't work. |
| 288 | + // Rethrow the original exception |
| 289 | + response.Dispose(); |
| 290 | + throw; |
| 291 | + } |
| 292 | + else |
| 293 | + { |
| 294 | + var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); |
| 295 | + |
| 296 | + // Try to parse the content as a V1Status object |
| 297 | + var genericObject = SafeJsonConvert.DeserializeObject<KubernetesObject>(content); |
| 298 | + V1Status status = null; |
| 299 | + |
| 300 | + if (genericObject.ApiVersion == "v1" && genericObject.Kind == "Status") |
| 301 | + { |
| 302 | + status = SafeJsonConvert.DeserializeObject<V1Status>(content); |
| 303 | + } |
| 304 | + |
| 305 | + var ex = new HttpOperationException($"The operation returned an invalid status code: {response.StatusCode}", wse) |
| 306 | + { |
| 307 | + Response = new HttpResponseMessageWrapper(response, content), |
| 308 | + Body = status != null ? (object)status : content, |
| 309 | + }; |
| 310 | + |
| 311 | + response.Dispose(); |
| 312 | + |
| 313 | + throw ex; |
| 314 | + } |
| 315 | + } |
273 | 316 | catch (Exception ex)
|
274 | 317 | {
|
275 | 318 | if (_shouldTrace)
|
|
0 commit comments