/// <summary> /// Accepts client and deals handshake with it. /// </summary> internal void Accept() { SecureSocket incomingClient; using (var monitor = new ALPNExtensionMonitor()) { incomingClient = _server.AcceptSocket(monitor); } Http2Logger.LogDebug("New connection accepted"); Task.Run(() => HandleAcceptedClient(incomingClient)); }
protected static SecureSocket GetHandshakedSocket(Uri uri) { string selectedProtocol = null; var extensions = new[] { ExtensionType.Renegotiation, ExtensionType.ALPN }; var options = _useSecurePort ? new SecurityOptions(SecureProtocol.Tls1, extensions, new[] { Protocols.Http2, Protocols.Http1 }, ConnectionEnd.Client) : new SecurityOptions(SecureProtocol.None, extensions, new[] { Protocols.Http2, Protocols.Http1 }, ConnectionEnd.Client); options.VerificationType = CredentialVerification.None; options.Certificate = Org.Mentalis.Security.Certificates.Certificate.CreateFromCerFile(@"certificate.pfx"); options.Flags = SecurityFlags.Default; options.AllowedAlgorithms = SslAlgorithms.RSA_AES_256_SHA | SslAlgorithms.NULL_COMPRESSION; var sessionSocket = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, options); using (var monitor = new ALPNExtensionMonitor()) { monitor.OnProtocolSelected += (sender, args) => { selectedProtocol = args.SelectedProtocol; }; sessionSocket.Connect(new DnsEndPoint(uri.Host, uri.Port), monitor); if (_useHandshake) { var handshakeEnv = new Dictionary <string, object> { { ":method", "get" }, { ":version", Protocols.Http1 }, { ":path", uri.PathAndQuery }, { ":scheme", uri.Scheme }, { ":host", uri.Host }, { "securityOptions", options }, { "secureSocket", sessionSocket }, { "end", ConnectionEnd.Client } }; _handshakeResult = HandshakeManager.GetHandshakeAction(handshakeEnv).Invoke(); } } SendSessionHeader(sessionSocket); return(sessionSocket); }
public void AlpnSelectionHttp2Successful() { const string requestStr = @"https://*****:*****@"certificate.pfx"), Flags = SecurityFlags.Default, AllowedAlgorithms = SslAlgorithms.RSA_AES_256_SHA | SslAlgorithms.NULL_COMPRESSION }; var sessionSocket = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, options); using (var monitor = new ALPNExtensionMonitor()) { monitor.OnProtocolSelected += (sender, args) => { selectedProtocol = args.SelectedProtocol; }; sessionSocket.Connect(new DnsEndPoint(uri.Host, uri.Port), monitor); var handshakeEnv = new Dictionary <string, object> { { ":method", "get" }, { ":version", Protocols.Http1 }, { ":path", uri.PathAndQuery }, { ":scheme", uri.Scheme }, { ":host", uri.Host }, { "securityOptions", options }, { "secureSocket", sessionSocket }, { "end", ConnectionEnd.Client } }; HandshakeManager.GetHandshakeAction(handshakeEnv).Invoke(); } sessionSocket.Close(); Assert.Equal(Protocols.Http2, selectedProtocol); }
public bool Connect(Uri connectUri) { _path = connectUri.PathAndQuery; _version = Protocols.Http2; _scheme = connectUri.Scheme; _host = connectUri.Host; _port = connectUri.Port; ServerUri = connectUri.Authority; if (_clientSession != 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; _socket = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, _options); IDictionary <string, object> handshakeResult = null; using (var monitor = new ALPNExtensionMonitor()) { monitor.OnProtocolSelected += (o, args) => { _selectedProtocol = args.SelectedProtocol; }; _socket.Connect(new DnsEndPoint(connectUri.Host, connectUri.Port), monitor); if (_useHandshake) { var handshakeEnvironment = MakeHandshakeEnvironment(_socket); //Handshake manager determines what handshake must be used: upgrade or secure handshakeResult = HandshakeManager.GetHandshakeAction(handshakeEnvironment).Invoke(); Http2Logger.LogDebug("Handshake finished"); if (_selectedProtocol == Protocols.Http1) { _useHttp20 = false; return(true); } } } SendSessionHeader(); _useHttp20 = true; _clientSession = new Http2Session(_socket, ConnectionEnd.Client, _usePriorities, _useFlowControl, handshakeResult); //For saving incoming data _clientSession.OnFrameReceived += FrameReceivedHandler; _clientSession.OnRequestSent += RequestSentHandler; _clientSession.OnSessionDisposed += (sender, args) => Dispose(false); } catch (Http2HandshakeFailed ex) { if (ex.Reason == HandshakeFailureReason.InternalError) { _useHttp20 = false; } else { Http2Logger.LogError("Specified server did not respond"); Dispose(true); return(false); } } 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); }