/// <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); } }
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); }
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); }); }
/// <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; } }
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(); } } }
/// <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); }