Forum Discussion

Robert_Pagano_7's avatar
Robert_Pagano_7
Icon for Nimbostratus rankNimbostratus
Nov 14, 2007

pool selection based on path in URI (and subsequent URI path modification)

I am trying to route connections based on the portion of the URI after the hostname.

 

 

For example, connections to...

 

 

http://www.example.com/lms/path/to/resource

 

 

...should be routed to a "LMS" server pool...

 

 

while connections to...

 

 

http://www.example.com/content/path/to/resource

 

 

...should be routed to a "CONTENT" server pool.

 

 

 

Going by an example provided in the LTM Configuration Guide, it looks like the following will work...

 

 

----------

 

when HTTP_REQUEST {

 

if { [HTTP::uri] starts_with "/lms" } {

 

pool LMS_pool

 

} elseif { [HTTP::uri] starts_with "/content" } {

 

pool content_pool

 

}

 

}

 

----------

 

 

One wrinkle, however, that I am not sure if the above will handle, is that the URI sent to the real server should not have the "starts_with" piece.

 

 

In other words...

 

 

client requests "http://www.example.com/lms/path/to/resource"

 

|

 

|

 

V

 

load balancer (selects pool and sets URI path to... "/path/to/resource"

 

|

 

|

 

V

 

real server

 

 

 

Any help with this will be greatly appreciated.

3 Replies

  • Hi,

    You can use string map to remove the prefix "/lms" and HTTP::uri to update the URI. Here's an example:

    
    when HTTP_REQUEST {
       if { [HTTP::uri] starts_with "/lms" } {
          pool LMS_pool
          HTTP::uri [string map {/lms {}} [HTTP::uri]]
           log the original and updated URI's using the cached copy from HTTP::uri
          log local0. "URI - original: [HTTP::uri], updated: [string map {/lms {}} [HTTP::uri]]"
       } elseif { [HTTP::uri] starts_with "/content" } {
          pool content_pool
       }
    }

    Aaron
  • That works, but for whatever reason causes the config to fail when reloading with the two curly braces together. To avoid that issue, try using two double quotes for the string map instead:

     

     

    HTTP::uri [string map {/lms ""} [HTTP::uri]]

     

     

    Aaron
  • What happens when the URI is "/lms"? The string map will turn it into an empty string which isn't valid for a URI. A URI must be at least a starting slash.

     

     

    If you wanted to go with a more dynamic approach, this iRule will take the first path element "one" from the URI "/one/two/three", upper case the one to "ONE", create a dynamic pool name "ONE_pool", remove the "/one" from the first URI and then attempt to assign traffic to the dynamic created pool. Note, I used a catch command to catch any errors from assignments to pools that don't exist.

     

     

    when HTTP_REQUEST {
      log local0. "URI: [HTTP::uri]"
      set loc [lindex [split [HTTP::uri] "/"] 1]
      log local0. "loc: $loc"
      
      if { [string length $loc] > 0 } {
         Build the new URI
        set new_uri [string map { "/$loc" "" } [HTTP::uri] ]
        if { [string length $new_uri] == 0 } {
          set new_uri "/"
        }
        HTTP::uri $new_uri
        set new_pool "[string toupper ${loc}]_pool"
        if { [catch { pool $new_pool}] } {
          log local0. "Error assigning pool to $new_pool"
        }
      }
    }

     

     

    Of course, if you want to hard code only certain locations, then you could do so like this:

     

     

    when HTTP_REQUEST {
      log local0. "URI: [HTTP::uri]"
      switch -glob [HTTP::uri] {
        "/lms*" {
          set loc "lms"
        }
        "/content*" {
          set loc "content"
        }
        default {
          set loc ""
        }
      }
      
      log local0. "loc: $loc"
      
      if { [string length $loc] > 0 } {
         Build the new URI
        set new_uri [string map { "/$loc" "" } [HTTP::uri] ]
        if { [string length $new_uri] == 0 } {
          set new_uri "/"
        }
        HTTP::uri $new_uri
        
        set new_pool "[string toupper ${loc}]_pool"
        if { [catch { pool $new_pool}] } {
          log local0. "Error assigning pool to $new_pool"
        }
      }
    }

     

     

    Hope this helps...

     

     

    -Joe