public override void OnActionExecuting(ActionExecutingContext actionExecutingContext) { LoadConfiguration(); if (!_isEnabled) { return; } var today = DateTime.UtcNow; HttpContext httpContext = actionExecutingContext.HttpContext; var connectionFeature = httpContext.Features.Get <IHttpConnectionFeature>(); var ipAddress = connectionFeature == null ? string.Empty : connectionFeature.RemoteIpAddress.ToString(); var actionName = actionExecutingContext.RouteData.Values["Action"].ToString(); var controllerName = actionExecutingContext.RouteData.Values["Controller"].ToString(); var record = new CacheableResponse { ActionName = actionName, ControllerName = controllerName, IpAdress = ipAddress }; var jsonResponse = record.GetIdentifier(); var cachedData = GetValue(jsonResponse); if (cachedData == null) { return; } var cacheableResponse = cachedData as CacheableResponse; if (cacheableResponse == null) { return; } var needToRefresh = cacheableResponse.UpdateDateTime.AddMinutes(SlidingTime) <= today; if (!needToRefresh && cacheableResponse.NumberOfRequests >= NumberOfRequests) { var numberOfRemainingRequests = 0; var timeResetTime = (cacheableResponse.UpdateDateTime.AddMinutes(SlidingTime) - today).TotalSeconds; var message = string.Format( RateLimitationConstants.ErrorMessage, NumberOfRequests.ToString(CultureInfo.InvariantCulture), SlidingTime.ToString(CultureInfo.InvariantCulture)); var headers = actionExecutingContext.HttpContext.Response.Headers; actionExecutingContext.Result = new ContentResult { StatusCode = 429, Content = message, ContentType = "text/plain" }; headers.Add(RateLimitationConstants.XRateLimitLimitName, NumberOfRequests.ToString(CultureInfo.InvariantCulture)); headers.Add(RateLimitationConstants.XRateLimitRemainingName, numberOfRemainingRequests.ToString(CultureInfo.InvariantCulture)); headers.Add(RateLimitationConstants.XRateLimitResetName, timeResetTime.ToString(CultureInfo.InvariantCulture)); } }
public override void OnActionExecuted(ActionExecutedContext httpActionExecutedContext) { LoadConfiguration(); if (!_isEnabled) { return; } var today = DateTime.UtcNow; var connectionFeature = httpActionExecutedContext.HttpContext.Features.Get <IHttpConnectionFeature>(); var ipAddress = connectionFeature == null ? string.Empty : connectionFeature.RemoteIpAddress.ToString(); var actionName = httpActionExecutedContext.RouteData.Values["Action"].ToString(); var controllerName = httpActionExecutedContext.RouteData.Values["Controller"].ToString(); var record = new CacheableResponse { ActionName = actionName, ControllerName = controllerName, IpAdress = ipAddress }; var jsonResponse = record.GetIdentifier(); var cachedData = GetValue(jsonResponse); // Add into the cache if (cachedData == null) { record.UpdateDateTime = today; record.NumberOfRequests = 1; SetValue(jsonResponse, record); } else { // Update the cache. record = cachedData as CacheableResponse; if (record == null) { return; } Remove(jsonResponse); var needToRefresh = record.UpdateDateTime.AddMinutes(SlidingTime) <= today; if (needToRefresh) { record.UpdateDateTime = today; record.NumberOfRequests = 1; } else { record.NumberOfRequests++; } SetValue(jsonResponse, record); } // Return the HTTP-HEADERS var numberOfRemainingRequests = NumberOfRequests - record.NumberOfRequests; if (numberOfRemainingRequests < 0) { numberOfRemainingRequests = 0; } var timeResetTime = (record.UpdateDateTime.AddMinutes(SlidingTime) - today).TotalSeconds; var response = httpActionExecutedContext.HttpContext.Response; if (response == null) { return; } response.Headers.Add(RateLimitationConstants.XRateLimitLimitName, NumberOfRequests.ToString(CultureInfo.InvariantCulture)); response.Headers.Add(RateLimitationConstants.XRateLimitRemainingName, numberOfRemainingRequests.ToString(CultureInfo.InvariantCulture)); response.Headers.Add(RateLimitationConstants.XRateLimitResetName, timeResetTime.ToString(CultureInfo.InvariantCulture)); }