public void RequiresThrottling( IPipelines pipelines, ThrottlingProperties propertiesSet, ThrottlingPeriod period, int requestCountLimit, Func <NancyContext, bool> checkIf = null, Func <NancyContext, bool> skipIf = null, params string[] requestKeys) { pipelines.BeforeRequest.AddItemToStartOfPipeline( ctx => CheckThrottlingLimitHook(ctx, propertiesSet, period, requestCountLimit, checkIf: checkIf, skipIf: skipIf, requestKeys: requestKeys)); }
public void RequiresThrottling( INancyModule module, ThrottlingProperties propertiesSet, ThrottlingPeriod period, int requestCountLimit, Func <NancyContext, bool> checkIf = null, Func <NancyContext, bool> skipIf = null, params string[] requestKeys) { module.AddBeforeHookOrExecute( ctx => CheckThrottlingLimitHook(ctx, propertiesSet, period, requestCountLimit, checkIf: checkIf, skipIf: skipIf, requestKeys: requestKeys), "RequiresThrottling"); }
private static string BuildRequestKey( ThrottlingProperties propertiesSet, ThrottlingPeriod period, NancyContext context, params string[] requestKeys) { using (var ms = new MemoryStream()) using (var sw = new StreamWriter(ms, Encoding.UTF8)) { if (propertiesSet.HasFlag(ThrottlingProperties.RemoteIp)) { sw.Write(context.GetClientHost()); } if (propertiesSet.HasFlag(ThrottlingProperties.Method)) { sw.Write(context.Request.Method); } if (propertiesSet.HasFlag(ThrottlingProperties.Path)) { sw.Write(context.Request.Path); } sw.Write(period); if (requestKeys != null) { foreach (var key in requestKeys) { sw.Write(key); } } sw.Flush(); ms.Position = 0; using (var algorithm = new SHA1Managed()) { var hash = algorithm.ComputeHash(ms); return(Convert.ToBase64String(hash)); } } }
private Response CheckThrottlingLimitHook( NancyContext context, ThrottlingProperties propertiesSet, ThrottlingPeriod period, int requestCountLimit, Func <NancyContext, bool> checkIf = null, Func <NancyContext, bool> skipIf = null, params string[] requestKeys) { if (checkIf != null && !checkIf(context)) { return(null); } if (skipIf != null && skipIf(context)) { return(null); } var key = BuildRequestKey(propertiesSet, period, context, requestKeys); var expirationTime = CalculateExpirationTime(period); var counterValue = IncrementCounter(key, expirationTime); if (IsLimitExceeded(requestCountLimit, counterValue)) { if (IsNeedToLog(requestCountLimit, counterValue)) { logger.Error($"Flood detected ({counterValue} in {period.ToString()} allowed {requestCountLimit})" + $" on path: {context?.Request?.Path}" + $" ip: {context?.GetClientHost()}"); } return(new Response { StatusCode = HttpStatusCode.TooManyRequests }); } return(null); }