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));
            }
        }
Beispiel #2
0
        public void Cacheable_response_created_using_local()
        {
            //Arrange
            var fakeResponse = new FakeResponse();

            //Act
            var cacheableResponse = new CacheableResponse(fakeResponse, expirationDate);

            //Assert
            Assert.NotNull(cacheableResponse);
            Assert.Equal(fakeResponse.ContentType, cacheableResponse.ContentType);
            Assert.Equal(fakeResponse.Headers, cacheableResponse.Headers);
            Assert.Equal(fakeResponse.StatusCode, cacheableResponse.StatusCode);
            Assert.Equal(expirationDate.ToUniversalTime(), cacheableResponse.Expiration);
            Assert.Equal(fakeResponse.GetContents(), cacheableResponse.Contents.ConvertStream());
        }
        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));
        }