Forum Discussion

John_LeMay_1062's avatar
John_LeMay_1062
Icon for Nimbostratus rankNimbostratus
Apr 08, 2008

Improving on this "catch all"?

Recently I configured a "catch all" type virtual server and I'm handling various aspects of traffic management with an iRule. So far it's working well, but it is already becoming difficult to manage. The rule follows and should be, I believe, relatively self-explanatory except for the "matchclass" statement. That statement is used to differentiate between internal and external clients, redirecting the external clients to a separate pool of servers.

 

 

I was hoping for some tips on improving this concept to make it easier on the eyes and simpler to manage going forward. I'm also concerned about performance as this rule continues to grow as we utilize it for additional sites. Host names and other info have been made more generic for the sake of posting here.

 

 

 

when HTTP_REQUEST {

 

if { [HTTP::host] equals "site1.domain.com" }{

 

pool pool_site1.domain.com

 

} elseif { [HTTP::host] equals "site2.domain.com" }{

 

if { [HTTP::uri] eq "/" }{

 

HTTP::uri "/pathtosite/site2"

 

}

 

if { [matchclass [IP::client_addr]/16 equals $::mySubnets] }{

 

pool pool_site2.domain.com_internal

 

} else {

 

pool pool_site2.domain.com

 

}

 

} elseif { [HTTP::host] equals "site3.domain.com" }{

 

pool pool_site3.domain.com

 

} else {

 

reject

 

}

 

}

5 Replies

  • The rule you have is actually pretty clean, if a bit hard to follow. You could use a switch statement with indentation and spacing instead. It might be a little easier to follow and slightly faster than multiple if/elseif/else's.

    
    when HTTP_REQUEST {
        Parse the HTTP host header value
       switch [string tolower [HTTP::host]] {
           Host was site1
          site1.domain.com {
              Set the pool to site1 pool
             pool pool_site1.domain.com
          }
           Host was site2
          site2.domain.com {
             if {[HTTP::path] eq "/"}{
                HTTP::uri "/pathtosite/site2"
             }
             if { [matchclass [IP::client_addr]/16 equals $::mySubnets] }{
                pool pool_site2.domain.com_internal
             } else {
                pool pool_site2.domain.com
             }
          }
           Host was site3
          site3.domain.com {
             pool pool_site1.domain.com
          }
           Unknown host, reset the connection
          default {
             reject
          }
       }
    }

    Aaron
  • Thanks Aaron, it looks like my spacing and indentation were lost when I posted. Using the switch statement certainly looks better and will likely be easier to maintain. I'll give that a shot.
  • Interesting issue. Are comments not allowed within the switch structure? I was unable to save until I removed all comment lines after "swtch {".
  • Sorry about that. I didn't test the syntax first. You can't have comments in the switch cases:

    http://www.tcl.tk/man/tcl8.4/TclCmd/switch.htm

    Beware of how you place comments in switch commands. Comments should only be placed inside the execution body of one of the patterns, and not intermingled with the patterns.

    So it would need to be like this:

    
    when HTTP_REQUEST {
        Parse the HTTP host header value
       switch [string tolower [HTTP::host]] {
          site1.domain.com {
              Host was site1, set the pool to site1 pool
             pool pool_site1.domain.com
          }
    ...

    Aaron
  • Nice, at least we confirmed it. I looked all over for syntax here and on ask but didn't get anywhere. Should have looked at tcl documentation. Now I know how to go back and add comments as well.

     

     

    Even with only the three sites in the rule, the switch is noticably faster than the previous rule. I also moved "site3" toward the top since it requires less processing than "site2". Thanks for the tip on the switch construct!

     

     

    I'm off to read a tcl book now - something I keep promising myself I'll do.