Forum Discussion
devrick0_22143
Feb 18, 2010Nimbostratus
uri query question
I am new to irules and hoped someone could lend a hand. The idea behind the irule I am trying to write up is that when a request comes in, the irule pulls out a certain name=value pair and then routes that request using modulus.
Here is what I have so far.
when HTTP_REQUEST {
set baseip "10.1.1."
set baseoctet "25"
set basepool "app_pool_1"
set modulus "2"
log local0.info "URI: [URI::query [HTTP::uri] "rx"]"
set key [URI::query [HTTP::uri] "rx"]
if {$key != ""} {
set key [expr {$key % $modulus}]
set newoctet [expr {$baseoctet + $key}]
set memberip "$baseip$newoctet"
log local0.info "memberip: $memberip"
pool $basepool member $memberip:80
}
}
What I have found is that "rx" is not an exact match for a name. If the name is "trx" it will also match. It seems to be some sort of a regex. I have tried a few methods of regex, like "^rx", but none have limited the results to just "rx". If rx is found anywhere in the UI name values it is considered a match.
- The_BhattmanNimbostratus
- hooleylistCirrostratusThis 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]" }
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]" } }
- devrick0_22143NimbostratusThank you both for replying. I won't be able to run the loop evaluation due to the high volume of queries and name/value pairs we deal with in each query but I will test out the other methods and hopefully get one of those working without impacting performance.
- hooleylistCirrostratusI'd push F5 for a hotfix as the workarounds can be quite CPU intensive. If you get a CR for this, can you reply with it here so others can attach cases to it as well?
- hooleylistCirrostratusActually I needed to fix this for a customer and came up with a workaround using findstr (Click here).
when RULE_INIT { Find the value for the first instance of a parameter name of "aa" in the query string Test query string set query "aaa=111&aa=11&a=1&aa=22" Test query string set query "aa=11" The parameter name to get the value for set param_name aa Check if query string starts with the parameter name and =. Need to hardcode the length of the parameter name + 1 for findstr if {$query starts_with "$param_name="}{ log local0. "$param_name = [findstr $query "$param_name=" 3 &]" } else { Parameter wasn't at the start of the query string, so check for ¶m_name= in the query string Need to hardcode the length of the parameter name + 2 for findstr log local0. "$param_name = [findstr $query "&$param_name=" 4 &]" } log local0. "Incorrect value from URI::query: $param_name = [URI::query ?$query $param_name]" }
- spark_86682Historic F5 AccountThis is a bug (CR137465). The problem is not that URI::query is doing a regex match, it's that it's essentially doing an "ends with" match, instead of the correct exact match.
Make the first param start with a "&" to make it like the others set uri [string replace [HTTP::uri] 0 0 "?&"] Note the "&" in front of paramname! set value [URI::query $uri ¶mname]
- hooleylistCirrostratusNice one, Spark. Thanks for the tip.
- JRahmAdminArgh...gotta fix that. Sorry guys, makes for some confusing output, doesn't it?
- devrick0_22143NimbostratusThanks to everyone for offering up alternate methods. I took some bits from the various methods and went this the approach below. We are evaluating its performance now.
when HTTP_REQUEST { set baseip 10.1.1. set baseoctet 25 set basepool app_pool_1 set modulus 2 set uri [string map {?rx ?XXX-rx &rx &XXX-rx} [HTTP::uri]] set key [URI::query $uri XXX-rx] if {$key != ""} { set maxkey [expr {$key + $modulus}] for { set i $key } { $i < $maxkey} { incr i } { set key [expr {$i % $modulus}] set newoctet [expr {$baseoctet + $key}] set memberip "$baseip$newoctet" log local0.info "uri: $uri" log local0.info "key: $key" log local0.info "memberip: $memberip" if { [LB::status pool $basepool member $memberip 80 ] eq "up" }{ pool $basepool member $memberip:80 return } } reject } }
- Thomas_SchaeferNimbostratus
Apparently, the bug where you needed to add ?& to the front or the URI and & to the front of the parameter searched for was being tracked through this thread. The ticket was CR137465. In the Wiki text for URI::query, it says this is fixed in v 11, but I tried this on 11.4 and had to still use the workaround syntax. Can anyone confirm if the bug was actually fixed on v11?
Thanks,
Tom
Recent Discussions
Related Content
Â
DevCentral Quicklinks
* 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
Discover DevCentral Connects