private ThrottleCounter ProcessRequest(RequestIdentity requestIdentity, TimeSpan timeSpan, RateLimitPeriod period, out string id)
        {
            var throttleCounter = new ThrottleCounter()
            {
                Timestamp = System.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 >= System.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;
        }
        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.ToLowerInvariant())))
                    return true;

            return false;
        }
        protected virtual RequestIdentity SetIndentity(HttpRequestBase request)
        {
            var entry = new RequestIdentity();
            entry.ClientIp = GetClientIp(request).ToString();

            entry.ClientKey = request.IsAuthenticated ? "auth" : "anon";

            var rd = request.RequestContext.RouteData;
            string currentAction = rd.GetRequiredString("action");
            string currentController = rd.GetRequiredString("controller");

            switch (Policy.EndpointType)
            {
                case EndpointThrottlingType.AbsolutePath:
                    entry.Endpoint = request.Url.AbsolutePath;
                    break;
                case EndpointThrottlingType.PathAndQuery:
                    entry.Endpoint = request.Url.PathAndQuery;
                    break;
                case EndpointThrottlingType.ControllerAndAction:
                    entry.Endpoint = currentController + "/" + currentAction;
                    break;
                case EndpointThrottlingType.Controller:
                    entry.Endpoint = currentController;
                    break;
                default:
                    break;
            }

            //case insensitive routes
            entry.Endpoint = entry.Endpoint.ToLowerInvariant();

            return entry;
        }
 private ThrottleLogEntry ComputeLogEntry(string requestId, RequestIdentity identity, ThrottleCounter throttleCounter, string rateLimitPeriod, long rateLimit, HttpRequestBase request)
 {
     return new ThrottleLogEntry
     {
         ClientIp = identity.ClientIp,
         ClientKey = identity.ClientKey,
         Endpoint = identity.Endpoint,
         LogDate = System.DateTime.UtcNow,
         RateLimit = rateLimit,
         RateLimitPeriod = rateLimitPeriod,
         RequestId = requestId,
         StartPeriod = throttleCounter.Timestamp,
         TotalRequests = throttleCounter.TotalRequests,
         Request = request
     };
 }
        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;
        }