Forum Discussion

Christian_Meiss's avatar
Christian_Meiss
Icon for Nimbostratus rankNimbostratus
Aug 01, 2016

I don't understand [class match ... nor [class search - pls help

Hi folks

i have a data group

 

path_dg{
    records {
        / {
            data /bar
        }
    }
    type string
}

 

I now try to get "/bar" if my HTTP::uri equals "/". but my irules behaves a little strange for me. I try:

 

set redirectrule [class match -value [HTTP::uri] starts_with path_dg]
set redirectrule [class search -value path_dg starts_with [HTTP:uri]]

 

But both returns /bar also if HTTP::uri contains /bar not only as expected if HTTP::uri is "/"

My intention is to only search in index. The string part.

What goes wrong?

Cheers

Christian

 

5 Replies

  • adityoari_14383's avatar
    adityoari_14383
    Historic F5 Account

    if I understand your requirement correctly, the behavior is expected since "/bar" does start with "/", i.e. when the code trace through the string "/bar" in the HTTP::uri, it sees that the string begins with a "/" and will match the variable with the data group

     

    • Christian_Meiss's avatar
      Christian_Meiss
      Icon for Nimbostratus rankNimbostratus

      Ok more accurate:

      i open http://host.domain.tld/ -> HTTP:uri equals /

       

          [class match -value "/" starts_with path_dg] should return /bar
      

       

      now i open http://host.domain.tld/bar -> HTTP:uri equals /bar

       

          [class match -value "/bar" starths_with path_dg] should return nothing
      

       

      But it's return also /bar.

      I thinke my data group is a key:value pair and "class match" only looks into keys for matchings.

    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP

      The problem can be found in the "starts_with" contition of the [class] command, since every [HTTP::path] will have a leading "/" and therefor always matches (at least) the datagroup entry of "/" and then resolves to "/bar".

       

      Cheers, Kai

       

  • Hi Christian,

    you may change the iRule to use...

    set redirectrule "[class lookup [HTTP::uri] equals path_dg]"

    If the currently requested [HTTP::uri] can be matched using the entries of your data-group "path_dg", then $redirectrule will become [set] with the data of the matching datagroup entry. If the datagroup doesn't match, then $redirectrule will be left empty (aka. "").

    Note: [class lookup] is just an easy to use shortcut for [class match -value]

    Note2: To support equals and starts_with datagroup querys at the same time, you have to perform two independent datagroup lookups in a row.

    Cheers, Kai

     

  • Hi Christian,

    the [class] command always compares a given input string with your datagroup entries names. It never uses the data portion of the containing entries for comparsion.

    There isn't even an option to do so. There are just options to match the input using a starts_with, ends_with, contains or equals or to control the output of the comparsion (e.g. bolean true/false, data value, etc.). In addition you have to keep in mind that you can't combine starts_with and equals in a single execution nor specify -regex or -glob style patterns to make the search patterns more accurate...

    To resolve your issue with the provided [class] functionality, you may want to execute two nested [class] commands. The outer [class] execution will query a equals datagroup and the inner [class] execution will query a starts_with datagroup.

    Another option would be to add an additional flag into datagroup result and perform additional checks/actions based on this flag. In this case you could use a single datagroup for both equals and starts_with matches. Below is an example how this could be done...

    Datagroup entries:

     

    "equals_searchstring" = "optional_operator target"
    "normal_searchstring" = "target"
    "/"  = "equals /folder/index.html"
    "/a" = "/folder/a.html"
    "/b" = "/folder/b.html"
    "/c" = "/folder/c.html"
    

     

    iRule Code:

     

     Format of [class match -element] after [join] is "searchstring optional_operator target" or just "searchstring target"
    set redirectrule [join [class match -element [HTTP::path] starts_with path_dg]]
     Check if the "equals" operator is present
    if { [lindex $redirectrule 1] eq "equals" } then {
         "equals" operator is present. Compare if datagroup item "equals" HTTP::path
        if { [lindex $redirectrule 0 ] eq [HTTP::path] } then {
             HTTP::path "equals" entryname. Sending redirect...
            set redirectrule [lindex $redirectrule 2]
        } else {
             HTTP::path does not equals entryname. Skipping redirect...
            set redirectrule ""
        }
    } else {
         "equals" operator is not present...
        set redirectrule [lindex $redirectrule 1]
    }
    

     

    Hope this helps..

    Update: Streamlined the code example and corrected some typos...

    Cheers, Kai