/// <summary>
 /// Saves the specified identifier.
 /// </summary>
 /// <param name="id">The identifier.</param>
 /// <param name="throttleCounter">The throttle counter.</param>
 /// <param name="expirationTime">The expiration time.</param>
 public void Save(string id, ThrottleCounter throttleCounter, TimeSpan expirationTime)
 {
     if (_chelper.ReadFromCache(id) != null)
     {
         _chelper.PutObjectOnCache(throttleCounter, id);
     }
 }
Beispiel #2
0
        public async Task <ThrottleCounter> GetAsync(string key, ThrottleRequirement requirement)
        {
            if (requirement == null)
            {
                throw new ArgumentNullException(nameof(requirement));
            }

            Connect();

            ThrottleCounter counter;
            var             entry = await _database.StringGetWithExpiryAsync(key);

            if (entry.Value.IsNull)
            {
                counter = new ThrottleCounter(_clock.UtcNow.Add(requirement.RenewalPeriod));
            }
            else
            {
                long value        = (long)entry.Value;
                bool limitReached = value >= requirement.MaxValue;
                counter = new ThrottleCounter(_clock.UtcNow.Add(entry.Expiry.Value), value, limitReached);
            }

            return(counter);
        }
Beispiel #3
0
        public void Save(string id, ThrottleCounter throttleCounter, TimeSpan expirationTime)
        {
            var entry = new ThrottleCounterWrapper
            {
                ExpirationTime = expirationTime,
                Timestamp      = throttleCounter.Timestamp,
                TotalRequests  = throttleCounter.TotalRequests
            };

            _cache.Add(id, entry);
        }
        public void Save(string id, ThrottleCounter throttleCounter, TimeSpan expirationTime)
        {
            var a = new CacheItem <object>(id, _regionName, throttleCounter, ExpirationMode.Absolute, expirationTime);

            _cache.AddOrUpdate(a, (item) =>
            {
                var counter           = (ThrottleCounter)item;
                counter.Timestamp     = throttleCounter.Timestamp;
                counter.TotalRequests = throttleCounter.TotalRequests;
                return(counter);
            });
        }
Beispiel #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="id"></param>
 /// <param name="throttleCounter"></param>
 /// <param name="expirationTime"></param>
 public void Save(string id, ThrottleCounter throttleCounter, TimeSpan expirationTime)
 {
     try
     {
         if (!CatchStatus)
         {
             RedisHelper.Set(MergeKey(id), throttleCounter, expirationTime);
         }
     }
     catch
     {
         CatchStatus = true;
     }
 }
Beispiel #6
0
        public void Save(string id, ThrottleCounter throttleCounter, TimeSpan expirationTime, string clientKey)
        {
            using (var sqlConnection = new SqlConnection(_connectionString))
            {
                using (var sqlCommand = new SqlCommand(Sql.Save, sqlConnection))
                {
                    sqlCommand.Parameters.AddWithValue("@id", id);
                    sqlCommand.Parameters.AddWithValue("@timestamp", throttleCounter.Timestamp);
                    sqlCommand.Parameters.AddWithValue("@totalrequests", throttleCounter.TotalRequests);
                    sqlCommand.Parameters.AddWithValue("@ExpirationTime", expirationTime.Ticks);
                    sqlCommand.Parameters.AddWithValue("@clientKey", clientKey);

                    sqlConnection.Open();

                    sqlCommand.ExecuteScalar();
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// To apply policy, check limit & restrict user.
        /// </summary>
        /// <param name="actionContext">Request context</param>
        /// <param name="policyList">List of throttle policies</param>
        /// <param name="IdentityKey">Key like emailId, IP address etc.</param>
        private void ApplyAndCheckPolicy(HttpActionContext actionContext, List <Policy> policyList, string IdentityKey)
        {
            foreach (Policy item in policyList)
            {
                var key          = ThrottlingHelper.ComputeCounterKey(IdentityKey, item);
                var allowExecute = false;
                item.PeriodTimespan = ThrottlingHelper.ConvertToTimeSpan(item.period);

                var throttleCounter = new ThrottleCounter()
                {
                    Timestamp     = DateTime.UtcNow,
                    TotalRequests = 1
                };
                lock (ProcessLocker)
                {
                    var entry = (ThrottleCounter?)HttpRuntime.Cache[key];
                    if (entry.HasValue)
                    {
                        // entry has not expired
                        if (entry.Value.Timestamp + item.PeriodTimespan >= DateTime.UtcNow)
                        {
                            // increment request count
                            var totalRequests = entry.Value.TotalRequests + 1;

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

                    if (HttpRuntime.Cache[key] != null)
                    {
                        HttpRuntime.Cache[key] = throttleCounter;
                    }
                    else
                    {
                        HttpRuntime.Cache.Add(
                            key,
                            throttleCounter,
                            null,
                            Cache.NoAbsoluteExpiration,
                            item.PeriodTimespan,
                            CacheItemPriority.Low,
                            null);
                        allowExecute = true;
                    }
                    if (throttleCounter.TotalRequests > item.limit)
                    {
                        allowExecute = false;
                    }
                    else
                    {
                        allowExecute = true;
                    }

                    if (!allowExecute)
                    {
                        actionContext.Response = actionContext.Request.CreateResponse(
                            (HttpStatusCode)429,
                            string.Format("API calls quota exceeded!")
                            );
                        actionContext.Response.Headers.Add("Retry-After", RetryAfterFrom(throttleCounter.Timestamp, item));
                        Trace.TraceError(string.Format(Environment.NewLine + "Request {0} from IpAddress:{1} clientKey:{2} has been throttled (blocked), quota {3}/{4} exceeded by {5}"
                                                       , actionContext.Request.RequestUri.AbsoluteUri
                                                       , requestIdentity.ipAddress
                                                       , requestIdentity.clientKey
                                                       , item.limit
                                                       , item.period
                                                       , throttleCounter.TotalRequests));
                    }
                }
            }
        }
 public override void AddRateLimitHeaders(ThrottleCounter counter, ThrottleContext throttleContext, AuthenticatedUserRateLimitRequirement requirement)
 {
     throttleContext.ResponseHeaders["X-RateLimit-UserLimit"]     = requirement.MaxValue.ToString(CultureInfo.InvariantCulture);
     throttleContext.ResponseHeaders["X-RateLimit-UserRemaining"] = counter.Remaining(requirement).ToString(CultureInfo.InvariantCulture);
     throttleContext.ResponseHeaders["X -RateLimit-UserReset"]    = counter.Reset.ToEpoch().ToString(CultureInfo.InvariantCulture);
 }
 public override void AddRateLimitHeaders(ThrottleCounter counter, ThrottleContext throttleContext, IPRateLimitRequirement requirement)
 {
     throttleContext.ResponseHeaders["X-RateLimit-IPLimit"]     = requirement.MaxValue.ToString();
     throttleContext.ResponseHeaders["X-RateLimit-IPRemaining"] = counter.Remaining(requirement).ToString();
 }
 public override void AddRateLimitHeaders(ThrottleCounter counter, ThrottleContext throttleContext, ApiKeyRateLimitRequirement requirement)
 {
     throttleContext.ResponseHeaders["X-RateLimit-ClientLimit"]     = requirement.MaxValue.ToString(CultureInfo.InvariantCulture);
     throttleContext.ResponseHeaders["X-RateLimit-ClientRemaining"] = counter.Remaining(requirement).ToString(CultureInfo.InvariantCulture);
 }