示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        public FlowControlManager(Http2Session flowControlledSession)
        {
            SessionInitialWindowSize = Constants.DefaultFlowControlCredit;
            StreamsInitialWindowSize = Constants.DefaultFlowControlCredit;

            _flowControlledSession = flowControlledSession;
            _streamCollection = _flowControlledSession.ActiveStreams;

            Options = Constants.InitialFlowControlOptionsValue;

            IsSessionBlocked = false;
        }
示例#4
0
        public FlowControlManager(Http2Session flowControlledSession)
        {
            SessionInitialWindowSize = Constants.DefaultFlowControlCredit;
            StreamsInitialWindowSize = Constants.DefaultFlowControlCredit;

            _flowControlledSession = flowControlledSession;
            _streamCollection      = _flowControlledSession.ActiveStreams;

            Options = Constants.InitialFlowControlOptionsValue;

            IsSessionBlocked = false;
        }
示例#5
0
        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");
            }
        }
示例#7
0
        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);
        }
示例#8
0
        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;
        }
示例#9
0
        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;
                }
            }
        }
示例#10
0
        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;
                }
            }
        }
示例#11
0
        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;
        }
示例#12
0
        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]);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }