Forum Discussion

jay_41157's avatar
jay_41157
Icon for Nimbostratus rankNimbostratus
Sep 05, 2008

wildcard in data group.

Hi ,

 

 

I am trying to use \apple\* --> * being wildcard... but i do not have the correct fromat.. in the data group. is there an escape squence ?

 

thanks
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    If you're using a string datagroup, you don't need to escape the *. You can use apple* unquoted and unescaped. If you're evaluating the class with findclass (Click here), you don't need to use a wildcard though.

     

     

    Aaron
  • I am using string data group, but I have matchclass instead of findclass, and when I use apple* --> it does not use the apple"*" as the wildcard.

     

     

    Thanks
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Does matchclass work with a * in the datagroup? I'm guessing not.

    If not, you could either replace the class with a switch statement and use the glob flag for wildcard matching, or if you like the class, you could replace matchclass with a foreach loop:

      
      when RULE_INIT {  
        
          Create a test class (actually a list in this case)  
         set ::test_class [list abcd abcde abcdef* abcdefg*]  
        
         foreach element $::test_class {  
        
            log local0. "Current \$element: $element"  
        
            if {[string match -nocase $element "ABCDEFG"]}{  
        
               log local0. "Matched \$element: $element.  Exiting loop."  
               break  
            }  
         }  
      }  
      

    Log output:

    Rule : Current $element: abcd

    Rule : Current $element: abcde

    Rule : Current $element: abcdef*

    Rule : Matched $element: abcdef*. Exiting loop.

    Aaron
  • Thanks, I just read the wiki on matchclass that indicates what you said about * in datagroup not wokring with match class, so I am guess a more cleaner approach might be to use findclass as you initially mentioned in the irule:

     

     

    Current IRULE:

     

    --------------------------------------------------------------------------------------------------------------------------------

     

    if { (not [matchclass [string tolower [HTTP::uri]] starts_with $::LegacyExceptions])

     

    and ([matchclass [string tolower [HTTP::uri]] equals $::LegacyPaths]) } {

     

    --------------------------------------------------------------------------------------------------------------------------------

     

    New:

     

    --------------------------------------------------------------------------------------------------------------------------------

     

    if { (not [findclass [string tolower [HTTP::uri]] $::LegacyExceptions] ==0 )

     

    and ([findclass [string tolower [HTTP::uri]] $::LegacyPaths] == 0) } {

     

     

     

     

    Or is there a better way to use findclass ? I am unsure about the syntax.
  • I think this might be more accurate for syntax..

     

    if { (not [catch[findclass [string tolower [HTTP::uri]] $::pubsLegacyExceptions] == 0] )

     

    and ([catch[findclass [string tolower [HTTP::uri]] $::pubsLegacyPaths] == 0 ]) } {

     

    not too sure on the result of catch..
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Catch is used to trap runtime errors. The only benefit for using catch with findclass is handling the TCL error if the class isn't defined.

     

     

    Here is a quick example:

     

     

      
          return 0 is false.  Save the result of running the command 'return 0' to the variable named result  
         if {[catch {return 0} result]}{  
            log local0. "catch was true, because return resulted in return code 0. Result: $result"  
         } else {  
            log local0. "catch was false, because return resulted in non-zero return code. Result: $result"  
         }  
        
         if {[catch {set ::test 1} result] }{  
            log local0. "catch was true, because the set command returned with an error. Result: $result"  
         } else {  
            log local0. "catch was false, because the set command returned without error. Result: $result"  
         }  
        
         if {[catch {set ::test $doesnt_exist} result] }{  
            log local0. "catch was true, because the set command returned with an error. Result: $result"  
         } else {  
            log local0. "catch was false, because the set command returned without error. Result: $result"  
         }  
      

     

     

    And the log output:

     

     

     

    Rule : catch was true, because return resulted in return code 0. Result: 0

     

    Rule : catch was false, because the set command returned without error. Result: 1

     

    Rule : catch was true, because the set command returned with an error. Result: can't read "doesnt_exist": no such variable

     

     

     

     

    As for using findclass to support wildcard matching, I don't think it will work. findclass does do wildcard matching, but the URI token listed in the class would need to be as long or longer than the requested URI. For a class which contains five elements:

     

     

      
      test_class:   
         /aaaaa  
         /bbbbb  
         /ccccc  
         /ddddd  
         /aaaaa/test  
      

     

     

    Here is an iRule which attempts to match a requested URI of /aaaaa/t against the class:

     

     

      
      when RULE_INIT {  
         set ::uri "/aaaaa/t"  
        
         log local0. "Test URI: $::uri; \$::test_class: $::test_class ([llength $::test_class])"  
        
         log local0. "\[findclass \$::test_class \$::uri\]: [findclass $::test_class $::uri]"  
        
         log local0. "\[findclass \$::uri \$::test_class\]: [findclass $::uri $::test_class]"  
        
      }  
      

     

     

    The log output shows that /aaaaa/t matches the class element, /aaaaa/test. A requested URI of /aaaaa/test does not match against a class element of /aaaaa/t.

     

     

     

    Rule : Test URI: /aaaaa/t; $::test_class: /aaaaa /bbbbb /ccccc /ddddd /aaaaa/test (5)

     

    Rule : [findclass $::test_class $::uri]:

     

    Rule : [findclass $::uri $::test_class]: /aaaaa/test

     

     

     

     

    I think the easiest way of accomplishing wildcard matching is to use a foreach loop:

     

     

      
           set test_uri "/ABCDEFG"  
           log local0. "\$test_uri: $test_uri"  
            Create a test class (actually a list in this case)    
           set ::test_class [list /abcd /abcde /abcdef* /abcdefg*]    
            
           foreach element $::test_class {    
            
              log local0. "Current \$element: $element"    
            
              if {[string match -nocase $element $test_uri]}{    
            
                 log local0. "Matched \$element: $element.  Exiting loop."    
                 break    
              }    
           }   
      

     

     

    And the log output:

     

     

     

    Rule : $test_uri: /ABCDEFG

     

    Rule : Current $element: /abcd

     

    Rule : Current $element: /abcde

     

    Rule : Current $element: /abcdef*

     

    Rule : Matched $element: /abcdef*. Exiting loop.

     

     

     

     

    Aaron