Exemplo n.º 1
0
        /// <summary>
        /// Asynchronous processing of Middleware
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            var checkResult = await _algorithm.CheckAsync(context);

            if (checkResult.IsLimit)
            {
                context.Response.StatusCode = _error.HttpStatusCode;

                Dictionary <string, StringValues> headers = null;
                if (_error.BuildHttpHeadersAsync != null)
                {
                    headers = await _error.BuildHttpHeadersAsync(context, checkResult).ConfigureAwait(false);
                }
                else if (_error.BuildHttpHeaders != null)
                {
                    headers = _error.BuildHttpHeaders(context, checkResult);
                }

                if (headers != null && headers.Count > 0)
                {
                    foreach (var h in headers)
                    {
                        context.Response.Headers.Append(h.Key, h.Value);
                    }
                }

                string content = null;
                if (_error.BuildHttpContentAsync != null)
                {
                    content = await _error.BuildHttpContentAsync(context, checkResult).ConfigureAwait(false);
                }
                else if (_error.BuildHttpContent != null)
                {
                    content = _error.BuildHttpContent(context, checkResult);
                }

                if (!string.IsNullOrWhiteSpace(content))
                {
                    var bodyContent = Encoding.UTF8.GetBytes(content);
                    await context.Response.Body.WriteAsync(bodyContent, 0, bodyContent.Length).ConfigureAwait(false);
                }
                else
                {
                    await context.Response.WriteAsync(string.Empty).ConfigureAwait(false);
                }
            }
            else
            {
                // Simulation leaky bucket algorithm queuing mechanism
                var wait = checkResult.RuleCheckResults.Max(d => d.Wait);
                if (wait > 0)
                {
                    await Task.Delay((int)wait);
                }

                await _next(context);
            }
        }
        /// <summary>
        /// Asynchronous processing of Middleware
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            await DoOnBeforeCheck(context, _algorithm).ConfigureAwait(false);

            var checkResult = await _algorithm.CheckAsync(context);

            await DoOnAfterCheck(context, checkResult).ConfigureAwait(false);

            if (checkResult.IsLimit)
            {
                await DoOnTriggered(context, checkResult).ConfigureAwait(false);

                context.Response.StatusCode = _error.HttpStatusCode;

                var headers = await BuildHttpHeaders(context, checkResult).ConfigureAwait(false);

                if (headers != null && headers.Count > 0)
                {
                    foreach (var h in headers)
                    {
                        context.Response.Headers.Append(h.Key, h.Value);
                    }
                }

                string content = await BuildHttpContent(context, checkResult).ConfigureAwait(false);

                if (!string.IsNullOrWhiteSpace(content))
                {
                    var bodyContent = Encoding.UTF8.GetBytes(content);
                    await context.Response.Body.WriteAsync(bodyContent, 0, bodyContent.Length).ConfigureAwait(false);
                }
                else
                {
                    await context.Response.WriteAsync(string.Empty).ConfigureAwait(false);
                }
            }
            else
            {
                await DoOnBreforUntriggeredDoNext(context, checkResult).ConfigureAwait(false);

                if (checkResult.RuleCheckResults.Any())
                {
                    await DoLeakyBucketWait(checkResult).ConfigureAwait(false);
                }

                //Debug.WriteLine("R-Count" + checkResult.RuleCheckResults.First().Count + " " + DateTimeOffset.Now.ToString("mm:ss.fff"));
                await _next(context);

                await DoOnAfterUntriggeredDoNext(context, checkResult).ConfigureAwait(false);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Asynchronous processing of Middleware
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            #region check whether need RateLimit  and local Attribute is prority then other rules

            string methodCacheName     = ContextMethodNameHandler(context);
            var    requestNeedRateLimt = await RequestNeedRateLimitAsync(context, methodCacheName);

            if (!requestNeedRateLimt.Item1)
            {
                return;
            }
            EnableRateLimitAttribute enableRateLimitAttribute = requestNeedRateLimt.Item2;
            #endregion check whether need RateLimit  and local Attribute is prority then other rules

            //local method attribute
            var getMethodAttrRateLimitData = GetRateLimitTypeAttributeData(context);

            // context.Items.Add("PollyRequire", _specialRule != null ? _specialRule.EnablePolly : false);
            await DoOnBeforeCheck(context, _algorithm).ConfigureAwait(false);

            AlgorithmCheckResult checkResult;//= await _algorithm.CheckAsync(context);

            #region Polly

            bool enablePolly = enableRateLimitAttribute == null ? (_specialRule != null ? _specialRule.EnablePolly : false) : enableRateLimitAttribute.EnablePolly;
            if (enablePolly)
            {
                checkResult = await PollyRateLimitAdvancedCircuitBreakerAsync(context.Request.Path.Value, enableRateLimitAttribute)
                              .ExecuteAsync(async() =>
                {
                    return(await _algorithm.CheckAsync(context, getMethodAttrRateLimitData));
                });
            }
            else
            {
                checkResult = await _algorithm.CheckAsync(context, getMethodAttrRateLimitData);
            }

            #endregion Polly

            await DoOnAfterCheck(context, checkResult).ConfigureAwait(false);

            if (checkResult.IsLimit)
            {
                if (checkResult.RuleCheckResults != null && checkResult.RuleCheckResults.Any())
                {
                    var checkException = checkResult.RuleCheckResults.FirstOrDefault(x => x.RateLimitExceptionThrow == true);
                    if (checkException != null)
                    {
                        throw new RateLimitException(methodCacheName);
                    }
                }
                await DoOnTriggered(context, checkResult).ConfigureAwait(false);

                context.Response.StatusCode = _error.HttpStatusCode;
                await SetHeaders(context, checkResult).ConfigureAwait(false);
                await ReponseWithTooManyRequests(context, checkResult).ConfigureAwait(false);
            }
            else
            {
                await DoOnBreforUntriggeredDoNext(context, checkResult).ConfigureAwait(false);

                await DoLeakyBucketWait(checkResult).ConfigureAwait(false);

                //Debug.WriteLine("R-Count" + checkResult.RuleCheckResults.First().Count + " " + DateTimeOffset.Now.ToString("mm:ss.fff"));
                await _next(context);

                await DoOnAfterUntriggeredDoNext(context, checkResult).ConfigureAwait(false);
            }
        }