This looks like a bug. For the following test, I'd expect three empty results followed by the actual value of the aaa parameter. Instead, all the "a, aa, aaa" parameter names return the value of the aaa parameter:
Tested on
when RULE_INIT {
set uri "/path/to/file.ext?aaa=111"
log local0. "\$uri: $uri"
log local0. "\[URI::query \$uri b\]: [URI::query $uri b]"
log local0. "\[URI::query \$uri a\]: [URI::query $uri a]"
log local0. "\[URI::query \$uri aa\]: [URI::query $uri aa]"
log local0. "\[URI::query \$uri aaa\]: [URI::query $uri aaa]"
}
: $uri: /path/to/file.ext?aaa=111
: [URI::query $uri b]:
: [URI::query $uri a]: 111 <--- ?? this should be null
: [URI::query $uri aa]: 111 <--- ?? this should be null
: [URI::query $uri aaa]: 111
I'd suggest opening a case with F5 Support. In the meantime, you could manually parse the query string in a loop or using a regex:
Loop through each parameter name looking for "param2" and log the name and value
set namevals [split [HTTP::query] "&"]
for {set i 0} {$i < [llength $namevals]} {incr i} {
set params [split [lindex $namevals $i] "="]
if {[lindex $params 0] eq "param2"}{
log local0. "Param: [lindex $params 0], Value: [lindex $params 1]"
}
}
In most regex flavors, you could use a lookbehind to match anything after the parameter name (param2 in this example):
(?<=(?:&|\?)param2=)[^&]*
Intead, you could use a combination of commands to get the parameter value (replace param2 with the actual parameter name):
Parse the value for the first "param2" parameter instance in the query string
set param_value [getfield [regexp -inline {(?:&|\?)param2=[^&]*} "?[HTTP::query]"] "=" 2]
I'm not sure which option would be more efficient. But I'd guess the loop might be more efficient for small numbers of parameters in the query string.
Aaron