Forum Discussion

anuj_2931's avatar
anuj_2931
Icon for Nimbostratus rankNimbostratus
Jun 02, 2012

Trying to write an irule which inspects url parameters to select the appropriate pool

Hi Guys,

 

 

I have a Virtual server which will get http requests like this http://mysite.com/login?id=xyz-1, http:://mysite.com/login?id=xyz-2.

 

 

I want the iRule to inspect the parameters and if the last digit of the parameter id is 1 select pool 1. If it is 2 select pool 2. I also want the subsequent requests to be persistent.

 

 

Thanks for helping in advance.

 

  • is this applicable?

    [root@ve1024:Active] config  b virtual bar list
    virtual bar {
       snat automap
       destination 172.28.19.79:80
       ip protocol 6
       rules myrule
       persist cookie
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve1024:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST {
            if { [HTTP::query] ends_with "1" } {
                    pool foo1
            } elseif { [HTTP::query] ends_with "2" } {
                    pool foo2
            } else {
                    persist none
                    pool foo
            }
    }
    
    when SERVER_CONNECTED {
            log local0. "[IP::client_addr]:[TCP::client_port] -> [clientside {IP::local_addr}]:[clientside {TCP::local_port}] -> [IP::remote_addr]:[TCP::remote_port]"
    }
    }
    [root@ve1024:Active] config  b pool foo list
    pool foo {
       members 200.200.200.101:80 {}
    }
    [root@ve1024:Active] config  b pool foo1 list
    pool foo1 {
       members 200.200.200.101:80 {}
    }
    [root@ve1024:Active] config  b pool foo2 list
    pool foo2 {
       members 200.200.200.102:80 {}
    }
    
    [root@ve1024:Active] config  curl -I http://172.28.19.79/?test=xyz1
    HTTP/1.1 200 OK
    Date: Sat, 02 Jun 2012 15:22:29 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Fri, 11 Nov 2011 14:48:14 GMT
    ETag: "4183e4-3e-9c564780"
    Accept-Ranges: bytes
    Content-Length: 62
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: BIGipServerfoo1=1707657416.20480.0000; path=/
    
    /var/log/ltm
    Jun  2 08:22:09 local/tmm info tmm[4793]: Rule myrule : 172.28.19.80:52027 -> 172.28.19.79:80 -> 200.200.200.101:80
    
    [root@ve1024:Active] config  curl -I http://172.28.19.79/?test=xyz2
    HTTP/1.1 200 OK
    Date: Sat, 02 Jun 2012 15:12:53 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Tue, 08 Nov 2011 12:26:29 GMT
    ETag: "4183f1-30-47e02740"
    Accept-Ranges: bytes
    Content-Length: 48
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: BIGipServerfoo2=1724434632.20480.0000; path=/
    
    /var/log/ltm
    Jun  2 08:22:36 local/tmm info tmm[4793]: Rule myrule : 172.28.19.80:57225 -> 172.28.19.79:80 -> 200.200.200.102:80
    
    [root@ve1024:Active] config  curl -I http://172.28.19.79/?test=xyz3
    HTTP/1.1 200 OK
    Date: Sat, 02 Jun 2012 15:23:17 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Fri, 11 Nov 2011 14:48:14 GMT
    ETag: "4183e4-3e-9c564780"
    Accept-Ranges: bytes
    Content-Length: 62
    Content-Type: text/html; charset=UTF-8
    
    /var/log/ltm
    Jun  2 08:22:57 local/tmm info tmm[4793]: Rule myrule : 172.28.19.80:57226 -> 172.28.19.79:80 -> 200.200.200.101:80
    
  • Thanks for such a quick response. This is great help. Now if I remember right, to use cookie persistence where the pools foo1 and foo2 have different members, I need to use oneconnect as well on the virtual server. Do you agree?

     

     

    Also what will be the difference in setting cookie after the parameter matches, instead of defining it at the virtual server definition?

     

     

    Thanks.
  • Now if I remember right, to use cookie persistence where the pools foo1 and foo2 have different members, I need to use oneconnect as well on the virtual server. Do you agree? are you talking about this one?

    sol9800: Using an iRule to load balance HTTP requests to multiple pools

    http://support.f5.com/kb/en-us/solutions/public/9000/800/sol9800.html

    well, i think using oneconnect is fine.

    Also what will be the difference in setting cookie after the parameter matches, instead of defining it at the virtual server definition? i got an error.

    [root@ve1024:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST {
            if { [HTTP::query] ends_with "1" } {
                    persist cookie
                    pool foo1
            } elseif { [HTTP::query] ends_with "2" } {
                    persist cookie
                    pool foo2
            } else {
                    pool foo
            }
    }
    
    when SERVER_CONNECTED {
            log local0. "[IP::client_addr]:[TCP::client_port] -> [clientside {IP::local_addr}]:[clientside {TCP::local_port}] -> [IP::remote_addr]:[TCP::remote_port]"
    }
    }
    [root@ve1024:Active] config  b virtual bar list
    virtual bar {
       snat automap
       destination 172.28.19.79:80
       ip protocol 6
       profiles {
          http {}
          tcp {}
       }
    }
    
    [root@ve1024:Active] config  b virtual bar rule myrule
    BIGpipe unknown operation error:
       01070372:3: Persistence mode (Cookie) called out in rule (myrule) requires a corresponding persistence profile for virtual server (bar).
    
  • You might want to check the specific parameter value to see if it ends in 0 or 1 instead of the full query string to be more exact. You can use [URI::query [HTTP::uri] id] to get the id parameter value.

     

     

    And if subsequent requests don't have that parameter set and you still want to persist clients to the prior pool, you will probably want to set a cookie to track when a pool selection has been made and then look for that cookie on requests without the id parameter.

     

     

    Here's a related example:

     

     

    https://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/50/aft/2158969/showtab/groupforums/Default.aspx2234700

     

     

    Aaron
  • Here's another example of selecting a pool *member* by query string parameter value:

     

     

    https://devcentral.f5.com/wiki/iRules.Select_pool_member_based_on_HTTP_query_string_parameter.ashx

     

     

    Aaron