Forum Discussion

Patrik_Jonsson's avatar
Nov 20, 2013

Throttle incoming requests per minute

Hi Guys! Trying to write an iRule that throttles incoming requests but I can't get this very simple example to work. Basically my problem seems to be that the global connections variable never is being reset.

Also, I'm not sure if I have to use a global variable in this case. The limit should only affect one particular VIP and the iRule is only used at this VIP.

Throttle number of requests per minute
when RULE_INIT {
    array set connections { }
        after 60000 -periodic {
            array set ::connections { }
        }
    }

when HTTP_REQUEST {
    if { [info exists ::connections([IP::client_addr])] } {
        if { [incr ::connections([IP::client_addr])] > 10 } {
            HTTP::respond 200 content "You have passed the request threshold of 10/minute."
            set blocked 1
        } 
    } else {
        set ::connections([IP::client_addr]) 1
        HTTP::respond 200 content "OK"
    }
}

Thankful for any advice!

Kind regards, Patrik

4 Replies

  • You should definitely use the "table" command to access the session table for this. The data expiration feature is made for this use-case. Look [here] (https://devcentral.f5.com/articles/v101-the-table-command-the-basics)

     

    Joanna

     

  • In case you don't have your answer yet, the 'table' is global which is one of the other reasons it's awesome.

     

  • Here's the sample rule I wrote to test the tables in case anyone else has the same issue.

    Throttle number of requests per minute
    when HTTP_REQUEST {
    
        table add [IP::client_addr] 1 indefinite 10
        if { [table incr [IP::client_addr]] > 4 } {
    
            HTTP::respond 200 content "Too many"
    
        } else {
            HTTP::respond 200 content "OK"
    
        }
    }
    
  • I don't think you need the "table add" statement. Just use "table incr" which will add key to the table with value 1 if it doesn't exist, and incr it by 1 if it does exist.