20 Lines or Less #68: Simplifying the Complexified Simplicity

What could you do with your code in 20 Lines or Less? That's the question I like to ask for the DevCentral community, and every time I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head. This week was no different with several good examples of iRules being used to useful and even sometimes dramatic effect. There are just some things that can’t be done anywhere else than the network layer, but even when there are multiple options often times the most effective, efficient or elegant solution is one in which BIG-IP and, yes, iRules can leap to the rescue. I may be an iRules zealot, and fully admit that I am for the record, but you can’t deny the fact that these things are doing some darn cool stuff.

This week I’ve managed to not only invent a a word (Complexified: Having been made more complex via the process of complexification. Past participle of complexify.) but also to stumble across some really cool examples of simple concepts that have been made far more complicated, but with iRules and their ability to see the whole picture of an application session and alter things as necessary they are re-simplified. Or brought back to simplification. Or something. Whether it’s a concept like redirection taken to a slightly more complex level, dealing with actual port values and altered destinations without having to bounce between servers to find the right one; or basic functionality like serving up sorry pages made less basic by wanting to offload them to a non server resources, iRules has your back. This week we’ll take a look at a few such examples of how to take something that should be simple, but got turned complex by some extenuating requirements, and make it simple again.


Sorry Server iRule with iFules


First off we’re dealing with sorry pages. This is a super simple, basic concept that pretty much everyone has had down to the point of forgetting about it since, well, forever. The problem here, however, is that this particular user wanted to be able to offload all of this functionality from the application servers to the network layer. This is commonly done for many reasons, not the least of which is ease of management and the ability to apply this concept to a large number of servers at once quickly and easily. This does, however, cause a bit more complexity, especially when looking to serve not just a simple HTML message, which has been done time and time again, but a more complete, complex request with several sub files including CSS and images. This becomes more complex because there isn’t just going to be a simple push of a page in response to a given URI, and then the network tier is done. It’s going to have to handle requests to multiple different URLs associated with the sub-objects contained within the initial HTML response to the user, displaying the sorry page, including serving up images and CSS and the like. Something simple for a web server, but often times rather complex for those that are more accustomed to slamming bits and bytes around the network. Fortunately with iRules, and specifically with the new(ish) iFiles feature, this is a snap. Take a look below for the wonderfully straight-forward example, and then go replace all your custom error pages with your BIG-IP(s). Don’t have BIG-IPs? Oh well uhh…I’m not sure what to tell you, then.


   1: when HTTP_REQUEST {
   2: if { [active_members [LB::server pool]] < 1} {
   3:      switch [string tolower [HTTP::uri]] {
   4:           "/" {
   5:                HTTP::respond 200 content [ifile get index.html] "Content-Type" "text/html"
   6:           }
   7:           "/ufstyle.css" {
   8:                HTTP::respond 200 content [ifile get ufstyle.css] "Content-Type" "text/css"
   9:           }
  10:           "/myuflheaderborder.jpg" {
  11:                HTTP::respond 200 content [ifile get myuflheaderborder.jpg] "Content-Type" "image/jpeg"
  12:           }
  13:           "/myuflheader_bg.jpg" {
  14:                HTTP::respond 200 content [ifile get myuflheader_bg.jpg] "Content-Type" "image/jpeg"
  15:           }
  16:      }
  17:   }
  18: }


iRule for Dynamic, URI Based Port


Re-writing part of the original HTTP request so that the application to which the client is connecting can properly process it is something that is pretty common, actually. This can be pretty easily done at many points within the connection, including quite commonly on the web tier, by the application servers themselves with rewrite rules and the like. Where this gets to be a bit more of an issue, however, is when it’s not the URI or hostname or the like that needs to be modified, but the port itself. You see if you have different applications, or versions of your app listening on individual ports, and you need to be sure that a request to a given URI is directed to the correct port, whether or not the user/client specified that port; well you’re looking at doing some redirection and request bouncing, having to pass from one application listener to another. That can get not only messy, but rather slow, as well. Isn’t it fortunate, then, that with a super simple iRule you can do this URI parsing and port switching at the network layer, so you only have to touch the appropriate listener, and skip that whole bouncing around bit? I thought so too, and thought I’d share this user’s take on just how to do that.


   1: when HTTP_REQUEST { 
   2:   set newuri [findstr [HTTP::uri] "/" 5] 
   3:   log local0. "Original request is: [HTTP::host][HTTP::uri]" 
   4:   log local0. "New URI is: $newuri" 
   5:   set newport [findstr [HTTP::uri] "/" 1 4] 
   6:   HTTP::uri "$newuri" 
   7:   log local0. "New Port is: $newport" 
   8:   HTTP::header replace Host "[HTTP::host]:$newport" 
  10:   if { $newport ne "" } { 
  11:     #Use the relevant Pool 
  12:     pool chuckpool_$newport } 
  13:   else { 
  14:     log local0. "Newport Variable was empty" 
  15:   } 
  16: }


Response Modifications Made Simple


This is a concept that could be extraordinarily complex turned just about as simple as humanly possible. It’s more answering what seems to be a common question or misconception than it is showing off some powerful iRule. You see the trick here is that…you don’t have to do anything. Let me explain; the user wanted to modify the response from the server that was generated from certain client requests. That’s something we can do, and a solution was quickly levied. The concern, and an understandable one frankly, was how much work would need to be done to ensure that only the appropriate responses would be modified. I.E. “How do I know that the response I’m modifying is the one that was generated from the request I just tracked?”. That’s a good question, actually, because if it weren’t for proper session management and concise tracking of client flows through the proxy, you’d have just a raw stream of requests and responses, and no direct correlation between them. Thankfully, however, that’s not the case. BIG-IP is a session tracking ninja and you can be sure that within the context of a given iRule (or session, really, since that’s the context of an iRule) that the response you’re dealing with will always be the appropriate one that is attached to the request you tracked heading through the proxy’s front door. Because of that, this is super simple, and you can see just how easy it is in the iRule below.


   1: when HTTP_REQUEST {
   2:  set specialurl 0
   3:  if { [HTTP::uri] equals "/test.txt" } {
   4:   set specialurl 1
   5:   }
   6:  ...any other rule elements...
   7: }
   8: when HTTP_RESPONSE {
   9:  if { $specialurl = 1 } {
  10:   do something }
  11:  else {
  12:   do something else or nothing }
  13: }



That wraps us up for another 20LoL. I’ll be back in two weeks with more simple examples of iRules being all sorts of hawesome. If you’ve got suggestions, examples or comments in the meantime, feel free to send them my way. And as always, code hard. Oh, and yes, complexified is totally a word now.


Published Apr 26, 2013
Version 1.0

Was this article helpful?

No CommentsBe the first to comment