Forum Discussion

Craig_Holland_2's avatar
Craig_Holland_2
Icon for Nimbostratus rankNimbostratus
Aug 29, 2006

iRule Optimization

Hi,

As you'll soon see I'm not a programmer by trade, so I'm sure there are some things I could do to make this run leaner. I'm hoping for some help with my iRule, mainly in the performance department.

The purpose of this iRule is to the following:

- As an HTTP request comes in, I grab the MSISDN number (phone number) from the request.

- I use the MSISDN number to determine which pool to go to and to create a hash for use by our backend systems as a UID(we don't want to store the MSISDN number for privacy reasons)

- Since sha1 and b64encode output non-integers, I use crc32 to make an integer off the hash and mod it to find a pool.

- After the pool is picked, I need to rebuild the URI with a standardized format with the UID set to the hash. (I'm sure this is not the best way to do this)

- If there wasn't as MSISDN number, then just fallback to cookie persistence.


when RULE_INIT {
  set ::prime_number 3
  set ::carrier_tag "MSISDN"
   Adding 1 for '=' sign
  set ::carrier_tag_length [expr [string length $::carrier_tag] + 1]
  set ::my_tag "uid"
   Adding 1 for '=' sign
  set ::my_tag_length [expr [string length $::my_tag] + 1]
  set ::salt "1234" 
}
when HTTP_REQUEST {
  set uri [HTTP::uri]
  set msisdn [findstr [HTTP::query] "${::carrier_tag}=" $::carrier_tag_length "&"]
  if { $msisdn != "" } {
     set hash [sha1 $msisdn$::salt]
     set key [expr [crc32 $hash] % $::prime_number]
     set uid [b64encode $hash]
      Pick a pool
     switch $key {
         0 {pool pool0}
         1 {pool pool1}
         2 {pool pool2}
 }
     Rewrite the MSISDN Tag with a My Tag
     Go through each field of the query string and parse
     it into a list variable
     for {set x 1} {$x<100} {incr x} {
         set field [getfield [HTTP::query] "&" $x]
      When you find an empty field, bail,
      Otherwise, add it to the list
         if { $field == "" } {
             set x 100   
         }
         else {
             lappend query_list $field
         }
     }
     set new_query ""
     set isfirst 1
     foreach x $query_list {
          If we find the Carrier Tag, ignore it and move on
          If we don't, check if the first element in the query string and don't add a &
          If not first element, split them with a &
         if { $x starts_with "$::carrier_tag" } {
         }
         elseif { $isfirst == 1 } {
             set new_query "$new_query$x"
             set isfirst 0
         }
         else {
             set new_query "${new_query}&${x}"
         }
     }
      Now that we are done building a query string without the Carrier Tag,
      ...add our tag to the end with the new UID
     if { $new_query == "" } {
         set new_query ${::my_tag}=[URI::encode ${uid}]
     }
     else {
         set new_query ${new_query}&${::my_tag}=[URI::encode ${uid}]
     }
      Cram the new query string and the original path together
      to create the new URI
     set new_uri [HTTP::path]?${new_query}
      Pass the new URI along to the web server
     HTTP::uri $new_uri
  }
  else {
      If there is no MSISDN number in the request,
      then use regular cookie persistence.
     log local0. "Missing MSISDN in Request!"
     persist cookie insert My.test1
  }
}

Thanks in advance!
No RepliesBe the first to reply