Forum Discussion
irule switch statement not matching header or paths
Marketing has hit me with another irule fun project. This is what they want me to accomplish:
They want 60/40 split load balancing between the following URL's:
-------------- 40% -------------------------- ------------>> -------------- 60% --------------------------
http://blah.domain.com/ba-business-admin.htm ---> http://bleeg.domain.com/baBusinessAdministration.htm
http://blah.domain.com/ba-psychology.htm ---> http://bleeg.domain.com/baPsychology.htm
http://blah.domain.com/ma-education.htm ---> http://bleeg.domain.com/maEducation.htm
http://blah.domain.com/ba-law-enforcement.htm ---> http://bleeg.domain.com/baLawEnforc...ration.htm
http://blah.domain.com/ba-journalis...cation.htm ---> http://bleeg.domain.com/baJournalis...cation.htm
ADDITIONAL REQUIREMENT:
Append a parameter to the URL to indicate percentage. For example: redirect=true
They also want any existing query variables passed through in addition to appending redirect=true. To avoid having a huge ass irule and five seperate irules for each 60/40 split, I've come up with. The irule passes the sanity check in notepad++ and irule editor, but when I try to hit blah.domain.com/anymatch, all I get is "new query string is \[$new_query\]". I tried turning on logging for the increment variable count and uri and redirect actions, but it seems like the irule doesn't even get there or doesn't successfully match the paths. Am I missing something fundamental here? I know how to make this work with straight if/else statements, but it will be really long and ugly, so I'm strying to 'switch' my brain (pun intended) into using switch instead of if/else statements wherever possible. Any help would be appreciated. CH
when RULE_INIT {
log local0. "initializing ... "
set static::debug 1
Host header variables for sub-domain and domain.
set static::a_sub "blah"
set static::b_sub "bleeg"
set static::domain "domain.com"
Path variables.
set static::a_Apath "ba-business-admin.htm"
set static::a_Bpath "baBusinessAdministration.htm"
set static::b_Apath "ba-psychology.htm"
set static::b_Bpath "baPsychology.htm"
set static::c_Apath "ma-education.htm"
set static::c_Bpath "maEducation.htm"
set static::d_Apath "ba-law-enforcement.htm"
set static::d_Bpath "baLawEnforcementAdministration.htm"
set static::e_Apath "ba-journalism-mass-communication.htm"
set static::e_Bpath "baJournalismMassCommunication.htm"
Marketing variable
set static::mktgvar "redirect=true"
Current count variable.
set static::current 0
1 in N requests will go to B subdomain - 6 for 60/40 ratio.
set static::ratio 4
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\]" }
switch -glob [string tolower [HTTP::header "$static::a_sub.$static::domain"]] {
"/$static::a_Apath*" {
if { "$static::current < $static::ratio" } {
incr static::current
HTTP::uri [string tolower "/${static::a_Apath}${new_query}${static::mktgvar}" ]
} elseif { "$static::current < $static::max" } {
incr static::current
HTTP::respond 301 Location "}" "Cache-Control" "no-cache, must-revalidate"}
}
"/$static::b_Apath*" {
if {"$static::current < $static::ratio" } {
incr static::current
HTTP::uri [string tolower "/${static::b_Apath}${new_query}${static::mktgvar}" ]
} elseif { "$static::current < $static::max" } {
incr static::current
HTTP::respond 301 Location "}" "Cache-Control" "no-cache, must-revalidate"}
}
"/$static::c_Apath*" {
if { "$static::current < $static::ratio" } {
incr static::current
HTTP::uri [string tolower "/${static::c_Apath}${new_query}${static::mktgvar}" ]
} elseif { "$static::current < $static::max" } {
incr static::current
HTTP::respond 301 Location "}" "Cache-Control" "no-cache, must-revalidate"}
}
"/$static::d_Apath*" {
if { "$static::current < $static::ratio" } {
incr static::current
HTTP::uri [string tolower "/${static::d_Apath}${new_query}${static::mktgvar}" ]
} elseif { "$static::current < $static::max" } {
incr static::current
HTTP::respond 301 Location "}" "Cache-Control" "no-cache, must-revalidate"}
}
"/$static::e_Apath*" {
if { "$static::current < $static::ratio" } {
incr static::current
HTTP::uri [string tolower "/${static::e_Apath}${new_query}${static::mktgvar}" ]
} elseif { "$static::current < $static::max" } {
incr static::current
HTTP::respond 301 Location "}" "Cache-Control" "no-cache, must-revalidate"}
}
default {
set static::ratio 0
TCP::close
event HTTP_REQUEST disable
}
}
}
9 Replies
- nitass
Employee
switch -glob [string tolower [HTTP::header "$static::a_sub.$static::domain"]] {what string do you want to match? is it http host header (HTTP::host), path (HTTP::path) or uri (HTTP::uri)?
incr static::currenti do not think you should alter static global variable value anyway. - Christian_15126
Nimbostratus
With the following variables (leaving our the host and path variables to make is simple):
current == 0
ratio == 4
max == 10
mktvar == redirect=true
I'm trying to match:
HTTP:;host
AND HTTP::path
AND current < ratio
APPEND TO PATH w/ HTTP::query AND mktgvar
INCR current
OR current < max
301 REDIRECT w/ HTTP::query AND mktgvar
INCR current
(Rinse and repeat five times for five different paths and redirects)
OR
(To close the loop, reset the count to 0, close out the session. and the event)
SET current == 0
TCP close
EVENT disable
I know how to do it with just if/else statements, but it's uggly.. - What_Lies_Bene1
Cirrostratus
If the more variable item is the paths I'd suggest this kind of structure;
1) An if on the host
-2) A switch on the path
--3) Further if statements on the rest
It still won't be great but it should look a little better. If you need an example for 'switch' just say and I'll post one. - Christian_15126
Nimbostratus
That would be great! I'm having issues getting my switch commands to read the variables to be matched in my irule.. They work fine with just if/else statements. - What_Lies_Bene1
Cirrostratus
OK, here's a simple example. If you don't need the * wildcards, you can omit the -glob;when HTTP_REQUEST { switch -glob [string tolower [HTTP::host]] { If HTTP host contains abc or def, redirect to xyz.com "*abc*" - "*def*" { HTTP::redirect https://www.xyz.com/xyz } If HTTP host contains ghi, redirect to mno.com "*ghi*" { HTTP::redirect https://www.mno.com/mno } If HTTP host is none of the above, take the default action below default { HTTP::redirect "https://[HTTP::host][HTTP::uri]" } } }
Sorry, no time to customise to your rule but hopefully this give you an idea. - Christian_15126
Nimbostratus
What about if you need to use a switch to match variables for the host header or path? That's the part I'm stuck on. Thanks for your help! - What_Lies_Bene1
Cirrostratus
This perhaps;when HTTP_REQUEST { switch -glob [string tolower $variable-name] { "*abc*" - "*def*" { HTTP::redirect https://www.xyz.com/xyz } "*ghi*" { HTTP::redirect https://www.mno.com/mno } default { HTTP::redirect "https://[HTTP::host][HTTP::uri]" } } } - What_Lies_Bene1
Cirrostratus
Apologies Christian but troubleshooting this rule is somewhat beyond me (for now). - Christian_15126
Nimbostratus
No worries, this one was a total nightmare, but I appreciate your guys assistance!
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