Forum Discussion

Bryce_Klimoski's avatar
Bryce_Klimoski
Icon for Nimbostratus rankNimbostratus
Jun 12, 2009

HTTP::retry with post data

I have a need to retry web service requests if I receive an http response code other than a 200. The issue that I'm having is that I do not seem to be able to get the post request to work with HTTP::retry.

 

 
 when CLIENT_ACCEPTED { 
 set Attempts 1 
 } 
 when HTTP_REQUEST {  
 log local0. "Making attempt $Attempts." 
 HTTP::collect [HTTP::header Content-Length] 
 set HttpHeaders [HTTP::request] 
 log local0. "****************Start HTTP Headers****************"  
 log local0. $HttpHeaders 
 log local0. "****************End HTTP Headers****************" 
 }  
 when HTTP_REQUEST_DATA { 
 log local0. "echo 1" 
 if {$Attempts != 0} { 
 } else { 
  HttpRequest is used to retry later on. 
 set HttpPostData [HTTP::payload] 
 HTTP::release 
 log local0. "****************Start Post Data****************"  
 log local0. $HttpPostData 
 log local0. "****************End Post Data****************" 
 } 
 } 
 when HTTP_RESPONSE {  
 if { [HTTP::status] != 200 && $Attempts < [active_members [virtual name]]} {  
 incr Attempts 
 log local0. "****************Start HTTP RETRY REQUEST****************"  
 log local0. "$HttpHeaders$HttpPostData" 
 log local0. "****************End HTTP RETRY REQUEST****************" 
 HTTP::retry "$HttpHeaders$HttpPostData" 
 } else { 
 if {$Attempts >= [active_members [virtual name]]} {log local0. "$Attempts out of [active_members [virtual name]] attempts, no further retries will be made"} 
 if {[HTTP::status] == 200} { 
 set Attempts 0 
 } 
 } 
 if {[HTTP::status] == 200} { 
 set Attempts 0 
 } 
 } 
 

 

However that appears to be only sending the headers accross for some reason. Next I tried this.

 

 
  non_200_reselect iRule 
  -------- 
  Requires that the default pool name and virtual name match 
  -------- 
  History: 
  v1.0.0 (2009.03.24 - Bryce Klimoski) 
     - Initial Version 
  v1.0.1 (2009.06.08 - Bryce Klimoski) 
     - Updated to ensure compatibility with both 9.3.1 and 9.4.5 
  -------- 
  Uncomment below to enable irule timer statistics 
 timing on 
 when CLIENT_ACCEPTED { 
 set Attempts 1 
 } 
 when HTTP_REQUEST {  
 log local0. "Making attempt $Attempts." 
 if {Attempts > 1} { 
 HTTP::collect [HTTP::header Content-Length] 
 set length [HTTP::header Content-Length] 
 set HttpHeaders [HTTP::request] 
 log local0. "****************Start HTTP Headers****************"  
 log local0. $HttpHeaders 
 log local0. "****************End HTTP Headers****************" 
 } else { 
 HTTP::payload replace 0 $length $HttpPostData 
 } 
 }  
 when HTTP_REQUEST_DATA { 
 log local0. "echo 1" 
 if {$Attempts != 0} { 
 } else { 
 set HttpPostData [HTTP::payload] 
 HTTP::release 
 log local0. "****************Start Post Data****************"  
 log local0. $HttpPostData 
 log local0. "****************End Post Data****************" 
 } 
 } 
 when HTTP_RESPONSE {  
 if { [HTTP::status] != 200 && $Attempts < [active_members [virtual name]]} {  
 incr Attempts 
 log local0. "****************Start HTTP RETRY REQUEST****************"  
 log local0. $HttpHeaders 
 log local0. "****************End HTTP RETRY REQUEST****************" 
 HTTP::retry $HttpHeaders 
 } else { 
 if {$Attempts >= [active_members [virtual name]]} { 
 log local0. "$Attempts out of [active_members [virtual name]] attempts, no further retries will be made" 
 } 
 if {[HTTP::status] == 200} { 
 set Attempts 0 
 } 
 } 
 } 
 

 

That ends up giving me the following error in the ltm log.

 

 - Out of bounds (line 4)     invoked from within "HTTP::payload replace 0 $length $HttpPostData" 
 

 

 

Anybody know how this can be done?
  • I tested the following irule and looks like it uses same technique that you use (in your first irule) to retry post request.

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/HTTP_sideband_policy_checking.html

     

     

    part of the irule that relates to this is

     

     

    set request_original [HTTP::request][HTTP::payload [HTTP::header Content-Length]]

     

     

    and this

     

     

    HTTP::retry $request_original

     

     

    I wonder if it might work if you save original post request to variable without qoute (")

     

     

    set saved_post $HttpHeaders$HttpPostData

     

    HTTP::retry $saved_post

     

     

    or like this

     

     

    HTTP::retry $HttpHeaders$HttpPostData

     

     

    Nat