Esempio n. 1
0
        protected async Task <WebSocket> StreamConnectAsync(Uri uri, string invocationId = null, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            bool _shouldTrace = ServiceClientTracing.IsEnabled;

            // Create WebSocket transport objects
            WebSocketBuilder webSocketBuilder = this.CreateWebSocketBuilder();

            // Set Headers
            if (customHeaders != null)
            {
                foreach (var _header in customHeaders)
                {
                    webSocketBuilder.SetRequestHeader(_header.Key, string.Join(" ", _header.Value));
                }
            }

            // Set Credentials
            foreach (var cert in this.HttpClientHandler.ClientCertificates)
            {
                webSocketBuilder.AddClientCertificate(cert);
            }

            HttpRequestMessage message = new HttpRequestMessage();

            await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken);

            foreach (var _header in message.Headers)
            {
                webSocketBuilder.SetRequestHeader(_header.Key, string.Join(" ", _header.Value));
            }

            // Send Request
            cancellationToken.ThrowIfCancellationRequested();

            WebSocket webSocket = null;

            try
            {
                webSocket = await webSocketBuilder.BuildAndConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                if (_shouldTrace)
                {
                    ServiceClientTracing.Error(invocationId, ex);
                }

                throw;
            }
            finally
            {
                if (_shouldTrace)
                {
                    ServiceClientTracing.Exit(invocationId, null);
                }
            }

            return(webSocket);
        }
Esempio n. 2
0
        protected async Task <WebSocket> StreamConnectAsync(Uri uri, string invocationId = null, string webSocketSubProtocol = null, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            bool _shouldTrace = ServiceClientTracing.IsEnabled;

            // Create WebSocket transport objects
            WebSocketBuilder webSocketBuilder = this.CreateWebSocketBuilder();

            // Set Headers
            if (customHeaders != null)
            {
                foreach (var _header in customHeaders)
                {
                    webSocketBuilder.SetRequestHeader(_header.Key, string.Join(" ", _header.Value));
                }
            }

            // Set Credentials
#if NET452
            foreach (var cert in ((WebRequestHandler)this.HttpClientHandler).ClientCertificates.OfType <X509Certificate2>())
#else
            foreach (var cert in this.HttpClientHandler.ClientCertificates.OfType <X509Certificate2>())
#endif
            {
                webSocketBuilder.AddClientCertificate(cert);
            }

            if (this.Credentials != null)
            {
                // Copy the default (credential-related) request headers from the HttpClient to the WebSocket
                HttpRequestMessage message = new HttpRequestMessage();
                await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken).ConfigureAwait(false);

                foreach (var _header in message.Headers)
                {
                    webSocketBuilder.SetRequestHeader(_header.Key, string.Join(" ", _header.Value));
                }
            }

#if (NET452 || NETSTANDARD2_0)
            if (this.CaCerts != null)
            {
                webSocketBuilder.SetServerCertificateValidationCallback(this.ServerCertificateValidationCallback);
            }
#endif

#if NETCOREAPP2_1
            if (this.CaCerts != null)
            {
                webSocketBuilder.ExpectServerCertificate(this.CaCerts);
            }

            if (this.SkipTlsVerify)
            {
                webSocketBuilder.SkipServerCertificateValidation();
            }

            if (webSocketSubProtocol != null)
            {
                webSocketBuilder.Options.AddSubProtocol(webSocketSubProtocol);
            }
#endif // NETCOREAPP2_1

            // Send Request
            cancellationToken.ThrowIfCancellationRequested();

            WebSocket webSocket = null;
            try
            {
                webSocket = await webSocketBuilder.BuildAndConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
            }
            catch (WebSocketException wse) when(wse.WebSocketErrorCode == WebSocketError.HeaderError || (wse.InnerException is WebSocketException && ((WebSocketException)wse.InnerException).WebSocketErrorCode == WebSocketError.HeaderError))
            {
                // This usually indicates the server sent an error message, like 400 Bad Request. Unfortunately, the WebSocket client
                // class doesn't give us a lot of information about what went wrong. So, retry the connection.
                var uriBuilder = new UriBuilder(uri);

                uriBuilder.Scheme = uri.Scheme == "wss" ? "https" : "http";

                var response = await this.HttpClient.GetAsync(uriBuilder.Uri, cancellationToken).ConfigureAwait(false);

                if (response.StatusCode == HttpStatusCode.SwitchingProtocols)
                {
                    // This should never happen - the server just allowed us to switch to WebSockets but the previous call didn't work.
                    // Rethrow the original exception
                    response.Dispose();
                    throw;
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // Try to parse the content as a V1Status object
                    var      genericObject = SafeJsonConvert.DeserializeObject <KubernetesObject>(content);
                    V1Status status        = null;

                    if (genericObject.ApiVersion == "v1" && genericObject.Kind == "Status")
                    {
                        status = SafeJsonConvert.DeserializeObject <V1Status>(content);
                    }

                    var ex = new HttpOperationException($"The operation returned an invalid status code: {response.StatusCode}", wse)
                    {
                        Response = new HttpResponseMessageWrapper(response, content),
                        Body     = status != null ? (object)status : content,
                    };

                    response.Dispose();

                    throw ex;
                }
            }
            catch (Exception ex)
            {
                if (_shouldTrace)
                {
                    ServiceClientTracing.Error(invocationId, ex);
                }

                throw;
            }
            finally
            {
                if (_shouldTrace)
                {
                    ServiceClientTracing.Exit(invocationId, null);
                }

#if (NET452 || NETSTANDARD2_0)
                if (this.CaCerts != null)
                {
                    webSocketBuilder.CleanupServerCertificateValidationCallback(this.ServerCertificateValidationCallback);
                }
#endif
            }
            return(webSocket);
        }