Пример #1
0
        internal bool IsWhitelisted(RequestIdentity requestIdentity)
        {
            if (Policy.IpThrottling)
            {
                if (Policy.IpWhitelist != null && ContainsIp(Policy.IpWhitelist, requestIdentity.ClientIp))
                {
                    return true;
                }
            }

            if (Policy.ClientThrottling)
            {
                if (Policy.ClientWhitelist != null && Policy.ClientWhitelist.Contains(requestIdentity.ClientKey))
                {
                    return true;
                }
            }

            if (Policy.EndpointThrottling)
            {
                if (Policy.EndpointWhitelist != null
                    && Policy.EndpointWhitelist.Any(x => requestIdentity.Endpoint.Contains(x.ToLowerInvariant())))
                {
                    return true;
                }
            }

            return false;
        }
Пример #2
0
        protected virtual RequestIdentity SetIndentity(HttpRequestMessage request)
        {
            var entry = new RequestIdentity();

            entry.ClientIp  = core.GetClientIp(request).ToString();
            entry.Endpoint  = request.RequestUri.AbsolutePath.ToLowerInvariant();
            entry.ClientKey = request.Headers.Contains("Authorization-Token") ? request.Headers.GetValues("Authorization-Token").First() : "anon";

            return(entry);
        }
Пример #3
0
        protected virtual RequestIdentity SetIdentity(IOwinRequest request)
        {
            var entry = new RequestIdentity();

            entry.ClientIp  = request.RemoteIpAddress;
            entry.Endpoint  = request.Uri.AbsolutePath.ToLowerInvariant();
            entry.ClientKey = request.Headers.Keys.Contains("Authorization-Token")
                ? request.Headers.GetValues("Authorization-Token").First()
                : "anon";

            return(entry);
        }
Пример #4
0
        public bool Match(RequestIdentity request)
        {
            if (!pathRegex.IsMatch(request.Endpoint))
            {
                return(false);
            }

            if (method != null && method != request.Method)
            {
                return(false);
            }

            return(true);
        }
Пример #5
0
 internal ThrottleLogEntry ComputeLogEntry(string requestId, RequestIdentity identity, ThrottleCounter throttleCounter, string rateLimitPeriod, long rateLimit, HttpRequestMessage request)
 {
     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,
         Request = request
     });
 }
Пример #6
0
 internal ThrottleLogEntry ComputeLogEntry(string requestId, RequestIdentity identity, ThrottleCounter throttleCounter, string rateLimitPeriod, long rateLimit, HttpRequestMessage request)
 {
     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,
         Request = request
     };
 }
Пример #7
0
        internal ThrottleCounter ProcessRequest(RequestIdentity requestIdentity, TimeSpan timeSpan, RateLimitPeriod period, long rateLimit, long suspendTime, out string id)
        {
            var throttleCounter = new ThrottleCounter()
            {
                Timestamp     = DateTime.UtcNow,
                TotalRequests = 1
            };

            id = ComputeThrottleKey(requestIdentity, period);

            TimeSpan suspendSpan = TimeSpan.FromSeconds(0);

            // serial reads and writes
            lock (ProcessLocker)
            {
                var entry = Repository.FirstOrDefault(id);
                if (entry.HasValue)
                {
                    var timeStamp = entry.Value.Timestamp;
                    if (entry.Value.TotalRequests >= rateLimit && suspendTime > 0)
                    {
                        timeSpan = GetSuspendSpanFromPeriod(period, timeSpan, suspendTime);
                    }

                    // 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     = timeStamp,
                            TotalRequests = totalRequests
                        };
                    }
                }

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

            return(throttleCounter);
        }
Пример #8
0
        internal 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.IndexOf(x.Key, 0, StringComparison.InvariantCultureIgnoreCase) != -1).ToList();
                //var rules = Policy.EndpointRules.Where(x => Regex.IsMatch(identity.Endpoint, x.Key, RegexOptions.IgnoreCase)).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;
                }
            }
        }
        internal 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 => x.Match(identity)).ToList();

                if (rules.Any())
                {
                    // get the lower limit from all applying rules
                    var customRate = (from r in rules let rateValue = r.limits.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;
                }
            }
        }
Пример #10
0
        internal 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.EndpointWithMethod.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;
                }
            }
        }
        internal 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.SHA1.Create())
            {
                hashBytes = algorithm.ComputeHash(idBytes);
            }

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

            return(hex);
        }
Пример #12
0
        internal 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 = Repository.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)
                Repository.Save(id, throttleCounter, timeSpan, requestIdentity.ClientKey);
            }

            return(throttleCounter);
        }
Пример #13
0
        protected virtual string ComputeThrottleKey(RequestIdentity requestIdentity, RateLimitPeriod period)
        {
            var keyValues = new List<string>()
                {
                    "throttle"
                };

            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);
            var hashBytes = new System.Security.Cryptography.SHA1Managed().ComputeHash(idBytes);
            var hex = BitConverter.ToString(hashBytes).Replace("-", "");
            return hex;
        }
Пример #14
0
        internal 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;
        }
Пример #15
0
 protected virtual string ComputeThrottleKey(RequestIdentity requestIdentity, RateLimitPeriod period)
 {
     return core.ComputeThrottleKey(requestIdentity, period);
 }
Пример #16
0
        protected virtual RequestIdentity SetIndentity(HttpRequestMessage request)
        {
            var entry = new RequestIdentity();
            entry.ClientIp = core.GetClientIp(request).ToString();
            entry.Endpoint = request.RequestUri.AbsolutePath.ToLowerInvariant();
            entry.ClientKey = request.Headers.Contains("Authorization-Token") ? request.Headers.GetValues("Authorization-Token").First() : "anon";

            return entry;
        }
Пример #17
0
        private 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 = Repository.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)
                Repository.Save(id, throttleCounter, timeSpan);
            }

            return throttleCounter;
        }
Пример #18
0
        internal bool IsEndpointMonitored(RequestIdentity identity)
        {
            var endpoints = Policy.Endpoints.Where(x => Regex.IsMatch(identity.Endpoint, x, RegexOptions.IgnoreCase)).ToList();

            return(endpoints.Any());
        }
Пример #19
0
        internal bool IsWhitelisted(RequestIdentity requestIdentity)
        {
            if (requestIdentity.ForceWhiteList)
            {
                return true;
            }

            if (Policy.IpThrottling)
            {
                if (Policy.IpWhitelist != null && ContainsIp(Policy.IpWhitelist, requestIdentity.ClientIp))
                {
                    return true;
                }
            }

            if (Policy.ClientThrottling)
            {
                if (Policy.ClientWhitelist != null && Policy.ClientWhitelist.Contains(requestIdentity.ClientKey))
                {
                    return true;
                }
            }

            if (Policy.EndpointThrottling)
            {
                if (Policy.EndpointWhitelist != null
                    && Policy.EndpointWhitelist.Any(x => requestIdentity.Endpoint.IndexOf(x, 0, StringComparison.InvariantCultureIgnoreCase) != -1))
                {
                    return true;
                }
            }

            return false;
        }
Пример #20
0
        internal 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)
            {
                if (Policy.EndpointThrottleMethod == EndpointThrottlingMethod.Action &&
                    !string.IsNullOrWhiteSpace(requestIdentity.ActionName) &&
                    !string.IsNullOrWhiteSpace(requestIdentity.ControllerName))
                {
                    //TODO: think of a better way to do this
                    keyValues.Add(requestIdentity.ControllerName + "." + requestIdentity.ActionName);
                }
                else if (Policy.EndpointThrottleMethod == EndpointThrottlingMethod.Url)
                {
                    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;
        }
Пример #21
0
        protected virtual RequestIdentity SetIndentity(IOwinRequest request)
        {
            var entry = new RequestIdentity();
            entry.ClientIp = request.RemoteIpAddress;
            entry.Endpoint = request.Uri.AbsolutePath.ToLowerInvariant();
            entry.ClientKey = request.Headers.Keys.Contains("Authorization-Token")
                ? request.Headers.GetValues("Authorization-Token").First()
                : "anon";

            return entry;
        }
Пример #22
0
        protected virtual RequestIdentity SetIndentity(HttpRequestMessage request)
        {
            var entry = new RequestIdentity();
            entry.ClientIp = core.GetClientIp(request).ToString();
            entry.Endpoint = request.RequestUri.AbsolutePath.ToLowerInvariant();
            entry.ClientKey = request.Headers.Contains("Authorization-Token") ? request.Headers.GetValues("Authorization-Token").First() : "anon";
            
            var actionDescriptor = request.GetActionDescriptor();
            if (actionDescriptor == null)
                return entry;

            entry.ActionName = actionDescriptor.ActionName;
            if(actionDescriptor.ControllerDescriptor != null)
                entry.ControllerName = actionDescriptor.ControllerDescriptor.ControllerName;

            return entry;
        }
Пример #23
0
 protected virtual string ComputeThrottleKey(RequestIdentity requestIdentity, RateLimitPeriod period)
 {
     return(core.ComputeThrottleKey(requestIdentity, period));
 }
Пример #24
0
        private bool IsWhitelisted(RequestIdentity requestIdentity)
        {
            if (Policy.IpThrottling)
                if (Policy.IpWhitelist != null && ContainsIp(Policy.IpWhitelist, requestIdentity.ClientIp))
                    return true;

            if (Policy.ClientThrottling)
                if (Policy.ClientWhitelist != null && Policy.ClientWhitelist.Contains(requestIdentity.ClientKey))
                    return true;

            if (Policy.EndpointThrottling)
                if (Policy.EndpointWhitelist != null && Policy.EndpointWhitelist.Any(x => requestIdentity.Endpoint.Contains(x)))
                    return true;

            return false;
        }