示例#1
0
        private async Task <bool> RevertIfRequired(RateLimitingResult rateLimitingResult, HttpActionContext context,
                                                   RateLimitingRequest request, RateLimitPolicy policy, Decision decision)
        {
            if (decision == Decision.REVERTSUCCESSCOST && rateLimitingResult.State == ResultState.Success)
            {
                await _rateLimiter.LimitRequestAsync(request,
                                                     () => RateLimitingFilter.GetCustomAttributes(context),
                                                     context.Request.Headers.Host,
                                                     getPolicyFuncAsync : _ => Task.FromResult(policy),
                                                     onPostLimitFuncAsync : async(rateLimitingRequest, postPolicy, rateLimitingRevertResult) =>
                {
                    if (rateLimitingRevertResult.State == ResultState.Success)
                    {
                        context.Request.Properties[$"RateLimitingResult_{_filterId}"] = rateLimitingRevertResult;
                    }

                    if (OnPostLimitRevert != null)
                    {
                        await OnPostLimitRevert.Invoke(request, postPolicy, rateLimitingRevertResult, context).ConfigureAwait(false);
                    }
                },
                                                     revert : true).ConfigureAwait(false);

                return(await Task.FromResult(true));
            }

            return(await Task.FromResult(false));
        }
示例#2
0
        public List <RateLimitPolicy> GetPolicys()
        {
            var result = new List <RateLimitPolicy>();

            using (var connection = new MySqlConnection(_mySqlOptions.ConnectionString))
            {
                var sql   = @"SELECT * FROM `ratelimit_item` where Type=3 and Prefix=@Prefix;
                            SELECT t2.* From `ratelimit_item` t1 inner join `ratelimit_rule` t2 on t1.Id=t2.PolicyId where t1.Type=3 and t1.Prefix=@Prefix";
                var multi = connection.QueryMultiple(sql, new { Prefix = _options.RateLimitCounterPrefix });
                var items = multi.Read <Entities.RateLimitItem>();
                var rules = multi.Read <Entities.RateLimitRule>();
                if (items != null && items.AsList().Count > 0)
                {
                    foreach (var item in items.AsList())
                    {
                        var policy = new RateLimitPolicy();
                        policy.Prefix     = item.Prefix;
                        policy.PolicyType = (RateLimitPolicyType)item.PolicyType;
                        policy.Value      = item.Value;
                        policy.Rules      = new List <Models.RateLimitRule>();
                        rules.Where(x => x.PolicyId == item.Id).AsList().ForEach(x =>
                        {
                            policy.Rules.Add(new Models.RateLimitRule()
                            {
                                Endpoint = x.Endpoint,
                                Period   = x.Period,
                                Limit    = x.Limit
                            });
                        });
                        result.Add(policy);
                    }
                }
            }
            return(result);
        }
示例#3
0
        public RateLimitResult Process(ClientRequestIdentity clientRequestIdentity, RateLimitPolicy rateLimitPolicy, CancellationToken cancellationToken)
        {
            if (clientRequestIdentity == null)
            {
                throw new ArgumentNullException(nameof(clientRequestIdentity));
            }
            if (rateLimitPolicy == null)
            {
                return(RateLimitResult.NoLimit("no rate limit policy."));
            }
            if (rateLimitPolicy.ClientIsRequired && string.IsNullOrWhiteSpace(clientRequestIdentity.ClientId))
            {
                return(RateLimitResult.Limited("client id is required."));
            }
            if (rateLimitPolicy.IsWhitelisted(clientRequestIdentity, out RateLimitNameListPolicyMatchedResult result))
            {
                return(RateLimitResult.NoLimit(result.ToString()));
            }
            var matchedRules = rateLimitPolicy.GetMatchedRules(clientRequestIdentity);

            if (matchedRules != null && matchedRules.Any())
            {
                lock (o_lock)
                {
                    var rulesDict = new Dictionary <string, Tuple <RateLimitRule, RateLimitCounter> >();
                    foreach (var rule in matchedRules)
                    {
                        if (rule.Limit > 0)
                        {
                            var counterKey = ComputeCounterKey(rule);
                            var counter    = GetCounter(counterKey, rule);
                            // check if key expired
                            if (counter.Timestamp + rule.PeriodTimespan.Value < DateTime.UtcNow)
                            {
                                continue;
                            }
                            // check if limit is reached
                            if (counter.Count > rule.Limit)
                            {
                                return(RateLimitResult.Limited(rule.ToString()));
                            }
                            rulesDict.Add(counterKey, Tuple.Create(rule, counter));
                        }
                        else
                        {
                            return(RateLimitResult.Limited(rule.ToString()));
                        }
                    }
                    if (rulesDict.Any())
                    {
                        foreach (var item in rulesDict)
                        {
                            _rateLimitCounterHandler.Set(item.Key, item.Value.Item2, item.Value.Item1.PeriodTimespan.Value);
                        }
                    }
                }
            }

            return(RateLimitResult.Default);
        }
示例#4
0
        public BattleriteClient Build(string token)
        {
            if (rateLimitPolicy == default(IRateLimitPolicy))
            {
                rateLimitPolicy = new RateLimitPolicy();
            }

            var jsonSerializerSettings = new JsonApiSerializerSettings();

            var requestUrlBuilder = new RequestUrlBuilder(EndPoints.BaseUrl, new List <IParameter>());

            var httpClient = new HttpClient();

            SetupHttpClient(token, httpClient);

            var requester = new Requester.Requester(httpClient, rateLimitPolicy);

            return(CreateBattleriteClient(
                       CreateOrGetAssetClient(),
                       CreateOrGetPlayerClient(
                           jsonSerializerSettings,
                           requestUrlBuilder,
                           requester,
                           CreateOrGetAssetClient()),
                       CreateOrGetMatchClient(requestUrlBuilder, requester)));
        }
        public void ShouldParseFourPoliciesFromOptionsCorrectly()
        {
            var rateLimitingOptions = new RateLimitingOptions()
            {
                RateLimitPolicyStrings = new List <string>()
                {
                    "*:GET:api/globallylimited/{id}:5_PerMinute&8_PerHour:true:StaticPolicy_0",
                    "*:*:/api/globallylimited/{id}/sub/{subid}:2_PerMinute:true:StaticPolicy_1",
                    "*:*:*:100_PerMinute:true:StaticPolicy_2"
                },
                RateLimitPolicyOptions = new List <RateLimitingPolicyOptions>()
                {
                    new RateLimitingPolicyOptions()
                    {
                        RouteTemplate          = "api/globallylimited",
                        AllowAttributeOverride = true,
                        AllowedCallRates       = new Dictionary <string, int>()
                        {
                            { RateLimitUnit.PerMinute.ToString(), 3 }
                        },
                        HttpMethod = "POST",
                        Name       = "GlobalPostRate"
                    }
                }
            };

            var policies = rateLimitingOptions.RateLimitPolicies;

            var rateLimitPolicies = policies as RateLimitPolicy[] ?? policies.ToArray();

            Assert.Equal(4, rateLimitPolicies.Count());

            var policy0 = new RateLimitPolicy("*", "api/globallylimited/{id}", "GET", new List <AllowedConsumptionRate>()
            {
                new AllowedConsumptionRate(5, RateLimitUnit.PerMinute),
                new AllowedConsumptionRate(8, RateLimitUnit.PerHour)
            }, true, "StaticPolicy_0");

            var policy1 = new RateLimitPolicy("*", "/api/globallylimited/{id}/sub/{subid}", "*", new List <AllowedConsumptionRate>()
            {
                new AllowedConsumptionRate(2, RateLimitUnit.PerMinute)
            }, true, "StaticPolicy_1");

            var policy2 = new RateLimitPolicy("*", "*", "*", new List <AllowedConsumptionRate>()
            {
                new AllowedConsumptionRate(100, RateLimitUnit.PerMinute)
            }, true, "StaticPolicy_2");


            var policy3 = new RateLimitPolicy("*", "api/globallylimited", "POST", new List <AllowedConsumptionRate>()
            {
                new AllowedConsumptionRate(3, RateLimitUnit.PerMinute)
            }, true, "GlobalPostRate");

            Assert.Equal(true, ContainsPolicy(policy0, rateLimitPolicies));
        }
示例#6
0
        private static int GetThrottleCount(IRateLimitingCacheProvider rateLimiter,
                                            RateLimitPolicy policy,
                                            int totalNumberOfCalls,
                                            int sleepTimeInMilliSeconds)
        {
            int throttleCount = 0;

            for (var i = 1; i <= totalNumberOfCalls; i++)
            {
                if (rateLimiter.LimitRequestAsync(policy.RequestKey, policy.HttpMethod,
                                                  "TestRateLimiting.com", policy.RouteTemplate, policy.AllowedCallRates).Result.Throttled)
                {
                    throttleCount++;
                }

                Thread.Sleep(sleepTimeInMilliSeconds);
            }
            return(throttleCount);
        }
示例#7
0
        private static async Task <PoliciesValidationModel> GetPoliciesValidationModel(
            string folderPath,
            IEnumerable <CustomPolicy> customPolicies,
            RateLimitPolicy rateLimitPolicy)
        {
            var rateLimitPolicyToValidate = rateLimitPolicy == null
                ? null
                : new RateLimitPolicyValidationModel(rateLimitPolicy.Name, rateLimitPolicy.Calls, rateLimitPolicy.RenewalPeriod);

            var customPoliciesToValidate = customPolicies == null
                ? Enumerable.Empty <CustomPolicyValidationModel>()
                : await Task.WhenAll(customPolicies.Select(async cp =>
            {
                using var xmlFs = new FileStream(Path.Combine(folderPath, cp.XmlFile), FileMode.Open, FileAccess.Read);
                using var sr    = new StreamReader(xmlFs);
                return(new CustomPolicyValidationModel(cp.Name, await sr.ReadToEndAsync().ConfigureAwait(false)));
            })).ConfigureAwait(false);

            return(new PoliciesValidationModel(customPoliciesToValidate, rateLimitPolicyToValidate));
        }
 private static bool ContainsPolicy(RateLimitPolicy expectedPolicy, IEnumerable <RateLimitPolicy> policies)
 {
     return(policies.Any(policy =>
                         policy.Key.Equals(expectedPolicy.Key) && policy.AllowAttributeOverride == expectedPolicy.AllowAttributeOverride &&
                         policy.Name == expectedPolicy.Name && policy.AllowedCallRates.All(expectedPolicy.AllowedCallRates.Contains)));
 }
示例#9
0
        private async Task CreateOrUpdatePolicies(
            IGatewayClient client,
            Guid subscriptionId,
            Guid?entityId,
            string folderPath,
            PoliciesValidationResult policiesResults,
            string entityType,
            RateLimitPolicy rateLimitPolicy,
            IEnumerable <CustomPolicy> customPolicies)
        {
            if (entityId.HasValue)
            {
                if (rateLimitPolicy != null)
                {
                    var rateLimitPolicyRequest = new RateLimitPolicyRequest(
                        rateLimitPolicy.Name, entityId, entityType, rateLimitPolicy.Description, rateLimitPolicy.Calls, rateLimitPolicy.RenewalPeriod);
                    switch (policiesResults.RateLimitPolicy.Status)
                    {
                    case ValidationStatus.CanBeCreated:
                        var created = await client.CreateRateLimitPolicyAsync(subscriptionId, rateLimitPolicyRequest).ConfigureAwait(false);

                        this.publishResults.Add(new GatewayAutomationResult()
                        {
                            ResultCode = ResultCode.RateLimitPolicyCreated, EntityId = created.Id
                        });
                        break;

                    case ValidationStatus.CanBeUpdated:
                        var updated = await client.UpdateRateLimitPolicyAsync(subscriptionId, policiesResults.RateLimitPolicy.EntityId.Value, rateLimitPolicyRequest).ConfigureAwait(false);

                        this.publishResults.Add(new GatewayAutomationResult()
                        {
                            ResultCode = ResultCode.RateLimitPolicyUpdated, EntityId = updated.Id
                        });
                        break;

                    default:
                        throw new NotSupportedException("Unsupported RateLimitPolicy ValidationStatus in CreateOrUpdatePolicies");
                    }
                }

                if (customPolicies != null)
                {
                    foreach (var customPolicy in customPolicies)
                    {
                        var customPolicyResult = policiesResults.CustomPolicies.Single(cp => string.Equals(cp.Name, customPolicy.Name, StringComparison.OrdinalIgnoreCase));

                        using var sr = new StreamReader(Path.Combine(folderPath, customPolicy.XmlFile));
                        var xmlContent = await sr.ReadToEndAsync().ConfigureAwait(false);

                        var customPolicyRequest = new CustomPolicyRequest(customPolicy.Name, xmlContent, entityId, customPolicy.Description, entityType);
                        switch (customPolicyResult.Status)
                        {
                        case ValidationStatus.CanBeCreated:
                            var created = await client.CreateCustomPolicyAsync(subscriptionId, customPolicyRequest).ConfigureAwait(false);

                            this.publishResults.Add(new GatewayAutomationResult()
                            {
                                ResultCode = ResultCode.CustomPolicyCreated, EntityId = created.Id
                            });
                            break;

                        case ValidationStatus.CanBeUpdated:
                            var updated = await client.UpdateCustomPolicyAsync(subscriptionId, customPolicyResult.EntityId.Value, customPolicyRequest).ConfigureAwait(false);

                            this.publishResults.Add(new GatewayAutomationResult()
                            {
                                ResultCode = ResultCode.CustomPolicyUpdated, EntityId = updated.Id
                            });
                            break;

                        default:
                            throw new NotSupportedException("Unsupported CustomPolicy ValidationStatus in CreateOrUpdatePolicies");
                        }
                    }
                }
            }
        }
示例#10
0
 public BattleriteClientBuilder WithRateLimitPolicy(RateLimitPolicy rateLimitPolicy)
 {
     this.rateLimitPolicy = rateLimitPolicy;
     return(this);
 }