示例#1
0
 public ThrottleProcessResult Process(RequestIdentity identity, IEnableThrottlingAttribute attrPolicy = null)
 {
     Identity = identity;
     Policy   = PolicyRepo.FirstOrDefault(ThrottleManager.GetPolicyKey());
     if (Policy != null)
     {
         Checking(attrPolicy);
     }
     return(processResult);
 }
示例#2
0
 public ThrottleLogEntry ComputeLogEntry(
     string requestId,
     RequestIdentity identity,
     ThrottleCounter throttleCounter,
     string rateLimitPeriod,
     long rateLimit)
 {
     return(new ThrottleLogEntry
     {
         ClientIp = identity.ClientIp,
         ClientKey = identity.ClientKey,
         Endpoint = identity.Endpoint,
         LogDate = DateTime.UtcNow,
         RateLimit = rateLimit,
         RateLimitPeriod = rateLimitPeriod,
         RequestId = requestId,
         StartPeriod = throttleCounter.Timestamp,
         TotalRequests = throttleCounter.TotalRequests
     });
 }
示例#3
0
        public void ApplyRules(RequestIdentity identity, TimeSpan timeSpan, RateLimitPeriod rateLimitPeriod, ref long rateLimit)
        {
            // apply endpoint rate limits
            if (Policy.EndpointRules != null)
            {
                var rules = Policy.EndpointRules.Where(x => identity.Endpoint.Contains(x.Key.ToLowerInvariant())).ToList();
                if (rules.Any())
                {
                    // get the lower limit from all applying rules
                    var customRate = (from r in rules let rateValue = r.Value.GetLimit(rateLimitPeriod) select rateValue).Min();

                    if (customRate > 0)
                    {
                        rateLimit = customRate;
                    }
                }
            }

            // apply custom rate limit for clients that will override endpoint limits
            if (Policy.ClientRules != null && Policy.ClientRules.Keys.Contains(identity.ClientKey))
            {
                var limit = Policy.ClientRules[identity.ClientKey].GetLimit(rateLimitPeriod);
                if (limit > 0)
                {
                    rateLimit = limit;
                }
            }

            // enforce ip rate limit as is most specific
            string ipRule = null;

            if (Policy.IpRules != null && ContainsIp(Policy.IpRules.Keys.ToList(), identity.ClientIp, out ipRule))
            {
                var limit = Policy.IpRules[ipRule].GetLimit(rateLimitPeriod);
                if (limit > 0)
                {
                    rateLimit = limit;
                }
            }
        }
示例#4
0
        public string ComputeThrottleKey(RequestIdentity requestIdentity, RateLimitPeriod period)
        {
            var keyValues = new List <string>()
            {
                ThrottleManager.GetThrottleKey()
            };

            if (Policy.IpThrottling)
            {
                keyValues.Add(requestIdentity.ClientIp);
            }

            if (Policy.ClientThrottling)
            {
                keyValues.Add(requestIdentity.ClientKey);
            }

            if (Policy.EndpointThrottling)
            {
                keyValues.Add(requestIdentity.Endpoint);
            }

            keyValues.Add(period.ToString());

            var id      = string.Join("_", keyValues);
            var idBytes = Encoding.UTF8.GetBytes(id);

            byte[] hashBytes;

            using (var algorithm = System.Security.Cryptography.HashAlgorithm.Create("SHA1"))
            {
                hashBytes = algorithm.ComputeHash(idBytes);
            }

            var hex = BitConverter.ToString(hashBytes).Replace("-", string.Empty);

            return(hex);
        }
示例#5
0
        public ThrottleCounter ProcessRequest(RequestIdentity requestIdentity, TimeSpan timeSpan, RateLimitPeriod period, out string id)
        {
            var throttleCounter = new ThrottleCounter()
            {
                Timestamp     = DateTime.UtcNow,
                TotalRequests = 1
            };

            id = ComputeThrottleKey(requestIdentity, period);

            // serial reads and writes
            lock (ProcessLocker)
            {
                var entry = ThrottleRepo.FirstOrDefault(id);
                if (entry.HasValue)
                {
                    // entry has not expired
                    if (entry.Value.Timestamp + timeSpan >= DateTime.UtcNow)
                    {
                        // increment request count
                        var totalRequests = entry.Value.TotalRequests + 1;

                        // deep copy
                        throttleCounter = new ThrottleCounter
                        {
                            Timestamp     = entry.Value.Timestamp,
                            TotalRequests = totalRequests
                        };
                    }
                }

                // stores: id (string) - timestamp (datetime) - total (long)
                ThrottleRepo.Save(id, throttleCounter, timeSpan);
            }

            return(throttleCounter);
        }