Forum Discussion

Craig_Hammer_10's avatar
Craig_Hammer_10
Icon for Nimbostratus rankNimbostratus
Jul 21, 2005

Failing to match URI in SWITCH statment

When using this rule, I never seem to match the first two evaluation steps:


when HTTP_REQUEST {
   switch { [HTTP::uri] starts_with } {
      "/argo/tcc" {
         use pool one
      }
      "/argo/tc-update" {
         use pool two
      }
      default {
         use pool three
      }
   }
}

Every request falls through to the default pool, and recevie this from the servers in the default pool: HTTP Status 404 - /argo/tc-update

From the 404, I know the URI is coming through like I expect it to, but I can not see why it does not match the first statement.

Any ideas?

4 Replies

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    I don't believe you want the "starts_with" operator as part of the switch. You probably want something more like this:

    
    when HTTP_REQUEST {
       switch -glob [HTTP::uri] {
          "/argo/tcc*" {
             use pool one
          }
          "/argo/tc-update*" {
             use pool two
          }
          default {
             use pool three
          }
       }
    }

    Notice I added -glob to the switch command to enable glob matching and then added an '*' after the strings.

    For more information on the switch command Click here:

    http://tmml.sourceforge.net/doc/tcl/switch.html

  • unRuleY,

     

     

    You're right on, using glob fixed the problem. In the meantime, I was using an if-elseif-else with the "starts_with" syntax which worked also.

     

     

    Do you know whether if-elseif (nested if) or switch (case) is more efficient using the TCL interpreter on v9 ?
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Hmm, that's a good question.

     

     

    You could attempt to measure it now that you have both versions working. You can enable rule timing by using the "timing on" command at the top of the rule before the when clause (Note: don't leave this turned on indefinitely as it does have a small impact on performance). This will cause cycle counts to be displayed when viewing rule statistics (ie: bigpipe rule show all). You could run a couple thousand iterations to get a decent average for each of the methods.

     

     

    Another factor that will influence your results is how often the first vs. second vs. last comparison matches. You can influence the performance by moving the most matched string first and the least matched last.

     

     

    However, there are a couple of factors that I could argue would make one method faster over the other, but I can't make a good guess as to which factor is going to be most influential. Empirical data would be best way to determine this. Here are the two most influential arguments for each method:

     

     

    In the if-elseif-else method, the "starts_with" operator is an operator designed specifically to match only the beginning of the string, whereas the switch command must do a string pattern match. Pattern matching is going to cost more cpu.

     

     

    In the switch command method, the switch command does a pre-compiled iteration over the provided list of patterns as opposed to the byte-code interpreted branch-test-branch approach of the if-elseif-else method. Though the Tcl byte-code is very fast, it's never going to be as fast as native machine language.

     

     

    Ultimately, both of these methods should yield very good performance and I personally would probably use the method that is easiest to maintain in this case.

     

     

  • These are the discussions that are most helpful to me. Code efficiency would be a helpful addition under the docs and tips section. As rules developed here on DevCentral reveal keen insight into the depths of iRules coding the threads could be repackaged as a collection of brief tutorials.