Forum Discussion

jrok_47156's avatar
jrok_47156
Icon for Nimbostratus rankNimbostratus
Dec 03, 2012

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

  • 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.
  • 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

     

    }

     

  • 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 : /
    
    
  • 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
  • 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.

     

  • 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?

     

  • 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.
  • 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?

     

  • 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