Forum Discussion
Deb_Allen_18
Apr 12, 2006Historic F5 Account
Your problem is a bit different than Zape's.
He wanted to limit concurrent sessions.
You're looking for a request rate limit.
There is now a timeout function in the session table, and I've requested a way to count session table entries by filter, so once we have that, both his request and yours will be considerably easier to address.
In the meantime, I recently created this rule for a customer who needed to limit the number of POSTs by the same client within a specified time window. You'll probably want to change the 401 and 503 responses to redirects, but it just so happens we also used a header to differentiate clients. This was developed for a low volume application, so I can make no representations as to performance under load, but this should be very close to what you're looking for:
when RULE_INIT {
set ::maxRate 10
set ::windowSecs 10
init array if non-existent
array set ::postHistory { }
wipe array if it already existed
array unset ::postHistory
}
when HTTP_REQUEST {
if { [HTTP::method] eq "POST" } {
if {[HTTP::header exists User]} {
set myUserID [HTTP::header User]
} else {
HTTP::respond 401
return
}
set currentTime [clock seconds]
set windowStart [expr {$currentTime - $::windowSecs}]
find POSTs for this userID
set postCount 0
foreach { requestID requestTime } [array get ::postHistory ${myUserID}*] {
count POSTs with start time > $windowStart, delete the rest
if { $requestTime > $windowStart } {
incr postCount 1
} else {
unset ::postHistory($requestID)
}
}
if { $postCount < $::maxRate } {
add new record to array w/myUserID.uniquekey + currentTime
set requestID "${myUserID}.[substr [AES::key 128] 10 16]"
set ::postHistory($requestID) $currentTime
} else {
otherwise rate is exceeded, respond with 503 (temp unavail)
HTTP::respond 503
return
}
}
}
HTH
/deb