Click here to Skip to main content
Licence CPOL
First Posted 27 Sep 2005
Views 36,150
Bookmarked 39 times

Use a floodgate class to block multiple posts

By | 27 Sep 2005 | Article
A simple class to block repeated attempts to submit comments or logins.

Introduction

Here's something that I'd like to share with you. I was developing a website and wanted to limit the number of operations per second that a client is allowed to post. For example, if a visitor posts a comment within 10 seconds of his previous post, it's very unlikely that the post contributed by the person is something useful. Most probably, that post was somehow automated.

Solution

The class that I have written is actually very simple to use. For example if you have an event handler that implements the post of a comment, your code may look something like this:

private void Submit_click(object sender, EventArgs args)
{
    if(Page.IsValid)
    {
        //Your code to persist the details in the database.
    }
}

Now, to add our flood gate, change the code so that it looks something like this:

private static FloodGate _submitFlooding;

private void Submit_click(object sender, EventArgs args)
{
    if(Page.IsValid)
    {
         if(_submitFlooding == null)
    {
         _submitFlooding = new FloodGate("Post Comment", 
                                    TimeSpan.FromSeconds(10))
    }
     _submitFlooding.Assert();
 
    //Your code to persist the details in the database.
    }
}

First, I declare a static reference to a FloodGate class. This makes sure that my floodgate is kept in memory across all the requests that are made to this application.

When somebody clicks on the Submit button, an instance of a FloodGate is assigned. It takes two parameters: the name of the gate, and the minimum delay between each operation.

Whenever somebody (with a certain client IP address) clicks the button within 10 seconds, a FloodGateException is thrown, thereby effectively aborting the operation.

To make it more user friendly, you can catch the exception and show a message box.

The code

It works as follows:

  1. The class maintains a Hashtable of client IP's.
  2. Whenever the Assert() method is called, a check is performed to see if the current client IP (by using HttpContext.Current.Request.UserHostAddress) is already on the list.
  3. If it is, the Hashtable entries contain the DateTime of the last operation. If that date is no longer than n seconds apart (configured by the constructor), a FloodGateException is thrown.
  4. If it isn't (or sufficient time has elapsed), the Hashtable is updated.

If you're interested in seeing the entire code, it is available for download at the top of the page.

The cool thing about this solution is that it is easily reusable in both code-behind and business classes, and that you can declare multiple floodgates for different operations. One of the downsides is that a reference to System.Web is required.

Improvements

The first thing that comes to mind: Clean up IP addresses that have dates older than the minimum waiting time. This will save precious memory.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rob van der Veer

Web Developer

Netherlands Netherlands

Member

Rob has been a professional web developer since 1998, and is working with C# and ASP.Net since early 2002.
 
Most of the time, his focus is on creating a clean and simple solution to development problems. (Although that sometimes means that he needs to do some hard work to make somebody else's life more easier.).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionWhat about multiple users thru a shared ip address? Pinmemberdavid wendelken9:54 19 Nov '07  
AnswerRe: What about multiple users thru a shared ip address? PinmemberRob van der Veer2:50 20 Nov '07  
Generalthanks Pinmembervanderven0:05 13 Apr '07  
GeneralRe: thanks PinmemberRob van der Veer11:21 3 May '07  
GeneralNice PinmemberClickok4:36 18 Jan '07  
GeneralRe: Nice PinmemberRob van der Veer5:47 4 Mar '09  
GeneralWhat's the best way to handle the exception PinmemberGordon Moore10:23 26 Nov '05  
GeneralRe: What's the best way to handle the exception PinmemberRob van der Veer2:30 27 Nov '05  
GeneralRe: What's the best way to handle the exception PinmemberGordon Moore3:38 27 Nov '05  
GeneralRe: What's the best way to handle the exception PinmemberGordon Moore3:48 27 Nov '05  
GeneralRe: What's the best way to handle the exception PinmemberGordon Moore4:04 27 Nov '05  
GeneralRe: What's the best way to handle the exception PinmemberGordon Moore4:51 27 Nov '05  
GeneralRe: What's the best way to handle the exception PinmemberGordon Moore23:21 3 Dec '05  
GeneralRe: What's the best way to handle the exception PinmemberSkpananghat22:54 3 Mar '09  
GeneralRe: What's the best way to handle the exception PinmemberSkpananghat23:04 3 Mar '09  
GeneralLink doesn't work PinmemberWCK20:37 6 Oct '05  
GeneralRe: Link doesn't work PinmemberRob van der Veer10:10 9 Oct '05  
GeneralRe: Link doesn't work PinmemberRob van der Veer11:33 13 Oct '05  
GeneralRe: Link doesn't work Pinmemberj c dinaker19:21 30 May '07  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 27 Sep 2005
Article Copyright 2005 by Rob van der Veer
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid