public bool Connect(Uri connectUri) { _path = connectUri.PathAndQuery; _version = Protocols.Http2; _scheme = connectUri.Scheme; _host = connectUri.Host; _port = connectUri.Port; ServerUri = connectUri.Authority; if (_sessionAdapter != null) { return false; } try { int port = connectUri.Port; int securePort; if (!int.TryParse(ConfigurationManager.AppSettings["securePort"], out securePort)) { Http2Logger.LogError("Incorrect port in the config file!"); return false; } //Connect alpn extension, set known protocols var extensions = new[] {ExtensionType.Renegotiation, ExtensionType.ALPN}; Options = port == securePort ? new SecurityOptions(SecureProtocol.Tls1, extensions, new[] { Protocols.Http1, Protocols.Http2 }, ConnectionEnd.Client) : new SecurityOptions(SecureProtocol.None, extensions, new[] { Protocols.Http1, Protocols.Http2 }, ConnectionEnd.Client); Options.VerificationType = CredentialVerification.None; Options.Certificate = Org.Mentalis.Security.Certificates.Certificate.CreateFromCerFile(CertificatePath); Options.Flags = SecurityFlags.Default; Options.AllowedAlgorithms = SslAlgorithms.RSA_AES_256_SHA | SslAlgorithms.NULL_COMPRESSION; var socket = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, Options); using (var monitor = new ALPNExtensionMonitor()) { monitor.OnProtocolSelected += (o, args) => { _selectedProtocol = args.SelectedProtocol; }; socket.Connect(new DnsEndPoint(connectUri.Host, connectUri.Port), monitor); _clientStream = new DuplexStream(socket, true); if (_useHandshake) { MakeHandshakeEnvironment(); //Handshake manager determines what handshake must be used: upgrade or secure if (socket.SecureProtocol != SecureProtocol.None) { socket.MakeSecureHandshake(Options); _selectedProtocol = socket.SelectedProtocol; } if (socket.SecureProtocol == SecureProtocol.None || _selectedProtocol == Protocols.Http1) { try { var handshakeResult = new UpgradeHandshaker(_environment).Handshake(); _environment.Add(HandshakeKeys.Result, handshakeResult); _useHttp20 = handshakeResult[HandshakeKeys.Successful] as string == HandshakeKeys.True; if (!_useHttp20) { Dispose(false); return true; } } catch (Http2HandshakeFailed ex) { if (ex.Reason == HandshakeFailureReason.InternalError) { _useHttp20 = false; } else { Http2Logger.LogError("Specified server did not respond"); Dispose(true); return false; } } } } } Http2Logger.LogDebug("Handshake finished"); if (_useHttp20) { //TODO provide transport info _sessionAdapter = new Http2ClientMessageHandler(_clientStream, ConnectionEnd.Client, default(TransportInformation), CancellationToken.None); } } catch (SocketException) { Http2Logger.LogError("Check if any server listens port " + connectUri.Port); Dispose(true); return false; } catch (Exception ex) { Http2Logger.LogError("Unknown connection exception was caught: " + ex.Message); Dispose(true); return false; } return true; }
public bool Connect(Uri connectUri) { _path = connectUri.PathAndQuery; _version = Protocols.Http2; _scheme = connectUri.Scheme; _host = connectUri.Host; _port = connectUri.Port; ServerUri = connectUri.Authority; if (_sessionAdapter != null) { return false; } try { int port = connectUri.Port; int securePort; if (!int.TryParse(ConfigurationManager.AppSettings["securePort"], out securePort)) { Http2Logger.LogError("Incorrect port in the config file!"); return false; } _isSecure = port == securePort; var tcpClnt = new TcpClient(connectUri.Host, port); _clientStream = tcpClnt.GetStream(); if (_useHandshake) { if (_isSecure) { _clientStream = new SslStream(_clientStream, false); _certificate = LoadPKCS12Certificate(AssemblyName + CertificatePath, String.Empty); _chain = new X509Chain {_certificate}; var certList = new X509List { _certificate }; (_clientStream as SslStream).AuthenticateAsClient(connectUri.AbsoluteUri, certList, _chain, SslProtocols.Tls, SslStrength.All, false); _selectedProtocol = (_clientStream as SslStream).AlpnSelectedProtocol; } if (!_isSecure || _selectedProtocol == Protocols.Http1) { MakeHandshakeEnvironment(); try { var handshakeResult = new UpgradeHandshaker(_environment).Handshake(); _environment.Add(HandshakeKeys.Result, handshakeResult); _useHttp20 = handshakeResult[HandshakeKeys.Successful] as string == HandshakeKeys.True; if (!_useHttp20) { Dispose(false); return true; } } catch (Http2HandshakeFailed ex) { if (ex.Reason == HandshakeFailureReason.InternalError) { _useHttp20 = false; } else { Http2Logger.LogError("Specified server did not respond"); Dispose(true); return false; } } } } Http2Logger.LogDebug("Handshake finished"); Protocol = _isSecure ? SslProtocols.Tls : SslProtocols.None; if (_useHttp20) { _sessionAdapter = new Http2ClientMessageHandler(_clientStream, ConnectionEnd.Client, _isSecure, CancellationToken.None); } } catch (SocketException) { Http2Logger.LogError("Check if any server listens port " + connectUri.Port); Dispose(true); return false; } catch (Exception ex) { Http2Logger.LogError("Unknown connection exception was caught: " + ex.Message); Dispose(true); return false; } return true; }