Forum Discussion
irule to redirect info.blah.edu catches all paths, not just the three defined
Match subdomain.domain, with a "/", b_path, c_path, d_path; Then A/B load balance 60/40 percent ratio.
Created 12/11/2012 Christian Henderson
Last edited 12/11/12
when RULE_INIT {
log local0. "initializing ... "
set static::debug 1
Host header variables for sub-domain and domain.
set static::a_sub "degrees"
set static::b_sub "onlinedegrees"
set static::c_sub "info"
set static::domain "blah.edu"
Path variables.
set static::b_path "\?*"
set static::c_path "index.htm"
set static::d_path "degrees"
Current count variable.
set static::current 0
1 in N requests will go to B subdomain - 6 for 60/40 ratio.
set static::ratio 6
Max value to reset count.
set static::max 10
}
when HTTP_REQUEST {
F5 doesn't put the question mark in the query string
if { [HTTP::query] equals "" } { set new_query "" }
else { set new_query "?[HTTP::query]" }
if { $static::debug > 1 } { log local0. "new query string is \[$new_query\]" }
Only catch requests that come in with the proper host header
if { [string tolower [HTTP::host]] equals "$static::c_sub.$static::domain" } {
Only catch clients that come in through the URI path static::a_path, static::b_site, or static::c_path
if { [string tolower [HTTP::path]] equals "/" || [string tolower [HTTP::uri]] matches_glob "/$static::b_path" || [string tolower [HTTP::uri]] starts_with "/$static::c_path" || [string tolower [HTTP::uri]] starts_with "/$static::d_path" } {
Check for < current for 60% of traffic.
if { $static::current < $static::ratio } {
Redirect traffic to A subdomain
if { $static::debug } { log local0. "redirect FROM [HTTP::uri] TO " }
HTTP::respond 301 Location "" "Cache-Control" "no-cache, must-revalidate"
Increment the counter
incr static::current
log local0. "A count is ${static::current} with ratio ${static::ratio}"
} else {
Redirect traffic to B subdomain for 40% requests
if { $static::current < $static::max } {
Redirect traffic to B subdomain
if { $static::debug } { log local0. "redirect FROM [HTTP::uri] TO " }
HTTP::respond 301 Location "" "Cache-Control" "no-cache, must-revalidate"
if { $static::debug > 1 } { log local0. "round robin is $static::round_robin" }
Increment the counter
incr static::current
log local0. "B count is ${static::current} with max ${static::max}"
} else {
If current count is 10, reset count to 0 and redirect traffic to A subdomain
if { $static::current >= $static::max } {
set static::current 0
log local0. "Reset current variable to ${static::current} "
if { $static::debug } { log local0. "redirect FROM [HTTP::uri] TO " }
HTTP::respond 301 Location "" "Cache-Control" "no-cache, must-revalidate"
TCP::close
event HTTP_REQUEST disable
}
}
}
}
}
}
7 Replies
- hoolio
Cirrostratus
Hi Christian,
Can you add the client IP:port to the log lines, enable debug, retest and reply with the logs from /var/log/ltm for a failure?
Replace:
log local0. "
with:
log local0. "[IP::client_addr]:[TCP::client_port]:
Thanks, Aaron - Christian_15126
Nimbostratus
Here are the logs. As you can see info.blah.edu, info.blah.edu/degres, and info.blah.edu/index.htm match as expected, and the 60/40 A/B load balancing also works as expected, but the irule is also matching anything past info.blah.edu, such as info.blah.edu/fake.htm, or info.blah.edu/mba.htm which is not in the match criteria.
tail -f /var/log/ltm | grep -v member
Jan 7 07:15:30 bpeca03-f501dev err mcpd[3534]: 01020066:3: The requested rule (irule_info.blah_301_controller) already exists in partition Dev.
Jan 7 07:15:30 tmm info tmm[5250]: Rule irule_info.blah_301_controller : initializing ...
Jan 7 07:15:30 tmm1 info tmm1[5251]: Rule irule_info.blah_301_controller : initializing ...
Jan 7 07:16:39 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 /mba.htm TO http://degrees.blah.edu/
Jan 7 07:16:39 tmm info tmm[5250]: Rule irule_info.blah_301_controller : A count is 1 with ratio 6
Jan 7 07:16:54 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 /blah.htm TO http://degrees.blah.edu/
Jan 7 07:16:54 tmm info tmm[5250]: Rule irule_info.blah_301_controller : A count is 2 with ratio 6
Jan 7 07:17:14 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 /degrees TO http://degrees.blah.edu/
Jan 7 07:17:14 tmm info tmm[5250]: Rule irule_info.blah_301_controller : A count is 3 with ratio 6
Jan 7 07:17:34 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 /fake.htm TO http://degrees.blah.edu/
Jan 7 07:17:34 tmm info tmm[5250]: Rule irule_info.blah_301_controller : A count is 4 with ratio 6
Jan 7 07:18:09 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 /degrees TO http://degrees.blah.edu/
Jan 7 07:18:09 tmm info tmm[5250]: Rule irule_info.blah_301_controller : A count is 5 with ratio 6
Jan 7 07:18:15 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 / TO http://degrees.blah.edu/
Jan 7 07:18:15 tmm info tmm[5250]: Rule irule_info.blah_301_controller : A count is 6 with ratio 6
Jan 7 07:18:23 tmm info tmm[5250]: Rule irule_info.blah_301_controller : redirect FROM 10.50.8.12:63030 /blah.htm TO http://onlinedegrees.blah.edu/
Jan 7 07:18:23 tmm info tmm[5250]: Rule irule_info.blah_301_controller : B count is 7 with max 10 - hoolio
Cirrostratus
Can you change the matches_glob to starts_with and retest?
Thanks, Aaron - Christian_15126
Nimbostratus
So switching from matches_glob to starts_with fixes it, but then creates another issue. Then when I try to match a path with info.blah.edu/?loadsflkjaskdfj, it doesn't match the info.blah.edu/?* (which is why I tried using matches_glob. Any idea how to catch those without breaking the rest of the code? Thanks! - hoolio
Cirrostratus
If you use starts_with info.blah.edu/? should match info.blah.edu/?adsfasdf. Can you remove the * from the variable value you're testing with?
Aaron - Christian_15126
Nimbostratus
Removing the * fixed it! I don't know why I didn't think of that before.. starts_with is the same as \?* anyways.. Thanks for your help! On a side note (but this isn't a deal breaker at all), how would I get this working using a switch statement instead of an if? I tried using a switch statement to clean up the code, but I couldn't get it to work (see below). No worries at all if it's too much work to figure out, I'm just trying to get away from if statements and move to switch to reduce code. I tried the following, but the switch statements don't seem to match correctly.. Thanks for your help!
Match subdomain.domain, with a path "/", b_path, c_path; Then A/B load balance 60/40 percent ratio.
Created 12/11/2012 Christian Henderson
Last edited 12/11/12
when RULE_INIT {
log local0. "initializing ... "
set static::debug 1
Host header variables for sub-domain and domain.
set static::a_sub "degrees"
set static::b_sub "onlinedegrees"
set static::c_sub "info"
set static::domain "blah.edu"
Path variables.
set static::b_path "\?"
set static::c_path "index.htm"
set static::d_path "degrees"
Current count variable.
set static::current 0
1 in N requests will go to B subdomain - 6 for 60/40 ratio.
set static::ratio 6
Max value to reset count.
set static::max 10
}
when HTTP_REQUEST {
F5 doesn't put the question mark in the query string
if { [HTTP::query] equals "" } { set new_query "" }
else { set new_query "?[HTTP::query]" }
if { $static::debug > 1 } { log local0. "new query string is \[$new_query\]" }
Only catch requests that come in with the proper host header, and matching /, b_path,c_path, or d_path.
if { [string tolower [HTTP::host]] equals "$static::c_sub.$static::domain" } {
Only catch clients that come in through the URI path static::a_path, static::b_path, or static::c_path
switch -glob [string tolower [HTTP::uri]] "/" -
"/$static::b_path*" -
"/$static::c_path*" -
"/$static::d_path*" {
Check for < current for 60% of traffic.
if { $static::current < $static::ratio } {
Redirect traffic to A subdomain
if { $static::debug } { log local0. "redirect FROM [HTTP::uri] TO http://${static::a_sub}.${static::domain}/$new_query" }
HTTP::respond 301 Location "http://${static::a_sub}.${static::domain}/$new_query" "Cache-Control" "no-cache, must-revalidate"
Increment the counter
incr static::current
log local0. "A count is ${static::current} with ratio ${static::ratio}"
} else {
Redirect traffic to B subdomain for 40% requests
if { $static::current < $static::max } {
Redirect traffic to B subdomain
if { $static::debug } { log local0. "redirect FROM [HTTP::uri] TO http://${static::b_sub}.${static::domain}/$new_query" }
HTTP::respond 301 Location "http://${static::b_sub}.${static::domain}/$new_query" "Cache-Control" "no-cache, must-revalidate"
if { $static::debug > 1 } { log local0. "round robin is $static::round_robin" }
Increment the counter
incr static::current
log local0. "B count is ${static::current} with max ${static::max}"
} else {
If current count is 10, reset count to 0 and redirect traffic to A subdomain
if { $static::current >= $static::max } {
set static::current 0
log local0. "Reset current variable to ${static::current} "
if { $static::debug } { log local0. "redirect FROM [HTTP::uri] TO http://${static::a_sub}.${static::domain}/$new_query" }
HTTP::respond 301 Location "http://${static::a_sub}.${static::domain}/$new_query" "Cache-Control" "no-cache, must-revalidate"
TCP::close
event HTTP_REQUEST disable
}
}
}
}
}
} - hoolio
Cirrostratus
Tcl requires special formatting to use variables as the cases in a switch statement:
See the two examples on the DC wiki page for switch for details:
https://devcentral.f5.com/wiki/iRules.switch.ashx
Here are two examples with slightly different syntax for how to use variables as switch cases. Both examples log "matched starts_with $case2: test2".
Aaron
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