private ThrottleLogEntry ComputeLogEntry(string requestId, RequestIndentity identity, ThrottleCounter throttleCounter, string rateLimitPeriod, long rateLimit) { return new ThrottleLogEntry { ClientIp = identity.ClientIp, ClientKey = identity.ClientKey, Endpoint = identity.Endpoint, LogDate = DateTime.UtcNow, RateLimit = rateLimit, RateLimitPeriod = rateLimitPeriod, RequestId = requestId, StartPeriod = throttleCounter.Timestamp, TotalRequests = throttleCounter.TotalRequests }; }
private ThrottleCounter ProcessRequest(ThrottlePolicy throttlePolicy, RequestIndentity throttleEntry, TimeSpan timeSpan, RateLimitPeriod period, out string id) { var throttleCounter = new ThrottleCounter(); throttleCounter.Timestamp = DateTime.UtcNow; throttleCounter.TotalRequests = 1; //computed request unique id from IP, client key, url and period id = "throttle"; if (throttlePolicy.IpThrottling) { if (throttlePolicy.IpWhitelist != null && throttlePolicy.IpWhitelist.Contains(throttleEntry.ClientIp)) { return throttleCounter; } id += "_" + throttleEntry.ClientIp; } if (throttlePolicy.ClientThrottling) { if (throttlePolicy.ClientWhitelist != null && throttlePolicy.ClientWhitelist.Contains(throttleEntry.ClientKey)) { return throttleCounter; } id += "_" + throttleEntry.ClientKey; } if (throttlePolicy.EndpointThrottling) { if (throttlePolicy.EndpointWhitelist != null && Policy.EndpointWhitelist.Any(x => throttleEntry.Endpoint.Contains(x))) { return throttleCounter; } id += "_" + throttleEntry.Endpoint; } id += "_" + period; //get the hash value of the computed id var hashId = ComputeHash(id); //serial reads and writes lock (_processLocker) { var entry = Repository.FirstOrDefault(hashId); if (entry.HasValue) { //entry has not expired if (entry.Value.Timestamp + timeSpan >= DateTime.UtcNow) { //increment request count var totalRequests = entry.Value.TotalRequests + 1; //deep copy throttleCounter = new ThrottleCounter { Timestamp = entry.Value.Timestamp, TotalRequests = totalRequests }; } } //stores: id (string) - timestamp (datetime) - total (long) Repository.Save(hashId, throttleCounter, timeSpan); } return throttleCounter; }
protected virtual RequestIndentity SetIndentity(HttpRequestMessage request) { var entry = new RequestIndentity(); entry.ClientIp = GetClientIp(request).ToString(); entry.Endpoint = request.RequestUri.AbsolutePath; entry.ClientKey = request.Headers.Contains("Authorization-Token") ? request.Headers.GetValues("Authorization-Token").First() : "anon"; return entry; }