public async Task ConnectionNotTimedOutWhileRequestBeingSent()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            using (var server = CreateServer(testContext))
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(
                        "POST /consume HTTP/1.1",
                        "Host:",
                        "Transfer-Encoding: chunked",
                        "",
                        "");

                    await _firstRequestReceived.Task.DefaultTimeout();

                    for (var totalDelay = TimeSpan.Zero; totalDelay < _longDelay; totalDelay += _shortDelay)
                    {
                        await connection.Send(
                            "1",
                            "a",
                            "");

                        testContext.MockSystemClock.UtcNow += _shortDelay;
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }

                    await connection.Send(
                        "0",
                        "",
                        "");
                    await ReceiveResponse(connection, testContext);
                }
        }
        /// <summary>
        /// 正在初始化心跳模块
        /// </summary>
        private static void InitHeartbeat()
        {
            //LogHelper.SystemInfo("正在初始化心跳检测模块");

            _heartbeatManager = new HeartbeatManager(_heartbeatInterval);
            _heartbeatManager.Start();
        }
        private async Task KeepAliveTimeoutDoesNotApplyToUpgradedConnections()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
            var cts = new CancellationTokenSource();

            using (var server = CreateServer(testContext, upgradeCt: cts.Token))
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(
                        "GET /upgrade HTTP/1.1",
                        "Host:",
                        "Connection: Upgrade",
                        "",
                        "");

                    await connection.Receive(
                        "HTTP/1.1 101 Switching Protocols",
                        "Connection: Upgrade",
                        $"Date: {testContext.DateHeaderValue}",
                        "",
                        "");

                    for (var totalDelay = TimeSpan.Zero; totalDelay < _longDelay; totalDelay += _shortDelay)
                    {
                        testContext.MockSystemClock.UtcNow += _shortDelay;
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }

                    cts.Cancel();

                    await connection.Receive("hello, world");
                }
        }
        private async Task ConnectionNotTimedOutWhileAppIsRunning()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
            var cts = new CancellationTokenSource();

            using (var server = CreateServer(testContext, longRunningCt: cts.Token))
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(
                        "GET /longrunning HTTP/1.1",
                        "Host:",
                        "",
                        "");

                    await _firstRequestReceived.Task.DefaultTimeout();

                    for (var totalDelay = TimeSpan.Zero; totalDelay < _longDelay; totalDelay += _shortDelay)
                    {
                        testContext.MockSystemClock.UtcNow += _shortDelay;
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }

                    cts.Cancel();

                    await ReceiveResponse(connection, testContext);

                    await connection.Send(
                        "GET / HTTP/1.1",
                        "Host:",
                        "",
                        "");
                    await ReceiveResponse(connection, testContext);
                }
        }
Esempio n. 5
0
        public async Task RequestHeadersTimeoutCanceledAfterHeadersReceived()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            await using (var server = CreateServer(testContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.TransportConnection.WaitForReadTask;

                    await connection.Send(
                        "POST / HTTP/1.1",
                        "Host:",
                        "Content-Length: 1",
                        "",
                        "");

                    // Min amount of time between requests that triggers a request headers timeout.
                    testContext.MockSystemClock.UtcNow += RequestHeadersTimeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    await connection.Send(
                        "a");

                    await ReceiveResponse(connection, testContext);
                }
            }
        }
Esempio n. 6
0
        public async Task ConnectionClosedWhenKeepAliveTimeoutExpires()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            await using (var server = CreateServer(testContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.TransportConnection.WaitForReadTask;

                    await connection.Send(
                        "GET / HTTP/1.1",
                        "Host:",
                        "",
                        "");
                    await ReceiveResponse(connection, testContext);

                    // Min amount of time between requests that triggers a keep-alive timeout.
                    testContext.MockSystemClock.UtcNow += _keepAliveTimeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    await connection.WaitForConnectionClose();
                }
            }
        }
Esempio n. 7
0
        public async Task TimeoutNotResetOnEachRequestLineCharacterReceived()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            // Disable response rate, so we can finish the send loop without timing out the response.
            testContext.ServerOptions.Limits.MinResponseDataRate = null;

            await using (var server = CreateServer(testContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.TransportConnection.WaitForReadTask;

                    foreach (var ch in "POST / HTTP/1.1\r\nHost:\r\n\r\n")
                    {
                        await connection.Send(ch.ToString());

                        testContext.MockSystemClock.UtcNow += ShortDelay;
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }

                    await ReceiveTimeoutResponse(connection, testContext);

                    await connection.WaitForConnectionClose();
                }
            }
        }
Esempio n. 8
0
        public async Task ConnectionKeptAliveBetweenRequests()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            await using (var server = CreateServer(testContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.TransportConnection.WaitForReadTask;

                    for (var i = 0; i < 10; i++)
                    {
                        await connection.Send(
                            "GET / HTTP/1.1",
                            "Host:",
                            "",
                            "");
                        await ReceiveResponse(connection, testContext);

                        // Max amount of time between requests that doesn't trigger a keep-alive timeout.
                        testContext.MockSystemClock.UtcNow += _keepAliveTimeout + Heartbeat.Interval;
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }
                }
            }
        }
Esempio n. 9
0
        public async Task DoesNotEnforceRequestBodyMinimumDataRateOnUpgradedRequest()
        {
            var appEvent         = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
            var delayEvent       = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceContext   = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(serviceContext.ConnectionManager);

            using (var server = new TestServer(async context =>
            {
                context.Features.Get <IHttpMinRequestBodyDataRateFeature>().MinDataRate =
                    new MinDataRate(bytesPerSecond: double.MaxValue, gracePeriod: Heartbeat.Interval + TimeSpan.FromTicks(1));

                using (var stream = await context.Features.Get <IHttpUpgradeFeature>().UpgradeAsync())
                {
                    appEvent.SetResult(null);

                    // Read once to go through one set of TryPauseTimingReads()/TryResumeTimingReads() calls
                    await stream.ReadAsync(new byte[1], 0, 1);

                    await delayEvent.Task.DefaultTimeout();

                    // Read again to check that the connection is still alive
                    await stream.ReadAsync(new byte[1], 0, 1);

                    // Send a response to distinguish from the timeout case where the 101 is still received, but without any content
                    var response = Encoding.ASCII.GetBytes("hello");
                    await stream.WriteAsync(response, 0, response.Length);
                }
            }, serviceContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(
                        "GET / HTTP/1.1",
                        "Host:",
                        "Connection: upgrade",
                        "",
                        "a");

                    await appEvent.Task.DefaultTimeout();

                    serviceContext.MockSystemClock.UtcNow += TimeSpan.FromSeconds(5);
                    heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);

                    delayEvent.SetResult(null);

                    await connection.Send("b");

                    await connection.ReceiveEnd(
                        "HTTP/1.1 101 Switching Protocols",
                        "Connection: Upgrade",
                        $"Date: {server.Context.DateHeaderValue}",
                        "",
                        "hello");
                }
                await server.StopAsync();
            }
        }
Esempio n. 10
0
        public async Task ConnectionClosedWhenResponseNotDrainedAtMinimumDataRate(ListenOptions listenOptions)
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
            var minRate          = new MinDataRate(16384, TimeSpan.FromSeconds(2));

            await using (var server = new TestServer(context =>
            {
                context.Features.Get <IHttpMinResponseDataRateFeature>().MinDataRate = minRate;
                return(Task.CompletedTask);
            }, testContext, listenOptions))
            {
                using (var connection = server.CreateConnection())
                {
                    var transportConnection = connection.TransportConnection;

                    var outputBufferedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

#pragma warning disable 0618 // TODO: Repalce OnWriterCompleted
                    transportConnection.Output.OnWriterCompleted((ex, state) =>
                    {
                        ((TaskCompletionSource)state).SetResult();
                    },
                                                                 outputBufferedTcs);
#pragma warning restore

                    await connection.Send(
                        "GET / HTTP/1.1",
                        "Host:",
                        "Connection: close",
                        "",
                        "");

                    // Wait for the drain timeout to be set.
                    await outputBufferedTcs.Task.DefaultTimeout();

                    // Advance the clock to the grace period
                    for (var i = 0; i < 2; i++)
                    {
                        testContext.MockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }

                    testContext.MockSystemClock.UtcNow += Heartbeat.Interval - TimeSpan.FromSeconds(.5);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    Assert.Null(transportConnection.AbortReason);

                    testContext.MockSystemClock.UtcNow += TimeSpan.FromSeconds(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    Assert.NotNull(transportConnection.AbortReason);
                    Assert.Equal(CoreStrings.ConnectionTimedBecauseResponseMininumDataRateNotSatisfied, transportConnection.AbortReason.Message);

                    Assert.Single(LogMessages, w => w.EventId.Id == 28 && w.LogLevel <= LogLevel.Debug);
                }
            }
        }
Esempio n. 11
0
        private static ServiceContext CreateServiceContext(IOptions <KestrelServerOptions> options, ILoggerFactory loggerFactory)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            var serverOptions     = options.Value ?? new KestrelServerOptions();
            var logger            = loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel");
            var trace             = new KestrelTrace(logger);
            var connectionManager = new ConnectionManager(
                trace,
                serverOptions.Limits.MaxConcurrentUpgradedConnections);

            var now = DateTimeOffset.UtcNow;
            var heartbeatManager       = new HeartbeatManager(connectionManager, now);
            var dateHeaderValueManager = new DateHeaderValueManager(now);
            var heartbeat = new Heartbeat(
                new IHeartbeatHandler[] { dateHeaderValueManager, heartbeatManager },
                new SystemClock(),
                DebuggerWrapper.Singleton,
                trace);

            // TODO: This logic will eventually move into the IConnectionHandler<T> and off
            // the service context once we get to https://github.com/aspnet/KestrelHttpServer/issues/1662
            PipeScheduler scheduler = null;

            switch (serverOptions.ApplicationSchedulingMode)
            {
            case SchedulingMode.Default:
            case SchedulingMode.ThreadPool:
                scheduler = PipeScheduler.ThreadPool;
                break;

            case SchedulingMode.Inline:
                scheduler = PipeScheduler.Inline;
                break;

            default:
                throw new NotSupportedException(CoreStrings.FormatUnknownTransportMode(serverOptions.ApplicationSchedulingMode));
            }

            return(new ServiceContext
            {
                Log = trace,
                HttpParser = new HttpParser <Http1ParsingHandler>(trace.IsEnabled(LogLevel.Information)),
                Scheduler = scheduler,
                SystemClock = heartbeatManager,
                DateHeaderValueManager = dateHeaderValueManager,
                ConnectionManager = connectionManager,
                Heartbeat = heartbeat,
                ServerOptions = serverOptions,
            });
        }
Esempio n. 12
0
 public HtcServer(HtcServerOptions serverOptions)
 {
     ServerOptions     = serverOptions;
     HtcLogger         = new HtcLogger(Logger);
     ConnectionManager = new ConnectionManager(HtcLogger, ServerOptions.Limits.MaxConcurrentUpgradedConnections);
     HeartbeatManager  = new HeartbeatManager(ConnectionManager);
     Heartbeat         = new Heartbeat(new IHeartbeatHandler[] { dateHeaderValueManager, heartbeatManager }, new SystemClock(), DebuggerWrapper.Singleton, trace);
     HttpCharacters.Initialize();
 }
Esempio n. 13
0
        public MembershipManager(IShard shard, NodeContext context, ClusterConfigurationManager clusterConfigMgr)
        {
            this._shard            = shard;
            this._context          = context;
            this._clusterConfigMgr = clusterConfigMgr;
            this._strategy         = new ElectionBasedMembershipStrategy(shard, context, _heartbeatReporting, _clusterConfigMgr);
            shard.RegisterShardListener(Common.MiscUtil.MEMBERSHIP_MANAGER, this);
            _heartbeatManager = new HeartbeatManager();

            _latestMembership.Cluster = _context.ClusterName;
            _latestMembership.Shard   = _context.LocalShardName;
        }
        public async Task ConnectionClosedWhenResponseNotDrainedAtMinimumDataRate(ListenOptions listenOptions)
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
            var minRate          = new MinDataRate(16384, TimeSpan.FromSeconds(2));

            using (var server = new TestServer(context =>
            {
                context.Features.Get <IHttpMinResponseDataRateFeature>().MinDataRate = minRate;
                return(Task.CompletedTask);
            }, testContext, listenOptions))
            {
                using (var connection = server.CreateConnection())
                {
                    var transportConnection = connection.TransportConnection;

                    var outputBufferedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

                    transportConnection.Output.OnWriterCompleted((ex, state) =>
                    {
                        ((TaskCompletionSource <object>)state).SetResult(null);
                    }, outputBufferedTcs);

                    await connection.Send(
                        "GET / HTTP/1.1",
                        "Host:",
                        "Connection: close",
                        "",
                        "");

                    // Wait for the drain timeout to be set.
                    await outputBufferedTcs.Task.DefaultTimeout();

                    testContext.MockSystemClock.UtcNow +=
                        Heartbeat.Interval +
                        TimeSpan.FromSeconds(testContext.ServerOptions.Limits.MaxResponseBufferSize.Value * 2 / minRate.BytesPerSecond);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    Assert.Null(transportConnection.AbortReason);

                    testContext.MockSystemClock.UtcNow += TimeSpan.FromTicks(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    Assert.NotNull(transportConnection.AbortReason);
                    Assert.Equal(CoreStrings.ConnectionTimedBecauseResponseMininumDataRateNotSatisfied, transportConnection.AbortReason.Message);

                    Assert.Single(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 28 && w.LogLevel == LogLevel.Information);
                }
            }
        }
Esempio n. 15
0
        public async Task HandshakeTimesOutAndIsLoggedAsDebug()
        {
            var loggerProvider = new HandshakeErrorLoggerProvider();

            LoggerFactory.AddProvider(loggerProvider);

            var testContext = new TestServiceContext(LoggerFactory)
            {
                ExpectedConnectionMiddlewareCount = 1
            };
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            var      handshakeStartedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
            TimeSpan handshakeTimeout    = default;

            await using (var server = new TestServer(context => Task.CompletedTask,
                                                     testContext,
                                                     listenOptions =>
            {
                listenOptions.UseHttps(o =>
                {
                    o.ServerCertificate = new X509Certificate2(TestResources.GetTestCertificate());
                    o.OnAuthenticate = (_, __) =>
                    {
                        handshakeStartedTcs.SetResult(null);
                    };

                    handshakeTimeout = o.HandshakeTimeout;
                });
            }))
            {
                using (var connection = server.CreateConnection())
                {
                    // HttpsConnectionAdapter dispatches via Task.Run() before starting the handshake.
                    // Wait for the handshake to start before advancing the system clock.
                    await handshakeStartedTcs.Task.DefaultTimeout();

                    // Min amount of time between requests that triggers a handshake timeout.
                    testContext.MockSystemClock.UtcNow += handshakeTimeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    Assert.Equal(0, await connection.Stream.ReadAsync(new byte[1], 0, 1).DefaultTimeout());
                }
            }

            await loggerProvider.FilterLogger.LogTcs.Task.DefaultTimeout();

            Assert.Equal(2, loggerProvider.FilterLogger.LastEventId);
            Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel);
        }
 /// <summary>
 /// Program's entry point.
 /// </summary>
 /// <param name="args">Commandline arguments.</param>
 public static void Main(string[] args)
 {
     Console.Title = "Gamemakergm's Heartbeater.";
     new ServerExample("[MCTest] Gamemakergm's Awesome Build", true);                            // Create a new server for demonstration purposes.
     Heartbeat = new HeartbeatExample();                                                         // Create the new heartbeat.
     Manager   = new HeartbeatManager(Heartbeat, TimeSpan.FromSeconds(5), ServerExample.Server); //
     while (true)
     {
         if (Console.ReadLine().Equals("h"))
         {
             Console.WriteLine("H");
         }
     }
 }
Esempio n. 17
0
        public void InitializeHeartbeat()
        {
            var heartbeatManager = new HeartbeatManager(ConnectionManager);

            DateHeaderValueManager = new DateHeaderValueManager();
            Heartbeat = new Heartbeat(
                new IHeartbeatHandler[] { DateHeaderValueManager, heartbeatManager },
                new SystemClock(),
                DebuggerWrapper.Singleton,
                Log);

            MockSystemClock = null;
            SystemClock     = heartbeatManager;
        }
        private async Task ConnectionTimesOutWhenOpenedButNoRequestSent()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            using (var server = CreateServer(testContext))
                using (var connection = server.CreateConnection())
                {
                    // Min amount of time between requests that triggers a keep-alive timeout.
                    testContext.MockSystemClock.UtcNow += _keepAliveTimeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    await connection.WaitForConnectionClose();
                }
        }
Esempio n. 19
0
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            PriceUpdateContext.Initialize(APIConfigManager.AWSAccessKey, APIConfigManager.AWSSecretKey, APIConfigManager.ServiceAccountId, APIConfigManager.ServiceAccountPassword, "smtp.gmail.com", "Automated Mail", APIConfigManager.TablesToCreate);
            //InitalizePriceUpdateContext();
            //Make endpoint and timeout configurable
            HeartbeatManager hbManager = new HeartbeatManager(@"http://localhost:59132/api/amazonproductapi", new TimeSpan(0, 1, 0));
            Task             hbTask    = Task.Factory.StartNew(hbManager.CheckServiceHeartbeat, TaskCreationOptions.LongRunning);

            JobScheduler.Start();
        }
Esempio n. 20
0
        public async Task ConnectionAbortedWhenRequestLineNotReceivedInTime(string requestLine)
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            using (var server = CreateServer(testContext))
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(requestLine);

                    // Min amount of time between requests that triggers a request headers timeout.
                    testContext.MockSystemClock.UtcNow += RequestHeadersTimeout + Heartbeat.Interval + TimeSpan.FromTicks(1);
                    heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);

                    await ReceiveTimeoutResponse(connection, testContext);
                }
        }
Esempio n. 21
0
 public void Dispose()
 {
     if (_heartbeatManager != null)
     {
         _heartbeatManager.Dispose();
     }
     _heartbeatManager = null;
     if (_takeOverElectionTask != null)
     {
         _takeOverElectionTask.Stop();
     }
     _takeOverElectionTask = null;
     if (_retryTask != null)
     {
         _retryTask.Stop();
     }
     _retryTask = null;
 }
Esempio n. 22
0
        public async Task TimeoutNotResetOnEachRequestLineCharacterReceived()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            using (var server = CreateServer(testContext))
                using (var connection = server.CreateConnection())
                {
                    foreach (var ch in "POST / HTTP/1.1\r\nHost:\r\n\r\n")
                    {
                        await connection.Send(ch.ToString());

                        testContext.MockSystemClock.UtcNow += ShortDelay;
                        heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                    }

                    await ReceiveTimeoutResponse(connection, testContext);

                    await connection.WaitForConnectionClose();
                }
        }
Esempio n. 23
0
    private static ServiceContext CreateServiceContext(IOptions <KestrelServerOptions> options, ILoggerFactory loggerFactory, DiagnosticSource?diagnosticSource)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }
        if (loggerFactory == null)
        {
            throw new ArgumentNullException(nameof(loggerFactory));
        }

        var serverOptions     = options.Value ?? new KestrelServerOptions();
        var trace             = new KestrelTrace(loggerFactory);
        var connectionManager = new ConnectionManager(
            trace,
            serverOptions.Limits.MaxConcurrentUpgradedConnections);

        var heartbeatManager       = new HeartbeatManager(connectionManager);
        var dateHeaderValueManager = new DateHeaderValueManager();

        var heartbeat = new Heartbeat(
            new IHeartbeatHandler[] { dateHeaderValueManager, heartbeatManager },
            new SystemClock(),
            DebuggerWrapper.Singleton,
            trace);

        return(new ServiceContext
        {
            Log = trace,
            Scheduler = PipeScheduler.ThreadPool,
            HttpParser = new HttpParser <Http1ParsingHandler>(trace.IsEnabled(LogLevel.Information)),
            SystemClock = heartbeatManager,
            DateHeaderValueManager = dateHeaderValueManager,
            ConnectionManager = connectionManager,
            Heartbeat = heartbeat,
            ServerOptions = serverOptions,
            DiagnosticSource = diagnosticSource
        });
    }
Esempio n. 24
0
        public async Task TimeoutNotResetOnEachRequestLineCharacterReceived()
        {
            var testContext      = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);

            using (var server = CreateServer(testContext))
                using (var connection = server.CreateConnection())
                {
                    // When the in-memory connection is aborted, the input PipeWriter is completed behind the scenes
                    // so eventually connection.Send() throws an InvalidOperationException.
                    await Assert.ThrowsAsync <InvalidOperationException>(async() =>
                    {
                        foreach (var ch in "POST / HTTP/1.1\r\nHost:\r\n\r\n")
                        {
                            await connection.Send(ch.ToString());

                            testContext.MockSystemClock.UtcNow += ShortDelay;
                            heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow);
                        }
                    });

                    await ReceiveTimeoutResponse(connection, testContext);
                }
        }
        public async Task RequestTimesOutWhenRequestBodyNotReceivedAtSpecifiedMinimumRate()
        {
            var gracePeriod      = TimeSpan.FromSeconds(5);
            var serviceContext   = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(serviceContext.ConnectionManager);

            var appRunningEvent = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            using (var server = new TestServer(context =>
            {
                context.Features.Get <IHttpMinRequestBodyDataRateFeature>().MinDataRate =
                    new MinDataRate(bytesPerSecond: 1, gracePeriod: gracePeriod);

                // The server must call Request.Body.ReadAsync() *before* the test sets systemClock.UtcNow (which is triggered by the
                // server calling appRunningEvent.SetResult(null)).  If systemClock.UtcNow is set first, it's possible for the test to fail
                // due to the following race condition:
                //
                // 1. [test]    systemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
                // 2. [server]  Heartbeat._timer is triggered, which calls HttpConnection.Tick()
                // 3. [server]  HttpConnection.Tick() calls HttpConnection.CheckForReadDataRateTimeout()
                // 4. [server]  HttpConnection.CheckForReadDataRateTimeout() is a no-op, since _readTimingEnabled is false,
                //              since Request.Body.ReadAsync() has not been called yet
                // 5. [server]  HttpConnection.Tick() sets _lastTimestamp = timestamp
                // 6. [server]  Request.Body.ReadAsync() is called
                // 6. [test]    systemClock.UtcNow is never updated again, so server timestamp is never updated,
                //              so HttpConnection.CheckForReadDataRateTimeout() is always a no-op until test fails
                //
                // This is a pretty tight race, since the once-per-second Heartbeat._timer needs to fire between the test updating
                // systemClock.UtcNow and the server calling Request.Body.ReadAsync().  But it happened often enough to cause
                // test flakiness in our CI (https://github.com/aspnet/KestrelHttpServer/issues/2539).
                //
                // For verification, I was able to induce the race by adding a sleep in the RequestDelegate:
                //     appRunningEvent.SetResult(null);
                //     Thread.Sleep(5000);
                //     return context.Request.Body.ReadAsync(new byte[1], 0, 1);

                var readTask = context.Request.Body.ReadAsync(new byte[1], 0, 1);
                appRunningEvent.SetResult(null);
                return(readTask);
            }, serviceContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(
                        "POST / HTTP/1.1",
                        "Host:",
                        "Content-Length: 1",
                        "",
                        "");

                    await appRunningEvent.Task.DefaultTimeout();

                    serviceContext.MockSystemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
                    heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);

                    await connection.Receive(
                        "HTTP/1.1 408 Request Timeout",
                        "");

                    await connection.ReceiveForcedEnd(
                        "Connection: close",
                        $"Date: {serviceContext.DateHeaderValue}",
                        "Content-Length: 0",
                        "",
                        "");
                }
            }
        }
        public async Task ConnectionClosedEvenIfAppSwallowsException()
        {
            var gracePeriod      = TimeSpan.FromSeconds(5);
            var serviceContext   = new TestServiceContext(LoggerFactory);
            var heartbeatManager = new HeartbeatManager(serviceContext.ConnectionManager);

            var appRunningTcs         = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
            var exceptionSwallowedTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            using (var server = new TestServer(async context =>
            {
                context.Features.Get <IHttpMinRequestBodyDataRateFeature>().MinDataRate =
                    new MinDataRate(bytesPerSecond: 1, gracePeriod: gracePeriod);

                // See comment in RequestTimesOutWhenRequestBodyNotReceivedAtSpecifiedMinimumRate for
                // why we call ReadAsync before setting the appRunningEvent.
                var readTask = context.Request.Body.ReadAsync(new byte[1], 0, 1);
                appRunningTcs.SetResult(null);

                try
                {
                    await readTask;
                }
                catch (BadHttpRequestException ex) when(ex.StatusCode == 408)
                {
                    exceptionSwallowedTcs.SetResult(null);
                }
                catch (Exception ex)
                {
                    exceptionSwallowedTcs.SetException(ex);
                }

                var response = "hello, world";
                context.Response.ContentLength = response.Length;
                await context.Response.WriteAsync("hello, world");
            }, serviceContext))
            {
                using (var connection = server.CreateConnection())
                {
                    await connection.Send(
                        "POST / HTTP/1.1",
                        "Host:",
                        "Content-Length: 1",
                        "",
                        "");

                    await appRunningTcs.Task.DefaultTimeout();

                    serviceContext.MockSystemClock.UtcNow += gracePeriod + TimeSpan.FromSeconds(1);
                    heartbeatManager.OnHeartbeat(serviceContext.SystemClock.UtcNow);

                    await exceptionSwallowedTcs.Task.DefaultTimeout();

                    await connection.Receive(
                        "HTTP/1.1 200 OK",
                        "");

                    await connection.ReceiveForcedEnd(
                        $"Date: {serviceContext.DateHeaderValue}",
                        "Content-Length: 12",
                        "",
                        "hello, world");
                }
            }
        }
Esempio n. 27
0
 // 秒心跳
 public static void HeartbeatSecond()
 {
     HeartbeatManager.HeartbeatAllPlayerSecond();
 }
Esempio n. 28
0
        // 10秒心跳
        public static void HeartbeatSecond10()
        {
            GameServerLinkManager.HeartbeatSecond10();

            HeartbeatManager.HeartbeatAllPlayerSecond10();
        }