Forum Discussion

GavinW_29074's avatar
GavinW_29074
Icon for Nimbostratus rankNimbostratus
Feb 02, 2012

Streamline error and response handling...

Hi there,

 

 

Currently we've got several rules set-up to do various functions.

 

A couple of examples are:

 

* Maintenance page handling

 

* Application error handling

 

* SSL Client verification handling

 

* Timeout handling

 

 

Several of these rules also include HTTP::Respond functions where we want to return specific content back to the client, such as a maintenance page or a sorry page...

 

 

Having these functions in multiple rules is becoming difficult to manage efficiently...

 

 

What I want to do is streamline the response handling into one iRule, and have the other rules set a variable or similar if there's an issue... This can then be handled by the response iRule as appropriate.

 

This is also necessary because we need to be able to provide tailored error pages for certain VIPs. I can see this being easily achieved by substituting variables on a HTML error page based of Datagroup lookups... However in order for this to be practical, I need to get the response logic contained to one iRule...

 

 

What's the best way to achieve this?

 

 

I've seen the session command mentioned, but I'm not sure exactly how to use it in this scenario...

 

 

Any guidance appreciated, and thanks in advance.

 

 

Regards

 

Gavin

 

  • Ok, after some further googling, I think I may have answered my own question...

    This thread was quite useful in highlighting the options - http://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/50/aft/1172260/showtab/groupforums/Default.aspx

    So I've set-up a couple of test rules:-

    SetVariable -

    when CLIENT_ACCEPTED {
    set vari "[IP::client_addr]:[TCP::client_port]"
    log local0.info "Variable has been set..."
    }  

    LogVariable -

    when HTTP_REQUEST {
    
    log local0.info "HTTP Request from $vari"
    
    } 

    Assigning these to a VIP and attempting to connect logs the following:

    Feb 2 11:58:36 tmm info tmm[9144]: Rule /Common/SetVariable : Variable has been set...

    Feb 2 11:58:36 tmm info tmm[9144]: Rule /Common/LogVariable : HTTP Request from 192.168.150.24:42438

    Is this a practical approach? Or am I better off using some of the more advanced session functionality?

    Cheers

    Gavin
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    Using a variable is almost certainly the best approach here, since it seems like you'll always be doing your HTTP::respond on the same connection as you detect all your error conditions. The session table would be overkill for this, and more complicated.
  • Ok, after a bit of experimentation, I came up with this:

     

     

    when RULE_INIT {
    
    set static::RespondDebug 1
    
    set static::unavailable_page [ifile get unavailable_page_html]
    set static::offline_page [ifile get offline_page_html]
    set static::secure_failure_page [ifile get secure_connection_failure_html]
    set static::act_logo [ifile get act_logo_png]
    
    }
    
    when CLIENT_ACCEPTED priority 1 {
    
    if {$static::RespondDebug > 0} { log local0.info "Processing CLIENT_ACCEPTED at priority 1" }
    
     Set-up base variables.
    set pool_error 0
    set maintenance_mode 0
    set ssl_error 0
    set failure_result ""
    set response_error 0
    
    if {$static::RespondDebug > 0} { log local0.info "Variables set: \$pool_error = $pool_error, \$maintenance_mode = $maintenance_mode, \$ssl_error = $ssl_error, \$failure_result = '$failure_result', \$response_error = $response_error" }
    }
    
    when HTTP_REQUEST priority 20 {
    
    if {$static::RespondDebug > 0} { log local0.info "Processing HTTP_REQUEST at Priority 20..." }
    if {$static::RespondDebug > 0} { log local0.info "\$maintenance_mode = $maintenance_mode, \$ssl_error = $ssl_error, \$failure_result = '$failure_result'" }
    
     Catch ACT Logo and return. 
    if { [HTTP::uri] ends_with "logo-act.png" } {
    if {$static::RespondDebug > 0} { log local0.info "Returning ACT Logo..." }
    HTTP::respond 200 content $static::act_logo "Content-Type" "image/png" "Connection" "Close"
    TCP::close
    event disable
    return
    } 
    
     Handle maintenance mode.
    if {$maintenance_mode} {
    if {$static::RespondDebug > 0} { log local0.info "Returning Maintenance page html..." }
    
    switch -glob [HTTP::method] {
    POST {
    if {$static::RespondDebug > 0} { log local0.info "POST Method - Returning Code 503" }
    HTTP::respond 503 
    event disable
    return
    }
    GET {
    if {$static::RespondDebug > 0} { log local0.info "GET Method - Returning HTML and Code 200" }
    HTTP::respond 200 content $static::offline_page "Content-Type" "text/html" 
    event disable
    return
    }
    }
    TCP::close
    }
    
     Handle SSL error
    if {$ssl_error} {
    if {$static::RespondDebug > 0} { log local0.info "Returning SSL Error page html..." }
    HTTP::respond 403 content [subst $static::secure_failure_page] "Content-Type" "text/html"
    event disable
    TCP::close
    return
    }
    
    }
    
    when HTTP_REQUEST priority 750 {
    if {$static::RespondDebug > 0} { log local0.info "Processing HTTP_REQUEST at Priority 750..." }
    if {$static::RespondDebug > 0} { log local0.info "\$pool_error = $pool_error" }
    
     Handle error page.
    if {$pool_error} {
    
    switch -glob [HTTP::method] {
    POST {
    if {$static::RespondDebug > 0} { log local0.info "POST Method - Returning Code 503" }
    HTTP::respond 503 
    event disable
    return
    }
    GET {
    if {$static::RespondDebug > 0} { log local0.info "GET Method - Returning HTML and Code 200" }
    HTTP::respond 503 content $static::unavailable_page "Content-Type" "text/html"
    event disable
    return
    }
    }
    
    TCP::close
    
    }
    
    if {$static::RespondDebug > 0} { log local0.info "Passed error checking... Continuing..." }
    return 
    
    }
    
    when HTTP_RESPONSE priority 250 {
    if {$static::RespondDebug > 0} { log local0.info "Processing HTTP_RESPONSE... at Priority 250" }
    if {$static::RespondDebug > 0} { log local0.info "\$response_error = $response_error" }
    
    if {$response_error} {
    switch -glob [string toupper $HTTP_METHOD] {
    "POST" {
    if {$static::RespondDebug > 0} { log local0.info "POST Method - Returning Code 503" }
    HTTP::respond 503 
    event disable
    return
    }
    "GET" {
    if {$static::RespondDebug > 0} { log local0.info "GET Method - Returning HTML and Code 200" }
    HTTP::respond 200 content $static::unavailable_page "Content-Type" "text/html"
    event disable
    return
    }
    }
    }
    
    } 

     

     

    Comment welcome.

     

     

    Cheers

     

    Gavin