Forum Discussion

radhakrishnan_7's avatar
radhakrishnan_7
Icon for Nimbostratus rankNimbostratus
Jun 26, 2008

Query:iRule to limit the number of requests clients can make within a certain amount of time

Hi All,

 

 

In the following iRule,

 

 

http://devcentral.f5.com/wiki/default.aspx/iRules/HTTPRequestThrottle.html

 

-----------------------------------------------------

 

profile stats Request_Limit_Stats {

 

defaults from stats

 

field1 throttled_dropped_requests

 

field2 blacklisted_dropped_requests

 

field3 throttled_clients

 

field4 unthrottled_clients

 

}

 

 

class RequestLimit_Blacklist {

 

host 192.168.2.1

 

host 192.168.2.2

 

host 192.168.2.3

 

}

 

class RequestLimit_Whitelist {

 

host 192.168.1.1

 

host 192.168.1.2

 

host 192.168.1.3

 

}

 

 

when RULE_INIT {

 

Expiration for tracking IPs not yet throttled (seconds)

 

set ::standard_expiration_time 300

 

Expiration for tracking throttled clients

 

set ::throttled_expiration_time 3600

 

Throttle clients that exceed this number of requests/min

 

set ::throttle_activate_rate 30

 

Once throttled, limit clients to this number of requests/min

 

set ::throttle_limit_rate 5

 

Limit blacklisted clients to this number of requests/min

 

set ::blacklist_limit_rate 2

 

Message to be displayed when requests are dropped

 

set ::drop_msg "Too many requests, please try again later."

 

}

 

 

when HTTP_REQUEST {

 

HTTP::header insert "X-RequestLimit-Class" "normal"

 

set client_ip [IP::remote_addr]

 

if {[matchclass [IP::remote_addr] equals $::RequestLimit_Whitelist]} {

 

HTTP::header replace "X-RequestLimit-Class" "whitelisted"

 

} else {

 

set curr_time [clock seconds]

 

set blacklisted 0

 

set throttle_timekey throttle_starttime_$client_ip

 

set throttle_reqkey throttle_reqcount_$client_ip

 

set throttle_request_count [session lookup uie $throttle_reqkey]

 

if {[matchclass [IP::remote_addr] equals $::RequestLimit_Blacklist]} {

 

set blacklisted 1

 

if {$throttle_request_count <= 0} {

 

session add uie $throttle_timekey [expr {$curr_time - 2}] \

 

[expr {$::throttled_expiration_time + 2}]

 

set throttle_request_count 1

 

}

 

}

 

if {$throttle_request_count > 0} {

 

set throttle_start_time [session lookup uie $throttle_timekey]

 

incr throttle_request_count

 

session add uie $throttle_reqkey $throttle_request_count $::throttled_expiration_time

 

set elapsed_time [expr {$curr_time - $throttle_start_time}]

 

if {$elapsed_time < 60} {

 

set elapsed_time 60

 

}

 

set curr_rate [expr {$throttle_request_count / ($elapsed_time/60)} ]

 

if {$blacklisted} {

 

HTTP::header replace "X-RequestLimit-Class" "blacklisted"

 

set limit_rate $::blacklist_limit_rate

 

} else {

 

HTTP::header replace "X-RequestLimit-Class" "throttled"

 

set limit_rate $::throttle_limit_rate

 

}

 

if {$curr_rate > $limit_rate} {

 

Throttle this request

 

HTTP::respond 500 content $::drop_msg

 

}

 

} else {

 

if {([HTTP::uri] contains "RemoteAdvancedSearchView") \

 

or ([HTTP::uri] contains "CatalogSearchResultView")} {

 

set timekey starttime_$client_ip

 

set reqkey reqcount_$client_ip

 

set request_count [session lookup uie $reqkey]

 

if {$request_count > 0} {

 

set start_time [session lookup uie $timekey]

 

incr request_count

 

session add uie $reqkey $request_count $::standard_expiration_time

 

set elapsed_time [expr {$curr_time - $start_time}]

 

if {$elapsed_time < 60} {

 

set elapsed_time 60

 

}

 

set curr_rate [expr {$request_count / ($elapsed_time / 60)}]

 

if {$curr_rate >= $::throttle_activate_rate} {

 

Throttle this client after this request (add them to throttle list)

 

session add uie $throttle_timekey $start_time \

 

[expr {$::throttled_expiration_time + 2}]

 

session add uie $throttle_reqkey $request_count $::throttled_expiration_time

 

log local0. "RequestLimit: !THROTTLED! $client_ip: rate=$curr_rate, \

 

request_count=$request_count, elapsed_time=$elapsed_time"

 

}

 

} else {

 

Add tracking sessions for new client IP

 

session add uie $timekey $curr_time [expr {$::standard_expiration_time + 2}]

 

session add uie $reqkey 1 $::standard_expiration_time

 

}

 

}

 

}

 

}

 

}

 

 

 

------------------------------------------------

 

The below mentioned part is not reached in any method,

 

if {$blacklisted} {

 

HTTP::header replace "X-RequestLimit-Class" "blacklisted"

 

set limit_rate $::blacklist_limit_rate

 

} else {

 

HTTP::header replace "X-RequestLimit-Class" "throttled"

 

set limit_rate $::throttle_limit_rate

 

}

 

 

 

Please let me know If any changes are required in this iRule or IS there any possible way for testing this part of the iRule.

 

 

Thanks and Regards,

 

Radhakrishnan G
No RepliesBe the first to reply