Forum Discussion

Deon's avatar
Deon
Icon for Nimbostratus rankNimbostratus
Oct 14, 2011

Multiple iRule Redirects, event disable, TCP::close

We have multiple iRules and each can do a redirect based on a condition in HTTP_REQUEST event. I added an event disable after the redirect in each iRule so that I don't have multiple redirects happening. I just noticed a side effect with this setup in that the event remains disabled for the duration of the connection and if a subsequent request comes on the same connection then the iRule does not function like I desire it to. I realize this is because the event disable is scoped to the connection and not the particular request. I've read the posts that discuss setting a local variable and checking the value of that in the other iRules. This seems like a lot of logic to add to many different iRules. Is there an alternative way of doing this with TCP::close following the redirect?

 

 

What is the downside of the following with the TCP::close added?

 

 

 

when HTTP_REQUEST {

 

if { ([HTTP::uri] equals "/") } {

 

HTTP::redirect "https://www.mycompany.com/myapproot"

 

TCP::close

 

event disable

 

}

 

}

 

 

 

 

Thanks

 

-Deon

 

  • Hi Deon,

     

     

    As you found out the "event disable" will disable the HTTP_REQUEST Event for the duration of the connection.

     

     

    What you can do is a "return" to escape the event from further processing.

     

     

    http://devcentral.f5.com/wiki/iRules.return.ashx

     

     

    Give it a try and see if it corrects your issue.

     

     

    Hope this helps.
  • What you can do is a "return" to escape the event from further processing.i understand return does not stop processing other event.

    What is the downside of the following with the TCP::close added?i do not see any downside except client has to create a new tcp connection.

    [root@iris:Active] config  b virtual bar list
    virtual bar {
       snat automap
       pool foo
       destination 172.28.17.33:http
       ip protocol tcp
       rules {
          myrule
          myrule2
       }
       profiles {
          http {}
          tcp {}
       }
    }
    [root@iris:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST priority 100 {
            if {[HTTP::uri] equals "/"} {
                    HTTP::redirect "http://172.28.17.33/myapproot"
                    TCP::close
                    event disable
            }
            log local0. "client [IP::remote_addr]:[TCP::remote_port], uri [HTTP::uri]"
    }
    }
    [root@iris:Active] config  b rule myrule2 list
    rule myrule2 {
       when HTTP_REQUEST {
            log local0. "client [IP::remote_addr]:[TCP::remote_port], uri [HTTP::uri]"
    }
    }
    
    [root@iris:Active] config  tail -f /var/log/ltm
    Oct 15 16:47:58 local/tmm info tmm[4601]: Rule myrule : client 192.168.206.102:62770, uri /
    
    since redirect was sent on existing tcp connection, http event was not triggered.
    
    [root@iris:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST priority 100 {
            if {[HTTP::uri] equals "/"} {
                    HTTP::redirect "http://172.28.17.33/myapproot"
                    TCP::close
                    event disable
            }
            log local0. "client [IP::remote_addr]:[TCP::remote_port], uri [HTTP::uri]"
    }
    }
    
    [root@iris:Active] config  tail -f /var/log/ltm
    Oct 15 17:09:48 local/tmm info tmm[4601]: Rule myrule : client 192.168.206.102:62848, uri /
    Oct 15 17:09:48 local/tmm info tmm[4601]: Rule myrule2 : client 192.168.206.102:62848, uri /
    Oct 15 17:09:48 local/tmm info tmm[4601]: Rule myrule : client 192.168.206.102:62849, uri /myapproot
    Oct 15 17:09:48 local/tmm info tmm[4601]: Rule myrule2 : client 192.168.206.102:62849, uri /myapproot
    
    [root@iris:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST priority 100 {
            if {[HTTP::uri] equals "/"} {
                    HTTP::redirect "http://172.28.17.33/myapproot"
                    TCP::close
                    event disable
            }
            log local0. "client [IP::remote_addr]:[TCP::remote_port], uri [HTTP::uri]"
    }
    }
    
    [root@iris:Active] config  tail -f /var/log/ltm
    Oct 15 17:11:40 local/tmm info tmm[4601]: Rule myrule : client 192.168.206.102:62860, uri /
    Oct 15 17:11:40 local/tmm info tmm[4601]: Rule myrule : client 192.168.206.102:62861, uri /myapproot
    Oct 15 17:11:40 local/tmm info tmm[4601]: Rule myrule2 : client 192.168.206.102:62861, uri /myapproot
    
    
  • Deon's avatar
    Deon
    Icon for Nimbostratus rankNimbostratus
    Hi nitass. Thanks for the assistance. I think your testing scenarios show the TCP::close and the event disable together accomplish what I need. I appreciate your help.
    • Magnum_IP's avatar
      Magnum_IP
      Icon for Nimbostratus rankNimbostratus
      It is a happy day when you find the answer to the exact issue you are having on DevCentral ;-) The solution works like a charm. A thought that did cross my mind was if there was any potential performance hit from creating new tcp connections per request especially on an https virtual server? I will need to lab this up and run a test.
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    Another option is to set a semaphore everywhere an iRule uses HTTP::response (HTTP::redirect counts as an HTTP::response). Although not as efficient, it does make it easier to prevent multiple responses - especially if there are multiple iRules and multiple iRule developers.