HTTP Rate Limiting - CMP Compatible

Problem this snippet solves:

This iRule is a CMP compatible Request per Second Throttling iRule.

Code :

when HTTP_REQUEST {

set debug 1
set expiration_time 300
set client_ip [IP::client_addr]
set req_limit 200
set curr_time [clock seconds]
set timekey starttime
set reqkey reqcount
set request_count [session lookup uie $reqkey]

if {$debug}{log local0. "Request Count: $request_count"}

#Sets up new count for first time connections. If not a new connection, connection count is incremented and the iRule checks to 
#see if over the threshold
if { $request_count eq "" } {
if {$debug}{log local0. "Request Count is 0"}
set request_count 1
session add uie $reqkey $request_count $expiration_time
if {$debug}{log local0. "Current Time: $curr_time"}
if {$debug}{log local0. "Timekey Value: $timekey"}
if {$debug}{log local0. "Reqkey value: $reqkey"}
session add uie $timekey [expr {$curr_time - 2}] [expr {$expiration_time + 2}]
if {$debug}{log local0. "Request Count is now: $request_count"}
} else {
set start_time [session lookup uie $timekey]
if {$debug}{log local0. "Start Time: $start_time"}
if {$debug}{log local0. "Request Count (beyond first request): $request_count"}
incr request_count
session add uie $reqkey $request_count $expiration_time
set elapsed_time [expr {$curr_time - $start_time}]
if {$debug}{log local0. "Elapsed Time: $elapsed_time"}

if {$elapsed_time < 60} {
set elapsed_time 60
}

set curr_rate [expr {$request_count / ($elapsed_time/60)}]
if {$debug}{log local0. "Current Rate of Request: $curr_rate"}

if {$curr_rate > $req_limit}{
if {$debug}{log local0.warn "Request Blocked: $client_ipClient over Threshold.[HTTP::request]"}
HTTP::redirect http://www.company.com/sorry.html
}
}
}
Published Jan 30, 2015
Version 1.0