private ThrottleCounter ProcessRequest(RequestIdentity requestIdentity, TimeSpan timeSpan, RateLimitPeriod period, out string id) { var throttleCounter = new ThrottleCounter() { Timestamp = System.DateTime.UtcNow, TotalRequests = 1 }; id = ComputeThrottleKey(requestIdentity, period); //serial reads and writes lock (_processLocker) { var entry = Repository.FirstOrDefault(id); if (entry.HasValue) { //entry has not expired if (entry.Value.Timestamp + timeSpan >= System.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(id, throttleCounter, timeSpan); } return throttleCounter; }
private bool IsWhitelisted(RequestIdentity requestIdentity) { if (Policy.IpThrottling) if (Policy.IpWhitelist != null && ContainsIp(Policy.IpWhitelist, requestIdentity.ClientIp)) return true; if (Policy.ClientThrottling) if (Policy.ClientWhitelist != null && Policy.ClientWhitelist.Contains(requestIdentity.ClientKey)) return true; if (Policy.EndpointThrottling) if (Policy.EndpointWhitelist != null && Policy.EndpointWhitelist.Any(x => requestIdentity.Endpoint.Contains(x.ToLowerInvariant()))) return true; return false; }
protected virtual RequestIdentity SetIndentity(HttpRequestBase request) { var entry = new RequestIdentity(); entry.ClientIp = GetClientIp(request).ToString(); entry.ClientKey = request.IsAuthenticated ? "auth" : "anon"; var rd = request.RequestContext.RouteData; string currentAction = rd.GetRequiredString("action"); string currentController = rd.GetRequiredString("controller"); switch (Policy.EndpointType) { case EndpointThrottlingType.AbsolutePath: entry.Endpoint = request.Url.AbsolutePath; break; case EndpointThrottlingType.PathAndQuery: entry.Endpoint = request.Url.PathAndQuery; break; case EndpointThrottlingType.ControllerAndAction: entry.Endpoint = currentController + "/" + currentAction; break; case EndpointThrottlingType.Controller: entry.Endpoint = currentController; break; default: break; } //case insensitive routes entry.Endpoint = entry.Endpoint.ToLowerInvariant(); return entry; }
private ThrottleLogEntry ComputeLogEntry(string requestId, RequestIdentity identity, ThrottleCounter throttleCounter, string rateLimitPeriod, long rateLimit, HttpRequestBase request) { return new ThrottleLogEntry { ClientIp = identity.ClientIp, ClientKey = identity.ClientKey, Endpoint = identity.Endpoint, LogDate = System.DateTime.UtcNow, RateLimit = rateLimit, RateLimitPeriod = rateLimitPeriod, RequestId = requestId, StartPeriod = throttleCounter.Timestamp, TotalRequests = throttleCounter.TotalRequests, Request = request }; }
protected virtual string ComputeThrottleKey(RequestIdentity requestIdentity, RateLimitPeriod period) { var keyValues = new List<string>() { "throttle" }; if (Policy.IpThrottling) keyValues.Add(requestIdentity.ClientIp); if (Policy.ClientThrottling) keyValues.Add(requestIdentity.ClientKey); if (Policy.EndpointThrottling) keyValues.Add(requestIdentity.Endpoint); keyValues.Add(period.ToString()); var id = string.Join("_", keyValues); var idBytes = Encoding.UTF8.GetBytes(id); var hashBytes = new System.Security.Cryptography.SHA1Managed().ComputeHash(idBytes); var hex = BitConverter.ToString(hashBytes).Replace("-", ""); return hex; }