What could you do with your code in 20 Lines or Less? That's the question I ask (almost) every week for the devcentral community, 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.

It’s been hectic here in DCland and finding time to write has been more difficult than normal, though that shouldn’t be a problem much longer. Fortunately for all of us this awesome community keeps kicking out the jams so I can rely on their hawesome knowledge to provide cool iRule snippets.  This week we’ve got two iRules from the forums and one from my own collection.


URI Rewriting done differently


First up, URI rewriting…with style.  I made a tweet recently about my newly rekindled love for the scan command and it was great to see someone else making use of it as well.  Aaron brings us a very cool example of switching on file types which is standard fare, but then he shows off a very cool way to use scan to strip out the first URI segment between the first two slashes.  I like it.

   # Check the requested path (URI minus query string)
   switch -glob [string tolower [HTTP::path]] {
      "*.gif" -
      "*.js" -
      "*.css" -
      "*.jpg" -
      "*.bmp" {
         # Read in everything after the first / that is not a /. 
     # Save that to $session_id and everything else to $uri_to_save
     # scan will return the number of matches
         if {[scan [HTTP::uri] {/%[^/]%s} session_id uri_to_save] == 2}{
            # Rewrite the URI without the session ID
            #log local0. "$session_id"
            HTTP::uri $uri_to_save


Class ordering and search lengths


User FishNiX brings a wicked cool look at searching not by a given parameter but by the length of the string being matched.  By first sorting a class by element length they were able to ensure they always get the longest (most complete) match.  Very inventive and something I haven’t seen before. Nicely done.

rule set_pool_by_host_and_uri {  
    when HTTP_REQUEST {  
     # Class order isn't guaranteed to come back in the order entered in the bigip.conf... 
     log local0. "list: $::host_uri_pool_selector_class" 
     log local0. "lsort: [lsort -decreasing -index 0 $::host_uri_pool_selector_class]"
     foreach row [lsort -decreasing -index 1 $::host_uri_pool_selector_class] {  
       log local0. "\$row: $row"
       if { [string tolower [HTTP::host]] equals [getfield $row " " 1] }{  
         if { [string tolower [HTTP::uri]] starts_with [getfield $row " " 2] }{  
           pool [getfield $row " " 3]


Partial Portal Access

Something that’s been bouncing around in my head for a while was the idea of being able to limit access to given applications based on a combination of criteria. Say for instance you wanted to limit access to the URIs that make up your intranet to only internal IPs, but allow access to everything else from anyone, well that’s exactly what this iRule is designed to do.  You end up with two classes, one for the list of allowed IPs, and one for the list of page IDs you want  to restrict. Fun stuff.

  if { !([matchclass [IP::client_addr] equals $::InternalIPs])} {
    if {[scan [URI::decode [string tolower [HTTP::uri]]] "/default.aspx?tabid=%d" tabid] == 1 } {
      if { [matchclass $tabid equals $::intranet_pages] } { 
        log local0. "Dropped request from IP:  [IP::client_addr]"

If you’ve got ideas or examples of iRules doing a lot in a little bit of space, send them my way. Otherwise, see you next 20LoL.