Forum Discussion

NiHo_202842's avatar
NiHo_202842
Icon for Cirrostratus rankCirrostratus
Sep 16, 2016

What to do after HTTP::respond ?

Hello,

I currently have a maintenance-unavailable iRule that returns a HTML page when the vs is in maintenance mode (value in datagroup list) or is not available. (LB_FAILED)

My first check is if the URI is an image that is linked to in the page. If yes, HTTP::respond with a Connection: Close header, disable all future iRule events & TCP::close. This seems a very hacky way of doing this. I manually close the TCP connection because for some apps, we have an IIS request forwarder in front of the bigip that may do connection pooling; event disable all would disable all iRules for all applications on that TCP connection.

How are you all doing this?

 

priority 50

when HTTP_REQUEST {

    if { [HTTP::uri] eq "/bip-company-logo.gif" }{
        HTTP::respond 200 content [ifile get "company-logo"] noserver Content-Type image/gif Connection Close
        event disable all
        TCP::close
        return
    }

    if { [class match -value [virtual name] equals "maintenance-list"] eq "1" } {

        if { [HTTP::uri] eq "/favicon.ico" }{
            HTTP::respond 404 noserver Connection Close
            event disable all
            TCP::close
            return
        }

        if { [virtual name] starts_with "/ITSS/" }{
            set contact "your Regional Helpdesk"
        } else {
            set contact "Application Support () or your Regional Helpdesk" 
        }

        HTTP::respond 200 content "


        
        Down for maintenance - company


        
                
                        
                        Maintenance
                        
                        
                
                
                
                
                
                        This application is currently undergoing maintenance.
                        It should be available again within the specified time period.
                
                
                
                        For any questions, please contact $contact.
                
        

" noserver Connection Close
        event disable all
        TCP::close
    }
}

when LB_FAILED {

    if { [virtual name] starts_with "/ITSS/" }{
       set contact "your Regional Helpdesk"
    } else {
        set contact "Application Support () or your Regional Helpdesk"
    }

    HTTP::respond 503 content "

    
            
            
            Application Unavailable - company
    
    
            
                    
                            
                            Application unavailable
                            
                            
                    
                    
                    
                    
                    
                            This application is currently not available.
                            Please contact $contact.
                    
            
    
" noserver Connection Close
    event disable all
    TCP::close
}

 

  • Hi NiHo,

    if you need to temporary disable further iRule processing without closing the connection. You may try to issue a [event disable all] as usual within your iRule. And then deploy a simple LTM Policy which reenables the iRule processing on each subsequent HTTP request.

    LTM Policy Condition:

    • None

    LTM Policy Action:

    • Target: TCL
    • Event: request
    • Action: set-variable
    • Name: dummy_var
    • Expression: [event enable all]

    Cheers, Kai

  • Connection Close header instructs customer's browser to close the old TCP connection. It's much more kosher than just bluntly doing TCP::close which will only tear down the connection in BigIP, but not in customer's browser. Also note that you will never need to use TCP::close and Connection Close in the same conditional routine. The return function has no functional value in your use-cases, but it does no harm to keep it for readability (some admins might prefer). The event disable all function can be safely replaced by just event disable.

    I've adjusted one of your conditional routines. That's how you can provide the same functions while using less lines of code.

     

    if { [HTTP::uri] eq "/bip-company-logo.gif" }{
        HTTP::respond 200 content [ifile get "company-logo"] noserver Content-Type image/gif Connection Close
        event disable
    }
    

     

     

    • Hannes_Rapp_162's avatar
      Hannes_Rapp_162
      Icon for Nacreous rankNacreous

      As a general rule, a LTM Local Traffic Policy should be preferred over iRule for performance reasons. In case of maintenance iRules/Policies, instead of serving all the static content from BigIP, I'd recommend issuing a 302 temp redirect to a specialized splash/maintenance service that is managed by the application owners, not middleware admins.

    • NiHo_202842's avatar
      NiHo_202842
      Icon for Cirrostratus rankCirrostratus

      Hi Hannes, thank you for your response. Will an event disable then trigger a stop of the irule processing? (like return does)

       

    • Hannes_Rapp_162's avatar
      Hannes_Rapp_162
      Icon for Nacreous rankNacreous

      No, you don't need to use return to stop iRule processing. It serves no use.

       

      'event disable' stops processing of the event (HTTP_REQUEST) in this, and all other iRules attached to VS. Unlike with 'event disable all', it does not stop processing of other events in this, or any other iRule.

       

  • Connection Close header instructs customer's browser to close the old TCP connection. It's much more kosher than just bluntly doing TCP::close which will only tear down the connection in BigIP, but not in customer's browser. Also note that you will never need to use TCP::close and Connection Close in the same conditional routine. The return function has no functional value in your use-cases, but it does no harm to keep it for readability (some admins might prefer). The event disable all function can be safely replaced by just event disable.

    I've adjusted one of your conditional routines. That's how you can provide the same functions while using less lines of code.

     

    if { [HTTP::uri] eq "/bip-company-logo.gif" }{
        HTTP::respond 200 content [ifile get "company-logo"] noserver Content-Type image/gif Connection Close
        event disable
    }
    

     

    • Hannes_Rapp's avatar
      Hannes_Rapp
      Icon for Nimbostratus rankNimbostratus

      As a general rule, a LTM Local Traffic Policy should be preferred over iRule for performance reasons (see Kai's post here: https://devcentral.f5.com/questions/advantages-of-local-traffic-policies-vs-irules). In case of maintenance iRules/Policies, instead of serving all the static content from BigIP, I'd recommend issuing a 302 temp redirect to a specialized splash/maintenance service that is managed by the application owners, not middleware admins.

       

    • Hannes_Rapp's avatar
      Hannes_Rapp
      Icon for Nimbostratus rankNimbostratus

      No, you don't need to use return to stop iRule processing. It serves no use.

       

      'event disable' stops processing of the event (HTTP_REQUEST) in this, and all other iRules attached to VS. Unlike with 'event disable all', it does not stop processing of other events in this, or any other iRule.

       

    • Hannes_Rapp's avatar
      Hannes_Rapp
      Icon for Nimbostratus rankNimbostratus

      Hello Kai,

       

      Yes, it's a quite nasty iRule indeed. I used to do similar iRules for maintenance a few years ago. Now I realize F5 doesn't need to be a dumpster of HTML pages and static images just because the functionality is there. It's best to just collaborate with apps team to migrate any maintenance HTML and static content to Apache/NIX (or better yet, CDN).

       

      If he could do the above, moving to a Local Traffic policy will no longer be that difficult. I do agree with you that iRules are still needed. They even took some LTM policy functionality out since v12, instead of adding any new :(