-
-
Save LSTANCZYK/25a1e5f4dbcb0a1795e6ba93d769343c to your computer and use it in GitHub Desktop.
How to throttle requests in a Web Api?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [Route("api/dothis/{id}")] | |
| [AcceptVerbs("POST")] | |
| [Throttle(Name = "ApiThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)] | |
| [Authorize] | |
| public HttpResponseMessage DoThis(int id) | |
| { | |
| // do something | |
| } | |
| public class ThrottleAttribute : ActionFilterAttribute | |
| { | |
| /// <summary> | |
| /// A unique name for this Throttle. | |
| /// </summary> | |
| /// <remarks> | |
| /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1" | |
| /// </remarks> | |
| public string Name { get; set; } | |
| /// <summary> | |
| /// The number of seconds clients must wait before executing this decorated route again. | |
| /// </summary> | |
| public int Seconds { get; set; } | |
| /// <summary> | |
| /// A text message that will be sent to the client upon throttling. You can include the token {n} to | |
| /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again". | |
| /// </summary> | |
| public string Message { get; set; } | |
| public override void OnActionExecuting(HttpActionContext actionContext) | |
| { | |
| var key = string.Concat(Name, "-", GetClientIp(actionContext.Request)); | |
| var allowExecute = false; | |
| if (HttpRuntime.Cache[key] == null) | |
| { | |
| HttpRuntime.Cache.Add(key, | |
| true, // is this the smallest data we can have? | |
| null, // no dependencies | |
| DateTime.Now.AddSeconds(Seconds), // absolute expiration | |
| Cache.NoSlidingExpiration, | |
| CacheItemPriority.Low, | |
| null); // no callback | |
| allowExecute = true; | |
| } | |
| if (!allowExecute) | |
| { | |
| if (string.IsNullOrEmpty(Message)) | |
| { | |
| Message = "You may only perform this action every {n} seconds."; | |
| } | |
| actionContext.Response = actionContext.Request.CreateResponse( | |
| HttpStatusCode.Conflict, | |
| Message.Replace("{n}", Seconds.ToString()) | |
| ); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment