Forum Discussion
Reroute traffic based on request content
Hi All,
I have trying to implement traffic route based on request content.
Request :
username
Der30T09Ur10-03-2016 12-03-2016
21US
CY1910
0
020
depend on the username I need to route specific user request to separate VIP. Is that possible with F5?
Regards, Chathuranga.
4 Replies
- Kevin_Stewart
Employee
Most certainly. But you may have to consider other factors. Is this a single atomic request, or will the user make multiple requests? Will all of the user requests contain the information you're looking for?
Let's assume for a moment that these are atomic requests, and by "VIP" you actually mean servers, or a pool of servers. You could simply use a string function to parse out the content you're looking for and make a load balancing decision based on that. Something like this:
when HTTP_REQUEST { if { [HTTP::header exists Content-Length] } { Collect the payload and trigger the HTTP_REQUEST_DATA event HTTP::collect [HTTP::header Content-Length] } } when HTTP_REQUEST_DATA { The HTTP request payload is buffered and accessible here Now use string functions to get the username from the request payload set username [findstr [HTTP::payload] "" 10 ""] switch $username { "bob" { pool bob_pool } "alice" { pool alice_pool } "eve" { pool eve_pool } "oscar" { pool oscar_pool } default { pool default_pool } } }Of course this is a wildly simplistic example, and you could a) use XML_CONTENT_BASED_ROUTING to parse the XML payload with real xpath processing, and b) use something more elaborate than a static switch statement to test usernames. In any case, the findstr command is a fast and easy way to selectively extract information from a string, in this case the data between "" and "".
- Kevin_Stewart
Employee
This was an example, so you'll likely need to do some tweaking. For starters, add some logging statements to see what is returned from the findstr:
when HTTP_REQUEST { if { [HTTP::header exists Content-Length] } { Collect the payload and trigger the HTTP_REQUEST_DATA event HTTP::collect [HTTP::header Content-Length] } } when HTTP_REQUEST_DATA { The HTTP request payload is buffered and accessible here N ow use string functions to get the username from the request payload set username [findstr [HTTP::payload] "" 10 ""] log local0. "username = $username" switch $username { "bob" { pool bob_pool } "alice" { pool alice_pool } "eve" { pool eve_pool } "oscar" { pool oscar_pool } default { pool default_pool } } }Now test that and either look at LTM logs in the management GUI, or better, open up an SSH session to the BIG-IP and tail the LTM log:
tail -f /var/log/ltmYou'll be looking for a log statement like this:
username = [something]If the username value is empty, then you know the findstr isn't returning something and you need to modify the search. If it is returning something, then perhaps the switch isn't right. Start there and let us know what you find.
- Kevin_Stewart
Employee
Okay, do this: add a new log statement before the other log statement that displays the HTTP payload:
log local0. [HTTP::payload]At this point you're either not sending the data that you think you are, or the fields are not as you've described. The above log statement should shed some more light on that.
- Kevin_Stewart
Employee
Okay, so it looks like the HTTP (XML) payload is coming through encoded. Let's modify the findstr accordingly:
set username [findstr [URI::decode [HTTP::payload]] ""]
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* 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