What could you do with your code in 20 Lines or Less? That's the question I ask (almost) every week, and every week I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head.

For this week's 20 Lines or Less I thought I might bring you some iRules that are fresh off the presses. I've been digging through the iRules forums today, trying to keep up with this outstanding community and their many innovations, concepts and questions. In doing so I got to answer some very cool questions and thought I'd use three of those example iRules for today's 20LoL.  These are production tested, hardened or anything like that, they're just proof of concept like you'd expect, but I think they're neat ... or at least the questions they answer are.

Multi-header inspection

https://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&postid=32156&view=topic

A question was raised about how to inspect several headers to see if any of them meet a certain criteria. In this case they were looking to see if a header was exceeding a certain size. With a little foreach action I was able to deliver an example that I hope gets them going, or solves their problem outright.  It's important to note the loop control that's in place to only execute the foreach loop on the first HTTP Request, not on every single one. That would be...slow.

when HTTP_REQUEST {
  if {$loop == 0} {
    foreach header {[HTTP::header names]} {
      if {[string length $header] > 32768} {
        log local0. "Header exceeds maximum length! - Header Name: $header, Length: [string length $header], Value: [HTTP::header value $header]"
      }
    }
    incr loop
  }
}

 

Nested TCL Logic

https://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&postid=32082&view=topic

This particular user was having some trouble with putting together a somewhat complex TCL logic structure that involved some nesting of ifs.  I can absolutely relate to this being confusing at times, so hopefully this example of some simple nesting keeps things working for them.

when HTTP_REQUEST {
  if {[matchclass $::test equals [IP::client_addr]] } {
    if {[HTTP::uri] contains "/cf/" or [HTTP::uri] contains "/hf/"} {
      pool PoolA 
    } else {
      pool PoolB 
    }
  } elseif {[HTTP::uri] contains "/cf/" or [HTTP::uri] contains "/hf/" } {
    pool PoolC 
  } elseif {[HTTP::uri] contains "/vh/"} {
    pool PoolD 
  } else {
    pool Default
  }
}

 

Timed event within iRules

https://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&postid=32166&view=topic

This is a question that's come up many times: Can I initiate a command within an iRule after a certain amount of time has passed.  The simple answer is ... sort of.  There isn't currently support for TCL's after command, which is their implementation of an actual programmable timer within the language. That doesn't mean you can't get tricky with system time and variables. It does mean that you should be careful in doing so, and that you shouldn't rely on the results being 100% exact, since it's definitely a kluge, but it should be functional in many cases. Hopefully this will only have to hold you over for a while, assuming we get to see this kind of functionality within iRules in the future...here's hoping. Also, I wouldn't generally recommend having a 10 minute timeout for a pool failure, this is just intended as an example of how to build in a delayed evaluation within the iRule. ;)

when CLIENT_ACCEPTED {
   set loop 0
}
 
when HTTP_REQUEST {
   if {[active_members primarypool] == 0} {
     if { $loop == 0} {
       set first [clock seconds]
       set loop 1
     } elseif { [expr [clock seconds] - $first] >= 600} {
       pool backuppool
     }
   }
}

I hope you enjoyed this week's 20 Lines or Less. Feel free to send in your suggestions or feedback, as always, and I'll see you next week.

#Colin

Listening to: Stone Temple Pilots - Core - Creep