Forum Discussion
Redirecting request based on port number
I have two application servers as pool members to multiple pools. I want to be able to load balance based on port.
For example, If a user click first link, load balance staging pool. If user is in staging_pool and if user decides connect to development_pool from there, click the link that is in staging application.
Note: This is working currently but because I have to create Virtual Server for each pool. I don't want that.
when HTTP_REQUEST {
switch -glob [HTTP::host] {
http://example.mtd.today.com:8088/tuesday/ { pool Stagin_Pool }
http://example.mtd.today.com:8089/wednesday/ { pool Management_Pool }
http://example.mtd.today.com:8090/thursday/ { pool Development_Pool }
http://example.mtd.today.com:8091/friday/ { pool Test_Lab_Pool }
default { pool Production_Pool }
}
}
Thanks for your help.
18 Replies
- nitass
Employee
is virtual server port and pool member port number identical? for example, virtual server1 is listening on port 8080 and its pool member is also on port 8080. - Elias_O_16228
Nimbostratus
Yes! The VS and Pool members are listening to same port. - Kevin_Stewart
Employee
If you JUST want to match the port number, then you can do that using the TCP::local_port command:when HTTP_REQUEST { switch [TCP::local_port] { "8088" { pool Stagin_Pool } "8089" { pool Management_Pool } "8090" { pool Development_Pool } "8091" { pool Test_Lab_Pool } default { pool Production_Pool } } }
If you need to match the whole request (host, port, and uri) then you'd need something like this:
"[string tolower [HTTP::host]]:[TCP::local_port][string tolower [HTTP::uri]]"
This won't capture the protocol specifier (ex. "http://"), so you'll need to remove it from the evaluation. Considering that all of the hosts are the same, you can probably skip the [HTTP::host] evaluation as well. Also, if the port and URI are specific to a service (ex. 8088 and /tuesday), then you might also want to consider just evaluating one or the other. - Elias_O_16228
Nimbostratus
Thanks Kevin,
Yes, I want to match the whole request (host, port, and uri), also port and URI are specific to a service.
Check this out:
when HTTP_REQUEST {
switch "[string tolower [HTTP::host]]:[TCP::local_port][string tolower [HTTP::uri]]" {
"8088" { pool Stagin_Pool }
"8089" { pool Management_Pool }
"8090" { pool Development_Pool }
"8091" { pool Test_Lab_Pool }
default { pool Production_Pool }
}
}
Does it make a difference if capture the protocol specifier since users need to specify the whole link in the browser e.g. http://example.mtd.today.com:8089/wednesday/ or it will work regardless? - Kevin_Stewart
Employee
"[string tolower [HTTP::host]]:[TCP::local_port][string tolower [HTTP::uri]]" is going to evaluate the host, port, and URI, so your switch conditions will have to contain all three of those values.
ex. "example.mtd.today.com:8088/tuesday" { pool Stagin_Pool }
Also, if there's a chance that there's something after the "/tuesday" URI, then you should use switch -glob and make sure your switch conditionals end with a wildcard (star character).
ex. ex. "example.mtd.today.com:8088/tuesday*" { pool Stagin_Pool }
My other points were this:
1. If the host value IS ALWAYS THE SAME (ex. "example.mtd.today.com"), then there's probably no reason to include that in the evaluation.
2. If the port and URI are specific to a service (ex. port 8088 and URI "/tuesday"), then there's probably no reason to evaluate both. In other words, evaluate either the URI or the port.
Last, you can't capture the protocol specifier with these commands, so you should leave it out of the switch evaluation. - Elias_O_16228
Nimbostratus
Awesome! Thanks.
I feel like it's working even though I have not tested it but for the fact that you layed it out exactly how it is, I'm confident it will work.
I will use the "Switch -glob" because there are other different things after the /. It's actually a long link
1. The host is always the same.
2. URI and port are specific. e.g. example.mtd.today.com:8088/tuesday does not change. Can it evaluate either port or both just in case I decide to redirect to another port or uri?
3. Do I need to use the quoten " " on switch before and after the parentesis ? - Kevin_Stewart
Employee
1. The host is always the same.
I would then recommend not evaluating the [HTTP::host] value. It provides no value.
2. URI and port are specific. e.g. example.mtd.today.com:8088/tuesday does not change. Can it evaluate either port or both just in case I decide to redirect to another port or uri?
You'd need to modify the iRule switch conditions in either case. So if port 8088 always equals the "/tueday" URI, which equals the Stagin_Pool pool, then I'd recommend just evaluating the port OR the URI.
3. Do I need to use the quoten " " on switch before and after the parentesis ?
A switch conditional is generally a string comparison. I added the quotes in my last example because I needed to insert the colon ":" character in the evaluation string. If you're just evaluating the port or URI, the the following (without quotes in the switch) will work:
switch [TCP::local_port] {
...
}
or
switch [string tolower [HTTP::uri]] {
...
} - Elias_O_16228
Nimbostratus
Below is what I was able to put all together, evaluating only the URI and wildcard (*) for other trailing links.
when HTTP_REQUEST {
switch -glob [string tolower [HTTP::uri]] {
http://example.mtd.today.com:8088/tuesday* "8088" { pool Stagin_Pool }
http://example.mtd.today.com:8089/wednesday* "8089" { pool Management_Pool }
http://example.mtd.today.com:8090/thursday* "8090" { pool Development_Pool }
http://example.mtd.today.com:8091/friday* "8091" { pool Test_Lab_Pool }
default { pool Production_Pool }
}
}
I was not sure of the ports with quotes "8091" based on your first response and the ones in the hostname. - Kevin_Stewart
Employee
The [string tolower [HTTP::uri]] commands will only return the lowercase version of the requested URI, nothing more.
ex. "/tuesday"
You need [string tolower [HTTP::host]] to return the Host information (ie. "example.mtd.today.com"), [TCP::client_port] to return the port (ex. 8088), and none of these will return the protocol specifier (ex. "http://). The switch command is going to take what's given, in this case the request URI, and look for it in the switch conditions. None of your switch conditions will ever match because you're providing more than the URI.My recommendation was to skip the [HTTP::host] evaluation (because the requested host is always the same) and just focus on either the port OR the URI. - Elias_O_16228
Nimbostratus
I took out the [HTTP::host] evaluation. Then put wildcard immediately after port "8088*" to evaluate everything after the port,
e.g. example.mtd.today.com:8088/tuesday/calendar/student/file/
e.g. example.mtd.today.com:8089/wednesday/journal/teachers/data/
e.g. example.mtd.today.com:8090/thursday/classes/schedule/courses/
I need to figure out how to evaulate lower and upper cases when evalauting URI,
e.g. example.mtd.today.com:8088/TUESDAY/calendar/student/file/
I am getting undefined "default" error.
when HTTP_REQUEST {
switch -glob "[TCP::local_port][string tolower [HTTP::uri]]" {
"8088*" { pool Stagin_Pool }
"8089*" { pool Management_Pool }
"8090*" { pool Development_Pool }
"8091*" { pool Test_Lab_Pool }
default { pool Production_Pool }
}
}
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