@@ -3,6 +3,11 @@ package retryablehttp_test
33import (
44 "bufio"
55 "bytes"
6+ "context"
7+ "fmt"
8+ "io"
9+ "net/http"
10+ "net/http/httptest"
611 "os"
712 "strings"
813 "testing"
@@ -69,6 +74,125 @@ func TestEncodedPaths(t *testing.T) {
6974 }
7075}
7176
77+ func TestRedirectPOSTWithBody (t * testing.T ) {
78+ boundary := "----WebKitFormBoundaryx8jO2oVc6SWP3Sad"
79+ bodyContent := fmt .Sprintf ("--%s\r \n Content-Disposition: form-data; name=\" 1\" \r \n \r \n \" $@0\" \r \n --%s--\r \n " , boundary , boundary )
80+
81+ ts := setupRedirectServer (t , bodyContent )
82+ defer ts .Close ()
83+
84+ url := ts .URL + "/redirect"
85+
86+ // Test with retryablehttp
87+ opts := retryablehttp .DefaultOptionsSpraying
88+ client := retryablehttp .NewClient (opts )
89+
90+ req , err := retryablehttp .NewRequestWithContext (context .Background (), "POST" , url , strings .NewReader (bodyContent ))
91+ if err != nil {
92+ t .Fatalf ("NewRequestWithContext failed: %v" , err )
93+ }
94+
95+ req .Header .Set ("Content-Type" , "multipart/form-data; boundary=" + boundary )
96+
97+ resp , err := client .Do (req )
98+ if err != nil {
99+ t .Fatalf ("client.Do failed: %v" , err )
100+ }
101+ defer resp .Body .Close ()
102+
103+ if resp .StatusCode != http .StatusOK {
104+ body , _ := io .ReadAll (resp .Body )
105+ t .Errorf ("Expected status 200, got %d. Body: %s" , resp .StatusCode , string (body ))
106+ }
107+ }
108+
109+ func TestRedirectPOSTWithBodyFromRequest (t * testing.T ) {
110+ boundary := "----WebKitFormBoundaryx8jO2oVc6SWP3Sad"
111+ bodyContent := fmt .Sprintf ("--%s\r \n Content-Disposition: form-data; name=\" 1\" \r \n \r \n \" $@0\" \r \n --%s--\r \n " , boundary , boundary )
112+
113+ ts := setupRedirectServer (t , bodyContent )
114+ defer ts .Close ()
115+
116+ url := ts .URL + "/redirect"
117+
118+ // Test with retryablehttp
119+ opts := retryablehttp .DefaultOptionsSpraying
120+ client := retryablehttp .NewClient (opts )
121+
122+ // Use http.NewRequest then FromRequest
123+ httpReq , err := http .NewRequest ("POST" , url , strings .NewReader (bodyContent ))
124+ if err != nil {
125+ t .Fatalf ("http.NewRequest failed: %v" , err )
126+ }
127+ httpReq .Header .Set ("Content-Type" , "multipart/form-data; boundary=" + boundary )
128+
129+ req , err := retryablehttp .FromRequest (httpReq )
130+ if err != nil {
131+ t .Fatalf ("FromRequest failed: %v" , err )
132+ }
133+
134+ resp , err := client .Do (req )
135+ if err != nil {
136+ t .Fatalf ("client.Do failed: %v" , err )
137+ }
138+ defer resp .Body .Close ()
139+
140+ if resp .StatusCode != http .StatusOK {
141+ body , _ := io .ReadAll (resp .Body )
142+ t .Errorf ("Expected status 200, got %d. Body: %s" , resp .StatusCode , string (body ))
143+ }
144+ }
145+
146+ func setupRedirectServer (t * testing.T , expectedBody string ) * httptest.Server {
147+ t .Helper ()
148+
149+ mux := http .NewServeMux ()
150+ mux .HandleFunc ("/redirect" , func (w http.ResponseWriter , r * http.Request ) {
151+ if r .Method != http .MethodPost {
152+ w .WriteHeader (http .StatusMethodNotAllowed )
153+
154+ return
155+ }
156+
157+ _ , err := io .ReadAll (r .Body )
158+ if err != nil {
159+ t .Logf ("redirect read body err: %v" , err )
160+ }
161+ r .Body .Close ()
162+
163+ w .Header ().Set ("Location" , "/target" )
164+ w .WriteHeader (http .StatusTemporaryRedirect ) // 307
165+ })
166+
167+ mux .HandleFunc ("/target" , func (w http.ResponseWriter , r * http.Request ) {
168+ body , err := io .ReadAll (r .Body )
169+ if err != nil {
170+ w .WriteHeader (http .StatusInternalServerError )
171+ return
172+ }
173+ r .Body .Close ()
174+
175+ if len (body ) == 0 {
176+ w .WriteHeader (http .StatusBadRequest )
177+ w .Write ([]byte ("empty body" ))
178+
179+ return
180+ }
181+
182+ if string (body ) != expectedBody {
183+ w .WriteHeader (http .StatusBadRequest )
184+ w .Write ([]byte ("body mismatch" ))
185+
186+ return
187+ }
188+
189+ w .WriteHeader (http .StatusOK )
190+ w .Write ([]byte ("success" ))
191+ })
192+
193+ return httptest .NewServer (mux )
194+ }
195+
72196func getPathFromRaw (bin []byte ) (relpath string ) {
73197 buff := bufio .NewReader (bytes .NewReader (bin ))
74198readline:
0 commit comments