Forum Discussion

Scott_Hopkins's avatar
Scott_Hopkins
Icon for Nimbostratus rankNimbostratus
Aug 03, 2011

Auto retry of a request when a 500 proxy error is returned.

We're working on making application failures more seamless in the event of an application crash... and our application uses a combination of the GET and POST methods. Is there a way (or even an easy way) to resubmit these messages to another pool member if a 500 error response is received?
  • Take a look at these...

     

    http://devcentral.f5.com/Default.aspx?tabid=53&aft=15752

     

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

     

     

  • Hi Scott,

     

     

    As boomchke pointed out it is possible to retry requests based on the response code. The overhead of saving every request's headers might not be horrible. But I'd be concerned with trying to do this for POST requests also. You will need to manually collect the payload for all POSTs. Another issue is that you cannot currently collect more than 4Mb of data. So you should check the Content-Length header to make sure it's less than 4Mb before trying to buffer the request data:

     

     

    sol6578: TMM will crash if an iRule collects more than 4 megabytes of data

     

    http://support.f5.com/kb/en-us/solutions/public/6000/500/sol6578.html

     

     

    Aaron
  • I started some work on a concept rule that would allow you to take chunks of the HTTP data and store in separate variables (from some code from Deb a while back). The chunk part is working in a clean collect/release method, and I had a working model of storing the chunks in variables (though I've misplaced that code now). What I hadn't done yet is figure out how to after something like a response, re-gather all the data for release to the server. Anyway, if you want to fiddle, here's the start:

     

     

    
    when HTTP_REQUEST {
    if { [HTTP::method] == "POST" } {
    set collected 0
    if { [HTTP::header exists "Content-Length"] } {
    set content_len [HTTP::header Content-Length]
    } else {
    set content_len 0
    }
    if { $content_len > 0 && $content_len < 524289 } {
    set collect_len $content_len
    } else {
    set collect_len 524288
    }
    if { $collect_len > 0 } {
    HTTP::collect $collect_len
    }
    }
    }
    when HTTP_REQUEST_DATA {
    if { $content_len > 0 } {
    set collected [expr {$collected + $collect_len}]
    set remaining [expr {$content_len - $collected}]
    if { $remaining > 0 } {
    if { $remaining < $collect_len } {
    HTTP::collect $remaining
    HTTP::release
    return
    }
    HTTP::collect $collect_len
    }
    }
    }