Forum Discussion
pool down redirect problem
...this is my init rule, it has some globals used in the later irule
when RULE_INIT {
sets number of seconds to wait before a maintenance retry
set ::wwwqawait 10
set the protcol to be used for all redirects
set ::wwwqaprot "https://"
set hostname for this virtual
set ::wwwqahost "www.site.com"
set failover directory for this virtual
set ::wwwqafail "/maintenance"
set pool name for this virtual
set ::wwwqapool "Test_POOL"
}
...this is the irule with my problem
when HTTP_REQUEST {
check to make sure connection is secure
if { [TCP::local_port] != 443 }
{
HTTP::redirect $::wwwqaprot[HTTP::host][HTTP::uri]
}
make sure a short host (2-part) is a correct match for our certificate (3-part) *.site.com
such as building up site.com (2-part) to www.site.com (3-part)
if there is no 3rd field at the end, then there's only two at the beginning
if { [string length [getfield [HTTP::host] "." 3]] == 0}
{
HTTP::redirect $::wwwqaprot$::wwwqahost[HTTP::uri]
}
make sure a long host (4-part) is a correct match for our certificate (3-part) *.site.com
such as stripping down www.sub.site.com (4-part) to sub.site.com (3-part)
if there is a 4th field at the end (.com), then there's a 1st something at the beginning (likely www.)
if { [string length [getfield [HTTP::host] "." 4]] > 0}
{
HTTP::redirect $::wwwqaprot[domain [HTTP::host] 3][HTTP::uri]
}
check to see if the URI of the request starts with /maintenance
if { [string tolower [HTTP::uri]] starts_with "$::wwwqafail" } {
HTTP::respond 200 content "\
\ blah, site down \
" noserver "Content-Type" "text/html"
return
}
check to see if the pool is down. if so, redirect to the maintenance page
if { [active_members $::wwwqapool] < 1 }
{
HTTP::redirect $::wwwqaprot$::wwwqahost$::wwwqafail
}
end http request block
}
when HTTP_RESPONSE {
HTTP::header remove Server
}
...ok, when the pool is up, everything works fine, I can even invoke the /maintenance URI and get it to kick over to the site. but when the pool is down it throws this error:
TCL error: wwwqa_20_ssl - Operation not supported. Multiple redirect/respond invocations not allowed (line 52) invoked from within "HTTP::redirect $::wwwqaprot$::wwwqahost$::wwwqafail"
...thanks for any help
9 Replies
- Tim_K_92675
Cirrostratus
Most likely the error is occurring because one of the http::redirect or http::respond events has already been applied from one of the logic statements prior to line 52. However, there can be only one http response per request. - jrok_47156
Nimbostratus
Ok thanks. I think I understand. It flows through and finds the /maintenance and applies that as the response, then it hits the pool_down and also tries to apply that as a response. Is that right?
I ended up making three irules. The first one isn't attached to anything it just initializes the global variables. The second one checks for the uri of /maintenance and then calls an "event disable all". The third one then corrects certificate errors and status of the pool. Is this a proper way to do it?
...iRule number one (not assigned)
when RULE_INIT {
set ::wwwqawait 10
set ::wwwqaprot "https://"
set ::wwwqahost "www.site.com"
set ::wwwqafail "/maintenance"
set ::wwwqapool "Test_POOL"
}
...iRule number two
when HTTP_REQUEST {
check to see if the URI of the request starts with /maintenance
if { [string tolower [HTTP::uri]] starts_with "$::wwwqafail" }
{
HTTP::respond 200 content blah-server-down
...redirects to wwwqahost in wwqawait seconds...
event disable all
}
...iRule number three
when HTTP_REQUEST {
check to make sure connection is secure
if { [TCP::local_port] != 443 }
{
HTTP::redirect $::wwwqaprot[HTTP::host][HTTP::uri]
}
make sure a short host (2-part) is a correct match for our certificate (3-part)
if { [string length [getfield [HTTP::host] "." 3]] == 0}
{
HTTP::redirect $::wwwqaprot$::wwwqahost[HTTP::uri]
}
make sure a long host is a correct match for our certificate
if { [string length [getfield [HTTP::host] "." 4]] > 0}
{
HTTP::redirect $::wwwqaprot[domain [HTTP::host] 3][HTTP::uri]
}
check to see if the pool is down. if so, redirect to the maintenance page
if { [active_members $::wwwqapool] < 1 }
{
HTTP::redirect $::wwwqaprot$::wwwqahost$::wwwqafail
}
end http request block
}
when HTTP_RESPONSE {
HTTP::header remove Server
}
- nitass
Employee
The second one checks for the uri of /maintenance and then calls an "event disable all".i understand event disable will prevent this irule being triggered by subsequence request in this connection such as image inside html file.without event disable [root@ve10:Active] config b virtual bar list virtual bar { snat automap pool foo destination 172.28.19.79:80 ip protocol 6 rules { rule1 rule2 } profiles { http {} tcp {} } } [root@ve10:Active] config b rule rule1 list rule rule1 { when HTTP_REQUEST priority 10 { log local0. [HTTP::uri] } } [root@ve10:Active] config b rule rule2 list rule rule2 { when HTTP_REQUEST priority 20 { log local0. [HTTP::uri] } } [root@ve10:Active] config tail -f /var/log/ltm Dec 5 00:59:16 local/tmm info tmm[7926]: Rule rule1 : / Dec 5 00:59:16 local/tmm info tmm[7926]: Rule rule2 : / Dec 5 00:59:16 local/tmm info tmm[7926]: Rule rule1 : /f5.gif Dec 5 00:59:16 local/tmm info tmm[7926]: Rule rule2 : /f5.gif with event disable [root@ve10:Active] config b rule rule1 list rule rule1 { when HTTP_REQUEST priority 10 { log local0. [HTTP::uri] event disable all } } [root@ve10:Active] config b rule rule2 list rule rule2 { when HTTP_REQUEST priority 20 { log local0. [HTTP::uri] } } [root@ve10:Active] config tail -f /var/log/ltm Dec 5 01:00:42 local/tmm info tmm[7926]: Rule rule1 : / - nitass
Employee
since 9.4.4, :: and $:: prefixes are no longer required for reference data group. class is cmp compatible.
sol13033: Constructing CMP-compatible iRules
http://support.f5.com/kb/en-us/solutions/public/13000/000/sol13033.html
there is static global variable in v10.x which is cmp compatible.
v.10 - A new iRules Namespace by Colin
https://devcentral.f5.com/tutorials/tech-tips/v10-a-new-irules-namespace - jrok_47156
Nimbostratus
I am sure you are correct, but the way I am sequencing the rules *seems* to make it work.
*** site is up ***
request passes through /maintenance checker - Rule 2
pool is up, complete request - Rule 3
*** site is down ***
request passes through /maintenance checker - Rule 2
pool is down, redirect to uri /maintenance - Rule 3
request gets caught by /maintenance checker - Rule 2
html page (just html text) shows down message and sets retry of site in 10 seconds - Rule 2
call to event disable all stop other rules while waiting for retry - Rule 2
...10 seconds pass, call to site
if site is up, it goes through ***site is up from above
if site still down, goes through ***site is down from above until site comes back up
it seems to be working but I'm not sure this is the proper way. - jrok_47156
Nimbostratus
I saw those references with and wthout the :: prefixes and also the static declaration. Unfortunately I am a lowly application developer and do not know what version of F5 we are on. Nobody here knows how to write irules so I had to learn recently. If we are on the right version should I change to static?
- nitass
Employee
request gets caught by /maintenance checker - Rule 2
html page (just html text) shows down message and sets retry of site in 10 seconds - Rule 2
call to event disable all stop other rules while waiting for retry - Rule 2i see. maintenance page is only text.
if site is up, it goes through ***site is up from aboveis it always new tcp connection?
If we are on the right version should I change to static?yes, i would do. - jrok_47156
Nimbostratus
Posted By nitass on 12/04/2012 09:49 AM
if site is up, it goes through ***site is up from above is it always new tcp connection?
If we are on the right version should I change to static? yes, i would do.
I guess the checker html page will get the browser to make a new http (tcp) request after 10 seconds. This particular site is a web portal running only ssl. There are no other protocols allowed. Is that what you mean?Also, I discovered on the dashboard that the F5 is on Version 10.2.2 (Build 930). So, that being the case, I should change my init variables to static and I *do not* have to prefix them with :: correct?
- nitass
Employee
I guess the checker html page will get the browser to make a new http (tcp) request after 10 seconds.if it is always new tcp connection, i think your irule will work just fine.
I should change my init variables to static and I *do not* have to prefix them with :: correct?i understand it could look like this.
declaration
set static::wwwqawait 10
using
$static::wwwqawait
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