Forum Discussion

_pre_'s avatar
_pre_
Icon for Nimbostratus rankNimbostratus
Jul 06, 2011

Simplifying route irules

Is there anyway to simplify the following rules

 

 

 

 

 

Route traffic to server1 if URL listed in class_goto_server1

 

 

 

 

 

when HTTP_REQUEST {

 

set $HTTPuri [string tolower [HTTP::uri]]

 

 

URL starts_with check and Node select

 

if {[class match -name $HTTPuri starts_with class_toserver1_StartsWith]} {

 

pool server_1

 

}

 

URL equals check and Node select

 

if {[class match -name $HTTPuri equals class_toserver1_Equals]} {

 

pool server1

 

}

 

}

 

 

 

 

 

 

 

 

 

The content of the external class file:

 

 

 

- class_toserver1_StartsWith

 

/s/

 

/staff/

 

/tax/

 

 

 

- class_toserver1_Equals

 

/s

 

/staff

 

/tax

 

 

 

The list is quite long ( about 500 lines )

 

 

 

The reason we have these 2 class match is because we want /staff/ to go to server1, but staff-profile to go to default server .

 

Im thinking of having just 1 class file and do the matching programatically using iRules. Is this possible and how ?

 

 

 

 

 

 

 

 

 

  • Anything else I can think of would require looping through the datagroup element by element. I think what you've got is probably the most efficient even if it's a bit inelegant to have nearly duplicate entries in two separate datagroups.

    You should move the second lookup into an elseif clause to avoid doing a second lookup if the first one matched. Or you could put it in one if clause with an ||. But I think elseif might be a bit more legible.

    You could remove the -name option from both class commands as you're not doing anything with the matching element.

    
     Route traffic to server1 if URL listed in class_goto_server1
    when HTTP_REQUEST {
       set $HTTPuri [string tolower [HTTP::uri]]
        URL starts_with check and Node select 
       if {[class match $HTTPuri starts_with class_toserver1_StartsWith]} {
          pool server_1
       } elseif {[class match $HTTPuri equals class_toserver1_Equals]} {
          pool server1
       }
    }

    Aaron
  • _pre_'s avatar
    _pre_
    Icon for Nimbostratus rankNimbostratus
    Hoolio ! Thanks for the confirmation and code suggestions. It's comforting to hear that the code is the efficient (especially from you) :)

     

  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    Hm. I think you actually could do a bit better. How about something like:
    when HTTP_REQUEST {
    
       set HTTPuri "[string tolower [HTTP::uri]]/"
    
        URL starts_with check and Node select 
       if {[class match $HTTPuri starts_with class_toserver1_StartsWith]} {
          pool server_1
       }
    }
    
    Basically, always append a "/" character to the URI and then just do a "starts_with" search. If the URI is already "/staff-profile/" (or even "/staff-profile"), then that won't start with "/staff/", so it won't match that class entry. That way you're only doing one class lookup, and only have to maintain the one class. If all of your class entries are only one directory level deep, then you can do even better than that:
    when HTTP_REQUEST {
    
       set HTTPtopdir "/[getfield [string tolower [HTTP::uri]] "/" 2]/"
    
        top directory equals check and Node select 
       if {[class match $HTTPtopdir equals class_toserver1_equals]} {
          pool server_1
       }
    }
    
    That second example assumes the entries in class_toserver1_equals all end with slashes (meaning, "/staff/", and not "/staff").
  • Similar to spark's second snippet of code, if you are looking only one directory level deep you can do the following:

     

     

    when HTTP_REQUEST {

     

    set HTTPtopdir [lindex [split [string tolower [HTTP::uri]] /] 1]

     

    if {[class match $HTTPtopdir equals class_toserver1]}

     

    {

     

    pool server1

     

    }

     

    }

     

     

    This takes URI "/xxx/yyy/zzz" and sets HTTPtopdir to just "xxx". It then does a class match against a class looking to match "xxx".

     

     

    This would allow you to have a simpler class definition, such as:

     

    class class_toserver1 {

     

    {

     

    "s"

     

    "staff"

     

    "tax"

     

    }

     

    }

     

  • _pre_'s avatar
    _pre_
    Icon for Nimbostratus rankNimbostratus
    Thanks for the reply guys, but unfortunately I need to have "equals" lookup as well as starts_with and directory level varied from 1 to 6.

     

     

  • Your classes are rather short.. For readability and a bit better performance you may want to check out the "switch" command.

     

     

    http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/129/iRules-101--04--Switch.aspx