Forum Discussion
Use of getfield in iRule
Hi all,
I'm using iRules to implement some rate limiting based on a custom HTTP header our users insert into each request.
The relevant bits in the iRule are as follows: if { [HTTP::header exists Authorization] } { set limiter [getfield [HTTP::header Authorization] " " 2 ] set methodCount [table key -count -subtable [IP::client_addr]:$limiter]
The header looks like this:
Authorization: ID biglongstring-usedforauthtoken
The iRule works if the user sends the Token biglongstring-usedforauthtoken with one white space between the two fields. However, it breaks if there are two or more white spaces. Our spec says to use one whitespace, but you can never be sure with users/
Is there a better way to scan and split that header such that I get only the token back and use it ? I've tried a few things, to no avail and am almost at wits end....
Thanks for any advice.
3 Replies
Hi Eblakely,
you may use one of the commands below to extract your Authorization data.
Example 1: Serach the position of the first
character, then skip directly after the found position and take the remaining string.whitespaceset limiter [findstr [HTTP::header value Authorization] " " 1 end]Example 2: Same as Example 1 but with additional removal of any additional
.whitespacesset limiter [join [findstr [HTTP::header value Authorization] " " 1 end] ""]Cheers, Kai
- Eblakely_225577
Nimbostratus
And one more problem .... for which I am just stumped:
The full iRule I have is thus:
when RULE_INIT { set static::maxRate 10 set static::timeout 1 } when HTTP_REQUEST { if { ([HTTP::uri] starts_with "/v3") } { log local0. "You are here: step 1"
if { [HTTP::header exists Authorization] } { log local0. "You are here: step 2" set limiter [join [findstr [HTTP::header value Authorization] " " 1 end] ""] log local0. "You are here: step 3 => got auth token => $limiter" set methodCount [table key -count -subtable [IP::client_addr]:$limiter] log local0. "You are here: step 4 => Count = $methodCount / $limiter" } else { set limiter "[TCP::client_port]" log local0. "You are here: Step 5: Limiter Set to: [TCP::client_port] for [IP::client_addr]" set methodCount [table key -count -subtable [IP::client_addr]:$limiter] log local0. "You are here: step 6 => Count = $methodCount / $limiter" } if { $methodCount < $static::maxRate } { incr methodCount 1 log local0. "You are here: step 7 Adding entry for [IP::client_addr]" table incr -notouch -subtable [IP::client_addr]:$limiter [clock clicks] "1" indef $static::timeout } else { log local0. "[IP::client_addr] with limiter $limiter blocked" HTTP::respond 429 content "Request blocked - Requests per second exceeded." Access-Control-Allow-Origin "*" return } }}
I get the following error in the logs and I for the life of me cannot figure out what is wrong:
- wrong args: should be "table incr -notouch -subtable 172.20.0.84:{f027f673812eb228d7b86a86601fc166-6f0a04ed3ef4722012ab8245f538abe8} 1480534505883002 1 indef 1 (extra args supplied)" while executing "table incr -notouch -subtable [IP::client_addr]:$limiter [clock clicks] "1" indef $static::timeout"
Help. Anyone !!! Please.
The goal of this irule is to rate limit on the IP::authtoken. If that fails then filter on the IP:remote_port
A client is allowed 120 HTTP requests per second. If I remove the "1" indef $static::timeout portion of the table incr command then it "works" , sort of. It will hit 120 connections and drop everything after the 120th connection, as it is not properly expiring the connection table.The [clock clicks] "1" indef $static::timeout works in another irule so I am not sure what is wrong here.
I'd appreciate any help or assistance.
Thank you.
Hi Eblakely,
To resolve your problem, you can simply change
to[table incr ...]
.[table set ...]This change will cause your iRule to create a unique
key based on the current-subtable
with the value 1. This change does not have any impact on the[clock]
command, since this command will just care about unique keys in a given[table key -count -subtable]
and don't care about the key values.-subtableNote: The difference of
and[table incr]
in your case is, that[table set]
supports additional parameters to handle timeouts and lifetimes.[table set]Cheers, Kai
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com