Forum Discussion
Robert_Pagano_7
Nimbostratus
Nov 14, 2007pool 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
- hoolio
Cirrostratus
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 - hoolio
Cirrostratus
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
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
