Forum Discussion

wtwagon_99154's avatar
wtwagon_99154
Icon for Nimbostratus rankNimbostratus
Apr 21, 2011

Looking to direct users to a server based upon URI

I'm an iRules and coding rookie, but I am trying to complete the following:

 

 

User will try to hit:

 

 

http://www.x.com/httm_TTT.xml.gz

 

 

Where the TTT can be one of the following:

 

 

Server A: 111, 254, 115, 114, 860, 103

 

Server B: 101, 219, 104, 759, 102, 725

 

Server C: 107, C27, 119, C28, D01, 633

 

 

If the link is http://www.x.com/httm_111.xml.gz, send to server A

 

If the link is http://www.x.com/httm_219.xml.gz, send to server B

 

If the link is http://www.x.com/httm_107.xml.gz, send to server C

 

 

I figured the best way to accomplish this would be creating a class with those string values in it.

 

 

I created two string classes called qml01 and qml02 (third server isn' t available yet), and put the string in each (and nothing for value)

 

 

I then created an iRule to do the following:

 

 

when HTTP_REQUEST {

 

if { [matchclass [HTTP::uri] contains $..qml01] } {

 

log local

 

pool qml01.80

 

} elseif { [matchclass [HTTP::uri] contains $..qml02] } {

 

pool qml02.80

 

}

 

}

 

 

I was expecting the iRule to look at the class for a number, i.e. 111, and redirect to server one. However, I think I am off in my way of thinking a bit - as it didn't appear to work.

 

 

Log output is as follows:

 

 

TCL error: xxx Invalid matchclass operands - no class or list type found, this: string, rhs: $..qml01 (line 1) invoked from within "matchclass [HTTP::uri] contains $..qml01

 

 

Wanted to see if someone could point me in the right direction on completing my iRule. I appreciate the help.

 

 

 

  • Since you're not doing too many matches against the data, why not use switch instead?

    when HTTP_REQUEST {
     set default_pool [LB::server pool]
     if { [string tolower [HTTP::uri]] starts_with "/httm_" } {
      switch [string tolower [string range $test 6 8] ] {
       "111" -
       "254" -
       "115" -
       "114" -
       "860" -
       "103" {
         pool qml01.80
       }
       "101" -
       "219" -
       "104" -
       "759" -
       "102" -
       "725" {
         pool qml02.80
       } 
       "107" -
       "c27" -
       "119" -
       "c28" -
       "d01" -
       "633" {
         pool qml03.80
       }
       default {
         pool $default_pool
       }
      }
     } else {
      pool $default_pool
     }
    }
    This will switch pools based on the 3 characters in URIs that begin with "/httm_" while setting to the default pool for everything else.
  • Thanks.

     

     

    Yes, I was looking at switch too just a moment ago.

     

     

    I ended up changing my iRule to this:

     

     

    when HTTP_REQUEST {

     

    if { [class match [HTTP::uri] contains "qml01"] } {

     

    log local

     

    pool qml01.80

     

    } elseif { [matchclass [HTTP::uri] contains "qml02"] } {

     

    pool qml02.80

     

    }

     

    }

     

     

    This rule also appears to be working - looks like I had some syntax errors.
  • Thanks.

     

     

    Yes, I was looking at switch too just a moment ago.

     

     

    I ended up changing my iRule to this:

     

     

    when HTTP_REQUEST {

     

    if { [class match [HTTP::uri] contains "qml01"] } {

     

    log local

     

    pool qml01.80

     

    } elseif { [matchclass [HTTP::uri] contains "qml02"] } {

     

    pool qml02.80

     

    }

     

    }

     

     

    This rule also appears to be working - looks like I had some syntax errors.
  • Hi WT,

     

     

    matchclass is used to check if a string, digit or address/subnet is part of a datagroup. It shouldn't be used to check one string against another.

     

     

    I suggest either using Joel's switch example, or a standard string comparison to do this instead. Joel's example should be the simplest to maintain if and when the URIs need to be updated.

     

     

    Aaron