/// <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); } }