Advertisement
Guest User

Untitled

a guest
Jan 25th, 2015
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.23 KB | None | 0 0
  1. public class ThrottlePlugin : IPlugin
  2. {
  3. /// <param name="redisHost">host name</param>
  4. /// <param name="redisPort">port</param>
  5. /// <param name="redisPassword">password</param>
  6. public ThrottlePlugin(string redisHost, int redisPort, string redisPassword = null)
  7. {
  8. _redisClient = new RedisClient(redisHost, redisPort, redisPassword);
  9. }
  10.  
  11. private string _scriptSha;
  12. private RedisClient _redisClient;
  13. private Dictionary<Type, ThrottleInfoAttribute> _throttleInfoMap = new Dictionary<Type, ThrottleInfoAttribute>();
  14.  
  15. public void Register(IAppHost appHost)
  16. {
  17. RegisterThrottleInfoForAllRoutes(appHost);
  18.  
  19. //Store the lua script in redis for quick ref during request lookups
  20. _redisClient.RemoveAllLuaScripts();
  21. _scriptSha = _redisClient.LoadLuaScript(ReadLuaScriptResource("rate_limit.lua"));
  22.  
  23. appHost.GlobalRequestFilters.Add((request, response, requestDto) =>
  24. {
  25. //this request isn't setup to be throttled
  26. if (!_throttleInfoMap.ContainsKey(requestDto.GetType()))
  27. return;
  28.  
  29. var throttleInfo = _throttleInfoMap[requestDto.GetType()];
  30. var key = string.Format("{0}:{1}", request.RemoteIp, request.OperationName);
  31.  
  32. try
  33. {
  34. var result = _redisClient.ExecLuaShaAsString(_scriptSha,
  35. new[] {key},
  36. new[]
  37. {
  38. throttleInfo.PerMinute.ToString(),
  39. throttleInfo.PerHour.ToString(),
  40. throttleInfo.PerDay.ToString(),
  41. SecondsFromUnixTime().ToString()
  42. }
  43. );
  44. if (result != null)
  45. {
  46. response.StatusCode = 429;
  47. response.StatusDescription = "Too many Requests. Back-off and try again later.";
  48. response.Close();
  49. }
  50. }
  51. catch (Exception ex)
  52. {
  53. //got an error calling redis so log something and let the redis through
  54. }
  55. });
  56. }
  57.  
  58. private void RegisterThrottleInfoForAllRoutes(IAppHost appHost)
  59. {
  60. //pre calculate all request throttling attributes to reduce lookup time during a request
  61. foreach (var operation in appHost.Metadata.Operations)
  62. {
  63. var throttleAttribute = operation.RequestType.GetCustomAttributes(typeof(ThrottleInfoAttribute)).First() as ThrottleInfoAttribute;
  64. if (throttleAttribute == null)
  65. continue;
  66.  
  67. _throttleInfoMap.Add(operation.RequestType, throttleAttribute);
  68. }
  69. }
  70.  
  71. private int SecondsFromUnixTime()
  72. {
  73. TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
  74. return (int)t.TotalSeconds;
  75. }
  76.  
  77. private string ReadLuaScriptResource(string resourceName)
  78. {
  79. var assembly = Assembly.GetExecutingAssembly();
  80. var script = string.Empty;
  81.  
  82. using (Stream stream = assembly.GetManifestResourceStream("Throttling." + resourceName))
  83. using (StreamReader reader = new StreamReader(stream))
  84. {
  85. script = reader.ReadToEnd();
  86. }
  87.  
  88. return script;
  89. }
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement