private bool ApplyThrottling(HttpActionContext actionContext, out IEnableThrottlingAttribute attr) { var applyThrottling = false; attr = null; var actionDescriptor = actionContext.ActionDescriptor; var controllerDescriptor = actionDescriptor.ControllerDescriptor; if (controllerDescriptor.GetCustomAttributes <EnableThrottlingAttribute>(true).Any()) { attr = controllerDescriptor.GetCustomAttributes <EnableThrottlingAttribute>(true).First(); applyThrottling = true; } if (actionDescriptor.GetCustomAttributes <EnableThrottlingAttribute>(true).Any()) { attr = actionDescriptor.GetCustomAttributes <EnableThrottlingAttribute>(true).First(); applyThrottling = true; } // explicit disabled if (actionDescriptor.GetCustomAttributes <DisableThrottingAttribute>(true).Any()) { applyThrottling = false; } return(applyThrottling); }
private bool ApplyThrottling(ActionExecutingContext filterContext, out IEnableThrottlingAttribute attr) { var applyThrottling = false; attr = null; if (filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(EnableThrottlingAttribute), true)) { attr = (EnableThrottlingAttribute)filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(EnableThrottlingAttribute), true).First(); applyThrottling = true; } if (filterContext.ActionDescriptor.IsDefined(typeof(EnableThrottlingAttribute), true)) { attr = (EnableThrottlingAttribute)filterContext.ActionDescriptor.GetCustomAttributes(typeof(EnableThrottlingAttribute), true).First(); applyThrottling = true; } //explicit disabled if (filterContext.ActionDescriptor.IsDefined(typeof(DisableThrottingAttribute), true)) { applyThrottling = false; } return(applyThrottling); }
public override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.IsChildAction == false) { IEnableThrottlingAttribute attrPolicy = null; var applyThrottling = ApplyThrottling(filterContext, out attrPolicy); if (applyThrottling) { var identity = GetIndentity(filterContext); var result = processer.Process(identity, attrPolicy); if (result.IsPass == false) { if (filterContext.HttpContext.Response.IsRequestBeingRedirected == false) { filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = result.StatusCode; filterContext.HttpContext.Response.Headers.Add("Retry-After", result.RetryAfter); filterContext.Result = new ContentResult { Content = result.Message }; } else { filterContext.HttpContext.Response.Write(result.Message); } return; } } } base.OnActionExecuting(filterContext); }
public ThrottleProcessResult Process(RequestIdentity identity, IEnableThrottlingAttribute attrPolicy = null) { Identity = identity; Policy = PolicyRepo.FirstOrDefault(ThrottleManager.GetPolicyKey()); if (Policy != null) { Checking(attrPolicy); } return(processResult); }
public override void OnActionExecuting(HttpActionContext actionContext) { var request = actionContext.Request; IEnableThrottlingAttribute attrPolicy = null; var applyThrottling = ApplyThrottling(actionContext, out attrPolicy); if (applyThrottling) { var identity = GetIndentity(actionContext); var result = processer.Process(identity, attrPolicy); if (result.IsPass == false) { // add status code and retry after x seconds to response var responseCode = (HttpStatusCode)result.StatusCode; var response = request.CreateResponse(responseCode, result.Content); response.Headers.Add("Retry-After", new string[] { result.RetryAfter }); actionContext.Response = response; } } base.OnActionExecuting(actionContext); }
private void Checking(IEnableThrottlingAttribute attrPolicy) { ThrottlingCore.ThrottleRepo = ThrottleRepo; ThrottlingCore.Policy = Policy; if (!Policy.IpThrottling && !Policy.ClientThrottling && !Policy.EndpointThrottling) { return; } if (ThrottlingCore.IsWhitelisted(Identity)) { return; } TimeSpan timeSpan = TimeSpan.FromSeconds(1); // get default rates var defRates = ThrottlingCore.RatesWithDefaults(Policy.Rates.ToList()); if (Policy.StackBlockedRequests) { // all requests including the rejected ones will stack in this order: week, day, hour, min, sec // if a client hits the hour limit then the minutes and seconds counters will expire and will eventually get erased from cache defRates.Reverse(); } // apply policy foreach (var rate in defRates) { var rateLimitPeriod = rate.Key; var rateLimit = rate.Value; timeSpan = ThrottlingCore.GetTimeSpanFromPeriod(rateLimitPeriod); if (attrPolicy != null) { // apply EnableThrottlingAttribute policy var attrLimit = attrPolicy.GetLimit(rateLimitPeriod); if (attrLimit > 0) { rateLimit = attrLimit; } } // apply global rules ThrottlingCore.ApplyRules(Identity, timeSpan, rateLimitPeriod, ref rateLimit); if (rateLimit == 0) { continue; } // increment counter string requestId; var throttleCounter = ThrottlingCore.ProcessRequest(Identity, timeSpan, rateLimitPeriod, out requestId); // check if key expired if (throttleCounter.Timestamp + timeSpan < DateTime.UtcNow) { continue; } // check if limit is reached if (throttleCounter.TotalRequests > rateLimit) { // log blocked request if (Logger != null) { var logEntry = ThrottlingCore.ComputeLogEntry(requestId, Identity, throttleCounter, rateLimitPeriod.ToString(), rateLimit); Logger.Log(logEntry); } var retryAfter = ThrottlingCore.RetryAfterFrom(throttleCounter.Timestamp, rateLimitPeriod); ProcessQuotaExceeded(rateLimitPeriod, rateLimit, retryAfter); return; } } }