Esempio n. 1
0
 public void RequiresThrottling(
     IPipelines pipelines,
     ThrottlingProperties propertiesSet,
     ThrottlingPeriod period,
     int requestCountLimit,
     Func <NancyContext, bool> checkIf = null,
     Func <NancyContext, bool> skipIf  = null,
     params string[] requestKeys)
 {
     pipelines.BeforeRequest.AddItemToStartOfPipeline(
         ctx => CheckThrottlingLimitHook(ctx, propertiesSet, period, requestCountLimit,
                                         checkIf: checkIf,
                                         skipIf: skipIf,
                                         requestKeys: requestKeys));
 }
Esempio n. 2
0
 public void RequiresThrottling(
     INancyModule module,
     ThrottlingProperties propertiesSet,
     ThrottlingPeriod period,
     int requestCountLimit,
     Func <NancyContext, bool> checkIf = null,
     Func <NancyContext, bool> skipIf  = null,
     params string[] requestKeys)
 {
     module.AddBeforeHookOrExecute(
         ctx => CheckThrottlingLimitHook(ctx, propertiesSet, period, requestCountLimit,
                                         checkIf: checkIf,
                                         skipIf: skipIf,
                                         requestKeys: requestKeys),
         "RequiresThrottling");
 }
Esempio n. 3
0
        private static string BuildRequestKey(
            ThrottlingProperties propertiesSet,
            ThrottlingPeriod period,
            NancyContext context,
            params string[] requestKeys)
        {
            using (var ms = new MemoryStream())
                using (var sw = new StreamWriter(ms, Encoding.UTF8))
                {
                    if (propertiesSet.HasFlag(ThrottlingProperties.RemoteIp))
                    {
                        sw.Write(context.GetClientHost());
                    }

                    if (propertiesSet.HasFlag(ThrottlingProperties.Method))
                    {
                        sw.Write(context.Request.Method);
                    }

                    if (propertiesSet.HasFlag(ThrottlingProperties.Path))
                    {
                        sw.Write(context.Request.Path);
                    }

                    sw.Write(period);

                    if (requestKeys != null)
                    {
                        foreach (var key in requestKeys)
                        {
                            sw.Write(key);
                        }
                    }

                    sw.Flush();
                    ms.Position = 0;
                    using (var algorithm = new SHA1Managed())
                    {
                        var hash = algorithm.ComputeHash(ms);
                        return(Convert.ToBase64String(hash));
                    }
                }
        }
Esempio n. 4
0
        private Response CheckThrottlingLimitHook(
            NancyContext context,
            ThrottlingProperties propertiesSet,
            ThrottlingPeriod period,
            int requestCountLimit,
            Func <NancyContext, bool> checkIf = null,
            Func <NancyContext, bool> skipIf  = null,
            params string[] requestKeys)
        {
            if (checkIf != null && !checkIf(context))
            {
                return(null);
            }

            if (skipIf != null && skipIf(context))
            {
                return(null);
            }

            var key            = BuildRequestKey(propertiesSet, period, context, requestKeys);
            var expirationTime = CalculateExpirationTime(period);

            var counterValue = IncrementCounter(key, expirationTime);

            if (IsLimitExceeded(requestCountLimit, counterValue))
            {
                if (IsNeedToLog(requestCountLimit, counterValue))
                {
                    logger.Error($"Flood detected ({counterValue} in {period.ToString()} allowed {requestCountLimit})" +
                                 $" on path: {context?.Request?.Path}" +
                                 $" ip: {context?.GetClientHost()}");
                }
                return(new Response
                {
                    StatusCode = HttpStatusCode.TooManyRequests
                });
            }

            return(null);
        }