@@ -230,6 +230,7 @@ func TestDoExponentialBackoff(t *testing.T) {
230230 name string
231231 options []ExponentialBackoffOption
232232 handler http.HandlerFunc
233+ requestBody io.Reader
233234 wantBody string
234235 wantErr string
235236 wantAttempts int
@@ -323,6 +324,55 @@ func TestDoExponentialBackoff(t *testing.T) {
323324 wantErr : "" ,
324325 wantAttempts : 3 ,
325326 },
327+ {
328+ name : "RequestBodyCopiedOnRetry" ,
329+ options : []ExponentialBackoffOption {
330+ ExponentialBackoffWithConfig (4 , 100 * time .Millisecond , 5 * time .Second , 2.0 ),
331+ },
332+ handler : func () http.HandlerFunc {
333+ initialBody := "request body content"
334+
335+ attempts := 0
336+ return func (w http.ResponseWriter , r * http.Request ) {
337+ attempts ++
338+
339+ if r .ContentLength != int64 (len (initialBody )) {
340+ w .WriteHeader (http .StatusInternalServerError )
341+ _ , _ = fmt .Fprintf (w , "wrong content-length: got %d, want %d" , r .ContentLength , len (initialBody ))
342+ return
343+ }
344+
345+ body , err := io .ReadAll (r .Body )
346+ if err != nil {
347+ w .WriteHeader (http .StatusInternalServerError )
348+ return
349+ }
350+
351+ if len (body ) != len (initialBody ) {
352+ w .WriteHeader (http .StatusInternalServerError )
353+ _ , _ = fmt .Fprintf (w , "content-length mismatch: header=%d actual=%d" , r .ContentLength , len (body ))
354+ return
355+ }
356+
357+ // Verify body is correctly sent on all attempts
358+ if string (body ) != initialBody {
359+ w .WriteHeader (http .StatusInternalServerError )
360+ _ , _ = fmt .Fprintf (w , "incorrect body: %q" , string (body ))
361+ return
362+ }
363+ if attempts < 3 {
364+ w .WriteHeader (http .StatusInternalServerError )
365+ return
366+ }
367+ w .WriteHeader (http .StatusOK )
368+ _ , _ = w .Write ([]byte ("body received correctly" ))
369+ }
370+ }(),
371+ requestBody : io .NopCloser (bytes .NewBuffer ([]byte ("request body content" ))),
372+ wantBody : "body received correctly" ,
373+ wantErr : "" ,
374+ wantAttempts : 3 ,
375+ },
326376 }
327377
328378 for _ , tt := range tests {
@@ -334,7 +384,11 @@ func TestDoExponentialBackoff(t *testing.T) {
334384 }))
335385 defer ts .Close ()
336386
337- req , err := http .NewRequest (http .MethodGet , ts .URL , nil )
387+ method := http .MethodGet
388+ if tt .requestBody != nil {
389+ method = http .MethodPost
390+ }
391+ req , err := http .NewRequest (method , ts .URL , tt .requestBody )
338392 if err != nil {
339393 t .Fatalf ("failed to create request: %v" , err )
340394 }
0 commit comments