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)));
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
            }
        }