public async Task <RateLimitPolicy> GetPolicyAsync(RateLimitingRequest rateLimitingRequest) { var clientId = rateLimitingRequest.ClaimsPrincipal?.Claims.FirstOrDefault(c => c.Type == "client_id"); if (string.IsNullOrWhiteSpace(clientId?.Value)) { return(null); } return(await Task.FromResult(new RateLimitPolicy(clientId.Value, allowAttributeOverride : true))); }
public async Task <RateLimitPolicy> GetPolicyAsync(RateLimitingRequest rateLimitingRequest) { if (IsWhiteListedPath(rateLimitingRequest.RouteTemplate) || IsWhiteListedPath(rateLimitingRequest.Path)) { return(null); } var providedPolicyEntry = await _policyProvider.GetPolicyAsync(rateLimitingRequest).ConfigureAwait(false); if (providedPolicyEntry == null || IsWhiteListedRequestKey(providedPolicyEntry.RequestKey)) { return(null); } if (providedPolicyEntry.AllowedCallRates != null && providedPolicyEntry.AllowedCallRates.Any()) { return(providedPolicyEntry); } var policyKey = new RateLimitingPolicyKey(providedPolicyEntry.RequestKey, rateLimitingRequest.RouteTemplate, rateLimitingRequest.Method); if (!_entries.ContainsKey(policyKey)) { policyKey = new RateLimitingPolicyKey(providedPolicyEntry.RequestKey, rateLimitingRequest.RouteTemplate, AllHttpMethods); } if (!_entries.ContainsKey(policyKey)) { policyKey = new RateLimitingPolicyKey(providedPolicyEntry.RequestKey, AllRequestPaths, rateLimitingRequest.Method); } if (!_entries.ContainsKey(policyKey)) { policyKey = new RateLimitingPolicyKey(providedPolicyEntry.RequestKey, AllRequestPaths, AllHttpMethods); } if (!_entries.ContainsKey(policyKey)) { policyKey = new RateLimitingPolicyKey(AllRequestKeys, rateLimitingRequest.RouteTemplate, rateLimitingRequest.Method); } if (!_entries.ContainsKey(policyKey)) { policyKey = new RateLimitingPolicyKey(AllRequestKeys, rateLimitingRequest.RouteTemplate, AllHttpMethods); } if (!_entries.ContainsKey(policyKey)) { policyKey = AllRequestsByHttpMethodKeyMapping[rateLimitingRequest.Method.ToUpperInvariant()]; } if (!_entries.ContainsKey(policyKey)) { policyKey = AllRequestsKey; } return(_entries.ContainsKey(policyKey) ? new RateLimitPolicy(providedPolicyEntry.RequestKey, _entries[policyKey].RouteTemplate, _entries[policyKey].HttpMethod, _entries[policyKey].AllowedCallRates, _entries[policyKey].AllowAttributeOverride, _entries[policyKey].Name) : null); }
public async Task LimitRequestAsync( RateLimitingRequest rateLimitingRequest, Func <IList <AllowedConsumptionRate> > getCustomAttributes, string host, Func <RateLimitingRequest, RateLimitPolicy, RateLimitingResult, Task> onPostLimitFuncAsync = null, Func <RateLimitingRequest, Task <RateLimitPolicy> > getPolicyFuncAsync = null, bool revert = false) { if (_policyProvider == null && getPolicyFuncAsync == null) { throw new ArgumentNullException("There are no valid policy providers"); } var getPolicyAsync = getPolicyFuncAsync ?? _policyProvider.GetPolicyAsync; var rateLimitingPolicy = await getPolicyAsync(rateLimitingRequest).ConfigureAwait(false); if (rateLimitingPolicy == null) { if (onPostLimitFuncAsync != null) { await onPostLimitFuncAsync.Invoke(rateLimitingRequest, rateLimitingPolicy, new RateLimitingResult(ResultState.NotApplicable)).ConfigureAwait(false); } return; } var allowedCallRates = rateLimitingPolicy.AllowedCallRates; var routeTemplate = rateLimitingPolicy.RouteTemplate; var httpMethod = rateLimitingPolicy.HttpMethod; var policyName = rateLimitingPolicy.Name; if (rateLimitingPolicy.AllowAttributeOverride) { var attributeRates = getCustomAttributes?.Invoke(); if (attributeRates != null && attributeRates.Any()) { allowedCallRates = attributeRates; routeTemplate = rateLimitingRequest.RouteTemplate; httpMethod = rateLimitingRequest.Method; policyName = $"AttributeOn_{routeTemplate}"; } } if (allowedCallRates == null || !Enumerable.Any <AllowedConsumptionRate>(allowedCallRates)) { if (onPostLimitFuncAsync != null) { await onPostLimitFuncAsync.Invoke(rateLimitingRequest, rateLimitingPolicy, new RateLimitingResult(ResultState.NotApplicable)).ConfigureAwait(false); } return; } var rateLimitingResult = await _rateLimitingCacheProvider.LimitRequestAsync(rateLimitingPolicy.RequestKey, httpMethod, host, routeTemplate, allowedCallRates, revert? -rateLimitingPolicy.CostPerCall : rateLimitingPolicy.CostPerCall).ConfigureAwait(false); if (onPostLimitFuncAsync != null) { await onPostLimitFuncAsync.Invoke(rateLimitingRequest, rateLimitingPolicy, rateLimitingResult).ConfigureAwait(false); } }