public void StartAndSuddenlyCloseSessionSuccessful() { string requestStr = GetAddress() + ConfigurationManager.AppSettings["smallTestFile"]; Uri uri; Uri.TryCreate(requestStr, UriKind.Absolute, out uri); bool gotException = false; var socketClosedRaisedEvent = new ManualResetEvent(false); var socket = GetHandshakedSocket(uri); socket.OnClose += (sender, args) => socketClosedRaisedEvent.Set(); try { var session = new Http2Session(socket, ConnectionEnd.Client, true, true, _handshakeResult); session.Start(); session.Dispose(); } catch (Exception) { gotException = true; } Assert.Equal(gotException, false); }
public void StartMultipleStreamsInOneSessionSuccessful(bool usePriorities, bool useFlowControl) { string requestStr = GetAddress() + ConfigurationManager.AppSettings["smallTestFile"]; Uri uri; Uri.TryCreate(requestStr, UriKind.Absolute, out uri); int finalFramesCounter = 0; const int streamsQuantity = 100; bool wasAllResourcesDownloaded = false; bool wasSocketClosed = false; var allResourcesDowloadedRaisedEvent = new ManualResetEvent(false); var socketClosedRaisedEvent = new ManualResetEvent(false); var socket = GetHandshakedSocket(uri); socket.OnClose += (sender, args) => { wasSocketClosed = true; socketClosedRaisedEvent.Set(); }; var session = new Http2Session(socket, ConnectionEnd.Client, usePriorities, useFlowControl, _handshakeResult); session.OnFrameReceived += (sender, args) => { if (args.Frame is IEndStreamFrame && ((IEndStreamFrame)args.Frame).IsEndStream) { finalFramesCounter++; if (finalFramesCounter == streamsQuantity) { allResourcesDowloadedRaisedEvent.Set(); wasAllResourcesDownloaded = true; } } }; session.Start(); for (int i = 0; i < streamsQuantity; i++) { SubmitRequest(session, uri); } allResourcesDowloadedRaisedEvent.WaitOne(120000); Assert.Equal(session.ActiveStreams.Count, streamsQuantity); session.Dispose(); socketClosedRaisedEvent.WaitOne(60000); Assert.Equal(wasAllResourcesDownloaded, true); Assert.Equal(wasSocketClosed, true); }
public FlowControlManager(Http2Session flowControlledSession) { SessionInitialWindowSize = Constants.DefaultFlowControlCredit; StreamsInitialWindowSize = Constants.DefaultFlowControlCredit; _flowControlledSession = flowControlledSession; _streamCollection = _flowControlledSession.ActiveStreams; Options = Constants.InitialFlowControlOptionsValue; IsSessionBlocked = false; }
internal void UpgradeToHttp2() { bool accepted = server.adaptor.OnUpgradeRequest(this, typeof(Http2Session)); if (accepted) { isPersistentSession = true; impl = new Http2Session(); } else { throw new InvalidOperationException("upgrade not accepted"); // TODO } }
private async void OpenHttp2Session(SecureSocket incomingClient, IDictionary <string, object> handshakeResult) { Http2Logger.LogDebug("Handshake successful"); _session = new Http2Session(incomingClient, ConnectionEnd.Server, _usePriorities, _useFlowControl, handshakeResult); _session.OnFrameReceived += FrameReceivedHandler; try { await _session.Start(); } catch (Exception) { Http2Logger.LogError("Client was disconnected"); } }
public void StartSessionAndGet10MbDataSuccessful() { string requestStr = GetAddress() + ConfigurationManager.AppSettings["10mbTestFile"]; Uri uri; Uri.TryCreate(requestStr, UriKind.Absolute, out uri); bool wasSocketClosed = false; bool wasFinalFrameReceived = false; var socketClosedRaisedEvent = new ManualResetEvent(false); var finalFrameReceivedRaisedEvent = new ManualResetEvent(false); var socket = GetHandshakedSocket(uri); socket.OnClose += (sender, args) => { socketClosedRaisedEvent.Set(); wasSocketClosed = true; }; var session = new Http2Session(socket, ConnectionEnd.Client, true, true, _handshakeResult); session.OnFrameReceived += (sender, args) => { if (args.Frame is IEndStreamFrame && ((IEndStreamFrame)args.Frame).IsEndStream) { finalFrameReceivedRaisedEvent.Set(); wasFinalFrameReceived = true; } }; session.Start(); SubmitRequest(session, uri); finalFrameReceivedRaisedEvent.WaitOne(60000); session.Dispose(); socketClosedRaisedEvent.WaitOne(60000); Assert.Equal(wasFinalFrameReceived, true); Assert.Equal(wasSocketClosed, true); }
public FlowControlManager(Http2Session flowControlledSession) { if (flowControlledSession == null) throw new ArgumentNullException("flowControlledSession"); //09 -> 6.9.2. Initial Flow Control Window Size //When a HTTP/2.0 connection is first established, new streams are //created with an initial flow control window size of 65535 bytes. The //connection flow control window is 65535 bytes. SessionInitialWindowSize = Constants.InitialFlowControlWindowSize; StreamsInitialWindowSize = Constants.InitialFlowControlWindowSize; _flowControlledSession = flowControlledSession; _streamDictionary = _flowControlledSession.StreamDictionary; Options = Constants.InitialFlowControlOptionsValue; _wasFlowControlSet = false; IsSessionBlocked = false; }
public void ProcessSettings(SettingsFrame settingsFrame, Http2Session session, FlowControlManager flCtrlManager) { for (int i = 0; i < settingsFrame.EntryCount; i++) { switch (settingsFrame[i].Id) { case SettingsIds.MaxCurrentStreams: session.RemoteMaxConcurrentStreams = settingsFrame[i].Value; break; case SettingsIds.InitialWindowSize: flCtrlManager.StreamsInitialWindowSize = settingsFrame[i].Value; break; case SettingsIds.FlowControlOptions: flCtrlManager.Options = settingsFrame[i].Value; break; } } }
public FlowControlManager(Http2Session flowControlledSession) { if (flowControlledSession == null) { throw new ArgumentNullException("flowControlledSession"); } //09 -> 6.9.2. Initial Flow Control Window Size //When a HTTP/2.0 connection is first established, new streams are //created with an initial flow control window size of 65535 bytes. The //connection flow control window is 65535 bytes. SessionInitialWindowSize = Constants.InitialFlowControlWindowSize; StreamsInitialWindowSize = Constants.InitialFlowControlWindowSize; _flowControlledSession = flowControlledSession; _streamDictionary = _flowControlledSession.StreamDictionary; Options = Constants.InitialFlowControlOptionsValue; _wasFlowControlSet = false; IsSessionBlocked = false; }
protected static Http2Stream SubmitRequest(Http2Session session, Uri uri) { const string method = "get"; string path = uri.PathAndQuery; string version = Protocols.Http2; string scheme = uri.Scheme; string host = uri.Host; var pairs = new HeadersList { new KeyValuePair <string, string>(":method", method), new KeyValuePair <string, string>(":path", path), new KeyValuePair <string, string>(":version", version), new KeyValuePair <string, string>(":host", host), new KeyValuePair <string, string>(":scheme", scheme), }; session.SendRequest(pairs, Priority.None, false); return(session.ActiveStreams[1]); }
public void ActiveStreamsSuccessful() { var handshakeResult = new Dictionary <string, object>(); var session = new Http2Session(null, ConnectionEnd.Client, true, true, handshakeResult); var testCollection = session.ActiveStreams; var fm = new FlowControlManager(session); testCollection[1] = new Http2Stream(null, 1, null, fm, null); testCollection[2] = new Http2Stream(null, 2, null, fm, null); testCollection[3] = new Http2Stream(null, 3, null, fm, null); testCollection[4] = new Http2Stream(null, 4, null, fm, null); fm.DisableStreamFlowControl(testCollection[2]); fm.DisableStreamFlowControl(testCollection[4]); Assert.Equal(testCollection.NonFlowControlledStreams.Count, 2); Assert.Equal(testCollection.FlowControlledStreams.Count, 2); bool gotException = false; try { testCollection[4] = new Http2Stream(null, 3, null, fm, null); } catch (ArgumentException) { gotException = true; } Assert.Equal(gotException, true); testCollection.Remove(4); Assert.Equal(testCollection.Count, 3); Assert.Equal(testCollection.ContainsKey(4), false); }
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); }
public void StartSessionAndSendRequestSuccessful() { string requestStr = GetAddress() + ConfigurationManager.AppSettings["smallTestFile"]; Uri uri; Uri.TryCreate(requestStr, UriKind.Absolute, out uri); bool wasSettingsSent = false; bool wasHeadersSent = false; bool wasSocketClosed = false; var settingsSentRaisedEventArgs = new ManualResetEvent(false); var headersPlusPriSentRaisedEvent = new ManualResetEvent(false); var socketClosedRaisedEvent = new ManualResetEvent(false); var socket = GetHandshakedSocket(uri); socket.OnClose += (sender, args) => { socketClosedRaisedEvent.Set(); wasSocketClosed = true; }; var session = new Http2Session(socket, ConnectionEnd.Client, true, true, _handshakeResult); session.OnSettingsSent += (o, args) => { wasSettingsSent = true; Assert.Equal(args.SettingsFrame.StreamId, 0); settingsSentRaisedEventArgs.Set(); }; session.OnFrameSent += (sender, args) => { if (wasHeadersSent == false) { wasHeadersSent = args.Frame is HeadersFrame; headersPlusPriSentRaisedEvent.Set(); } }; session.Start(); settingsSentRaisedEventArgs.WaitOne(60000); var stream = SubmitRequest(session, uri); headersPlusPriSentRaisedEvent.WaitOne(60000); //Settings frame does not contain flow control settings in this test. Assert.Equal(session.ActiveStreams.Count, 1); Assert.Equal(session.ActiveStreams.FlowControlledStreams.Count, 1); Assert.Equal(stream.IsFlowControlBlocked, false); Assert.Equal(stream.Id, 1); Assert.Equal(stream.IsFlowControlEnabled, true); Assert.Equal(stream.EndStreamSent, false); Assert.Equal(stream.Disposed, false); Assert.Equal(wasHeadersSent, true); Assert.Equal(wasSettingsSent, true); headersPlusPriSentRaisedEvent.Dispose(); settingsSentRaisedEventArgs.Dispose(); session.Dispose(); socketClosedRaisedEvent.WaitOne(60000); Assert.Equal(wasSocketClosed, true); }