public async Task InvokeAsync(HttpContext context, IRequestService reqService) { var client = await ClientIdentityHelper.ResolveIdentityAsync(context, _options); RequestLogRecord record = new RequestLogRecord { ClientId = client.ClientId, Timestamp = DateTime.UtcNow }; await reqService.StoreRequest(record); // Call the next delegate/middleware in the pipeline await _next(context); }
// IMyScopedService is injected into Invoke public async Task InvokeAsync(HttpContext context, IRateLimitService rateLimitService) { // check if rate limiting is enabled if (_options == null) { await _next.Invoke(context); return; } // compute identity from request var identity = await ClientIdentityHelper.ResolveIdentityAsync(context, _options); var currentTime = DateTime.UtcNow; // check if user is already requested var record = await rateLimitService.GetRateLimitRecordAsync(identity); if (record == null) { record = new RateLimitRecord { ClientId = identity.ClientId, Timestamp = currentTime } } ; // check if user is blocked if (record.isBlocked) { var blockTime = record.BlockedUntillTime - currentTime; if (blockTime.TotalSeconds > 0) { await ReturnQuotaExceededResponse(context, record.BlockedUntillTime); return; } else { //reset rateCounter record if time for block is run out await rateLimitService.ResetUserAsync(identity, context.RequestAborted); } } //find all rules eligibe for request IEnumerable <RateLimitRule> rules = await rateLimitService.GetMatchingRulesAsync(identity, context.RequestAborted); foreach (var rule in rules) { RateLimitRecord rateCounter = await rateLimitService.ProcessRequestAsync(record, rule, currentTime, context.RequestAborted); if (rule.Limit > 0) { // check if limit is reached if (rateCounter.Count > rule.Limit) { var blockedUser = await rateLimitService.BlockUserByRateLimitAsync(identity, rule); // break execution await ReturnQuotaExceededResponse(context, blockedUser.BlockedUntillTime); return; } } } // Call the next delegate/middleware in the pipeline await _next(context); }