1
2
3
4
5 package resty
6
7 import (
8 "bytes"
9 "crypto/tls"
10 "encoding/xml"
11 "errors"
12 "io"
13 "io/ioutil"
14 "net"
15 "net/http"
16 "net/url"
17 "os"
18 "path/filepath"
19 "strconv"
20 "strings"
21 "testing"
22 "time"
23 )
24
25 type AuthSuccess struct {
26 ID, Message string
27 }
28
29 type AuthError struct {
30 ID, Message string
31 }
32
33 func TestGet(t *testing.T) {
34 ts := createGetServer(t)
35 defer ts.Close()
36
37 resp, err := dc().R().
38 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
39 Get(ts.URL + "/")
40
41 assertError(t, err)
42 assertEqual(t, http.StatusOK, resp.StatusCode())
43 assertEqual(t, "HTTP/1.1", resp.Proto())
44 assertEqual(t, "200 OK", resp.Status())
45 assertNotNil(t, resp.Body())
46 assertEqual(t, "TestGet: text response", resp.String())
47
48 logResponse(t, resp)
49 }
50
51 func TestIllegalRetryCount(t *testing.T) {
52 ts := createGetServer(t)
53 defer ts.Close()
54
55 resp, err := dc().SetRetryCount(-1).R().Get(ts.URL + "/")
56
57 assertNil(t, err)
58 assertNil(t, resp)
59 }
60
61 func TestGetCustomUserAgent(t *testing.T) {
62 ts := createGetServer(t)
63 defer ts.Close()
64
65 resp, err := dcr().
66 SetHeader(hdrUserAgentKey, "Test Custom User agent").
67 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
68 Get(ts.URL + "/")
69
70 assertError(t, err)
71 assertEqual(t, http.StatusOK, resp.StatusCode())
72 assertEqual(t, "HTTP/1.1", resp.Proto())
73 assertEqual(t, "200 OK", resp.Status())
74 assertEqual(t, "TestGet: text response", resp.String())
75
76 logResponse(t, resp)
77 }
78
79 func TestGetClientParamRequestParam(t *testing.T) {
80 ts := createGetServer(t)
81 defer ts.Close()
82
83 c := dc()
84 c.SetQueryParam("client_param", "true").
85 SetQueryParams(map[string]string{"req_1": "jeeva", "req_3": "jeeva3"}).
86 SetDebug(true)
87 c.outputLogTo(ioutil.Discard)
88
89 resp, err := c.R().
90 SetQueryParams(map[string]string{"req_1": "req 1 value", "req_2": "req 2 value"}).
91 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
92 SetHeader(hdrUserAgentKey, "Test Custom User agent").
93 Get(ts.URL + "/")
94
95 assertError(t, err)
96 assertEqual(t, http.StatusOK, resp.StatusCode())
97 assertEqual(t, "HTTP/1.1", resp.Proto())
98 assertEqual(t, "200 OK", resp.Status())
99 assertEqual(t, "TestGet: text response", resp.String())
100
101 logResponse(t, resp)
102 }
103
104 func TestGetRelativePath(t *testing.T) {
105 ts := createGetServer(t)
106 defer ts.Close()
107
108 c := dc()
109 c.SetHostURL(ts.URL)
110
111 resp, err := c.R().Get("mypage2")
112
113 assertError(t, err)
114 assertEqual(t, http.StatusOK, resp.StatusCode())
115 assertEqual(t, "TestGet: text response from mypage2", resp.String())
116
117 logResponse(t, resp)
118 }
119
120 func TestGet400Error(t *testing.T) {
121 ts := createGetServer(t)
122 defer ts.Close()
123
124 resp, err := dcr().Get(ts.URL + "/mypage")
125
126 assertError(t, err)
127 assertEqual(t, http.StatusBadRequest, resp.StatusCode())
128 assertEqual(t, "", resp.String())
129
130 logResponse(t, resp)
131 }
132
133 func TestPostJSONStringSuccess(t *testing.T) {
134 ts := createPostServer(t)
135 defer ts.Close()
136
137 c := dc()
138 c.SetHeader(hdrContentTypeKey, "application/json; charset=utf-8").
139 SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.1", hdrAcceptKey: "application/json; charset=utf-8"})
140
141 resp, err := c.R().
142 SetBody(`{"username":"testuser", "password":"testpass"}`).
143 Post(ts.URL + "/login")
144
145 assertError(t, err)
146 assertEqual(t, http.StatusOK, resp.StatusCode())
147
148 logResponse(t, resp)
149
150
151 resp, err = c.R().
152 SetBody(`{"username":"testuser" "password":"testpass"}`).
153 Post(ts.URL + "/login")
154
155 assertError(t, err)
156 assertEqual(t, http.StatusBadRequest, resp.StatusCode())
157
158 logResponse(t, resp)
159 }
160
161 func TestPostJSONBytesSuccess(t *testing.T) {
162 ts := createPostServer(t)
163 defer ts.Close()
164
165 c := dc()
166 c.SetHeader(hdrContentTypeKey, "application/json; charset=utf-8").
167 SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.7", hdrAcceptKey: "application/json; charset=utf-8"})
168
169 resp, err := c.R().
170 SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
171 Post(ts.URL + "/login")
172
173 assertError(t, err)
174 assertEqual(t, http.StatusOK, resp.StatusCode())
175
176 logResponse(t, resp)
177 }
178
179 func TestPostJSONBytesIoReader(t *testing.T) {
180 ts := createPostServer(t)
181 defer ts.Close()
182
183 c := dc()
184 c.SetHeader(hdrContentTypeKey, "application/json; charset=utf-8")
185
186 bodyBytes := []byte(`{"username":"testuser", "password":"testpass"}`)
187
188 resp, err := c.R().
189 SetBody(bytes.NewReader(bodyBytes)).
190 Post(ts.URL + "/login")
191
192 assertError(t, err)
193 assertEqual(t, http.StatusOK, resp.StatusCode())
194
195 logResponse(t, resp)
196 }
197
198 func TestPostJSONStructSuccess(t *testing.T) {
199 ts := createPostServer(t)
200 defer ts.Close()
201
202 user := &User{Username: "testuser", Password: "testpass"}
203
204 c := dc().SetJSONEscapeHTML(false)
205 resp, err := c.R().
206 SetHeader(hdrContentTypeKey, "application/json; charset=utf-8").
207 SetBody(user).
208 SetResult(&AuthSuccess{}).
209 Post(ts.URL + "/login")
210
211 assertError(t, err)
212 assertEqual(t, http.StatusOK, resp.StatusCode())
213
214 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
215
216 logResponse(t, resp)
217 }
218
219 func TestPostJSONRPCStructSuccess(t *testing.T) {
220 ts := createPostServer(t)
221 defer ts.Close()
222
223 user := &User{Username: "testuser", Password: "testpass"}
224
225 c := dc().SetJSONEscapeHTML(false)
226 resp, err := c.R().
227 SetHeader(hdrContentTypeKey, "application/json-rpc").
228 SetBody(user).
229 SetResult(&AuthSuccess{}).
230 SetQueryParam("ct", "rpc").
231 Post(ts.URL + "/login")
232
233 assertError(t, err)
234 assertEqual(t, http.StatusOK, resp.StatusCode())
235
236 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
237
238 logResponse(t, resp)
239 }
240
241 func TestPostJSONStructInvalidLogin(t *testing.T) {
242 ts := createPostServer(t)
243 defer ts.Close()
244
245 c := dc()
246 c.SetDebug(false)
247
248 resp, err := c.R().
249 SetHeader(hdrContentTypeKey, "application/json; charset=utf-8").
250 SetBody(User{Username: "testuser", Password: "testpass1"}).
251 SetError(AuthError{}).
252 SetJSONEscapeHTML(false).
253 Post(ts.URL + "/login")
254
255 assertError(t, err)
256 assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
257
258 authError := resp.Error().(*AuthError)
259 assertEqual(t, "unauthorized", authError.ID)
260 assertEqual(t, "Invalid credentials", authError.Message)
261 t.Logf("Result Error: %q", resp.Error().(*AuthError))
262
263 logResponse(t, resp)
264 }
265
266 func TestPostJSONErrorRFC7807(t *testing.T) {
267 ts := createPostServer(t)
268 defer ts.Close()
269
270 c := dc()
271 resp, err := c.R().
272 SetHeader(hdrContentTypeKey, "application/json; charset=utf-8").
273 SetBody(User{Username: "testuser", Password: "testpass1"}).
274 SetError(AuthError{}).
275 Post(ts.URL + "/login?ct=problem")
276
277 assertError(t, err)
278 assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
279
280 authError := resp.Error().(*AuthError)
281 assertEqual(t, "unauthorized", authError.ID)
282 assertEqual(t, "Invalid credentials", authError.Message)
283 t.Logf("Result Error: %q", resp.Error().(*AuthError))
284
285 logResponse(t, resp)
286 }
287
288 func TestPostJSONMapSuccess(t *testing.T) {
289 ts := createPostServer(t)
290 defer ts.Close()
291
292 c := dc()
293 c.SetDebug(false)
294
295 resp, err := c.R().
296 SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
297 SetResult(AuthSuccess{}).
298 Post(ts.URL + "/login")
299
300 assertError(t, err)
301 assertEqual(t, http.StatusOK, resp.StatusCode())
302
303 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
304
305 logResponse(t, resp)
306 }
307
308 func TestPostJSONMapInvalidResponseJson(t *testing.T) {
309 ts := createPostServer(t)
310 defer ts.Close()
311
312 resp, err := dclr().
313 SetBody(map[string]interface{}{"username": "testuser", "password": "invalidjson"}).
314 SetResult(&AuthSuccess{}).
315 Post(ts.URL + "/login")
316
317 assertEqual(t, "invalid character '}' looking for beginning of object key string", err.Error())
318 assertEqual(t, http.StatusOK, resp.StatusCode())
319
320 authSuccess := resp.Result().(*AuthSuccess)
321 assertEqual(t, "", authSuccess.ID)
322 assertEqual(t, "", authSuccess.Message)
323
324 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
325
326 logResponse(t, resp)
327 }
328
329 type brokenMarshalJSON struct{}
330
331 func (b brokenMarshalJSON) MarshalJSON() ([]byte, error) {
332 return nil, errors.New("b0rk3d")
333 }
334
335 func TestPostJSONMarshalError(t *testing.T) {
336 ts := createPostServer(t)
337 defer ts.Close()
338
339 b := brokenMarshalJSON{}
340 exp := "b0rk3d"
341
342 _, err := dclr().
343 SetHeader(hdrContentTypeKey, "application/json").
344 SetBody(b).
345 Post(ts.URL + "/login")
346 if err == nil {
347 t.Fatalf("expected error but got %v", err)
348 }
349
350 if !strings.Contains(err.Error(), exp) {
351 t.Errorf("expected error string %q to contain %q", err, exp)
352 }
353 }
354
355 func TestForceContentTypeForGH276andGH240(t *testing.T) {
356 ts := createPostServer(t)
357 defer ts.Close()
358
359 retried := 0
360 c := dc()
361 c.SetDebug(false)
362 c.SetRetryCount(3)
363 c.SetRetryAfter(RetryAfterFunc(func(*Client, *Response) (time.Duration, error) {
364 retried++
365 return 0, nil
366 }))
367
368 resp, err := c.R().
369 SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
370 SetResult(AuthSuccess{}).
371 ForceContentType("application/json").
372 Post(ts.URL + "/login-json-html")
373
374 assertNotNil(t, err)
375 assertEqual(t, http.StatusOK, resp.StatusCode())
376 assertEqual(t, 0, retried)
377
378 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
379
380 logResponse(t, resp)
381 }
382
383 func TestPostXMLStringSuccess(t *testing.T) {
384 ts := createPostServer(t)
385 defer ts.Close()
386
387 c := dc()
388 c.SetDebug(false)
389
390 resp, err := c.R().
391 SetHeader(hdrContentTypeKey, "application/xml").
392 SetBody(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username><Password>testpass</Password></User>`).
393 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
394 Post(ts.URL + "/login")
395
396 assertError(t, err)
397 assertEqual(t, http.StatusOK, resp.StatusCode())
398
399 logResponse(t, resp)
400 }
401
402 type brokenMarshalXML struct{}
403
404 func (b brokenMarshalXML) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
405 return errors.New("b0rk3d")
406 }
407
408 func TestPostXMLMarshalError(t *testing.T) {
409 ts := createPostServer(t)
410 defer ts.Close()
411
412 b := brokenMarshalXML{}
413 exp := "b0rk3d"
414
415 _, err := dclr().
416 SetHeader(hdrContentTypeKey, "application/xml").
417 SetBody(b).
418 Post(ts.URL + "/login")
419 if err == nil {
420 t.Fatalf("expected error but got %v", err)
421 }
422
423 if !strings.Contains(err.Error(), exp) {
424 t.Errorf("expected error string %q to contain %q", err, exp)
425 }
426 }
427
428 func TestPostXMLStringError(t *testing.T) {
429 ts := createPostServer(t)
430 defer ts.Close()
431
432 resp, err := dclr().
433 SetHeader(hdrContentTypeKey, "application/xml").
434 SetBody(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username>testpass</Password></User>`).
435 Post(ts.URL + "/login")
436
437 assertError(t, err)
438 assertEqual(t, http.StatusBadRequest, resp.StatusCode())
439 assertEqual(t, `<?xml version="1.0" encoding="UTF-8"?><AuthError><Id>bad_request</Id><Message>Unable to read user info</Message></AuthError>`, resp.String())
440
441 logResponse(t, resp)
442 }
443
444 func TestPostXMLBytesSuccess(t *testing.T) {
445 ts := createPostServer(t)
446 defer ts.Close()
447
448 c := dc()
449 c.SetDebug(false)
450
451 resp, err := c.R().
452 SetHeader(hdrContentTypeKey, "application/xml").
453 SetBody([]byte(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username><Password>testpass</Password></User>`)).
454 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
455 SetContentLength(true).
456 Post(ts.URL + "/login")
457
458 assertError(t, err)
459 assertEqual(t, http.StatusOK, resp.StatusCode())
460
461 logResponse(t, resp)
462 }
463
464 func TestPostXMLStructSuccess(t *testing.T) {
465 ts := createPostServer(t)
466 defer ts.Close()
467
468 resp, err := dclr().
469 SetHeader(hdrContentTypeKey, "application/xml").
470 SetBody(User{Username: "testuser", Password: "testpass"}).
471 SetContentLength(true).
472 SetResult(&AuthSuccess{}).
473 Post(ts.URL + "/login")
474
475 assertError(t, err)
476 assertEqual(t, http.StatusOK, resp.StatusCode())
477
478 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
479
480 logResponse(t, resp)
481 }
482
483 func TestPostXMLStructInvalidLogin(t *testing.T) {
484 ts := createPostServer(t)
485 defer ts.Close()
486
487 c := dc()
488 c.SetError(&AuthError{})
489
490 resp, err := c.R().
491 SetHeader(hdrContentTypeKey, "application/xml").
492 SetBody(User{Username: "testuser", Password: "testpass1"}).
493 Post(ts.URL + "/login")
494
495 assertError(t, err)
496 assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
497 assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm")
498
499 t.Logf("Result Error: %q", resp.Error().(*AuthError))
500
501 logResponse(t, resp)
502 }
503
504 func TestPostXMLStructInvalidResponseXml(t *testing.T) {
505 ts := createPostServer(t)
506 defer ts.Close()
507
508 resp, err := dclr().
509 SetHeader(hdrContentTypeKey, "application/xml").
510 SetBody(User{Username: "testuser", Password: "invalidxml"}).
511 SetResult(&AuthSuccess{}).
512 Post(ts.URL + "/login")
513
514 assertEqual(t, "XML syntax error on line 1: element <Message> closed by </AuthSuccess>", err.Error())
515 assertEqual(t, http.StatusOK, resp.StatusCode())
516
517 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
518
519 logResponse(t, resp)
520 }
521
522 func TestPostXMLMapNotSupported(t *testing.T) {
523 ts := createPostServer(t)
524 defer ts.Close()
525
526 _, err := dclr().
527 SetHeader(hdrContentTypeKey, "application/xml").
528 SetBody(map[string]interface{}{"Username": "testuser", "Password": "testpass"}).
529 Post(ts.URL + "/login")
530
531 assertEqual(t, "unsupported 'Body' type/value", err.Error())
532 }
533
534 func TestRequestBasicAuth(t *testing.T) {
535 ts := createAuthServer(t)
536 defer ts.Close()
537
538 c := dc()
539 c.SetHostURL(ts.URL).
540 SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
541
542 resp, err := c.R().
543 SetBasicAuth("myuser", "basicauth").
544 SetResult(&AuthSuccess{}).
545 Post("/login")
546
547 assertError(t, err)
548 assertEqual(t, http.StatusOK, resp.StatusCode())
549
550 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
551 logResponse(t, resp)
552 }
553
554 func TestRequestBasicAuthFail(t *testing.T) {
555 ts := createAuthServer(t)
556 defer ts.Close()
557
558 c := dc()
559 c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
560 SetError(AuthError{})
561
562 resp, err := c.R().
563 SetBasicAuth("myuser", "basicauth1").
564 Post(ts.URL + "/login")
565
566 assertError(t, err)
567 assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
568
569 t.Logf("Result Error: %q", resp.Error().(*AuthError))
570 logResponse(t, resp)
571 }
572
573 func TestRequestAuthToken(t *testing.T) {
574 ts := createAuthServer(t)
575 defer ts.Close()
576
577 c := dc()
578 c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
579 SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF")
580
581 resp, err := c.R().
582 SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF-Request").
583 Get(ts.URL + "/profile")
584
585 assertError(t, err)
586 assertEqual(t, http.StatusOK, resp.StatusCode())
587 }
588
589 func TestRequestAuthScheme(t *testing.T) {
590 ts := createAuthServer(t)
591 defer ts.Close()
592
593 c := dc()
594 c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
595 SetAuthScheme("OAuth").
596 SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF")
597
598 resp, err := c.R().
599 SetAuthScheme("Bearer").
600 SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF-Request").
601 Get(ts.URL + "/profile")
602
603 assertError(t, err)
604 assertEqual(t, http.StatusOK, resp.StatusCode())
605 }
606
607 func TestFormData(t *testing.T) {
608 ts := createFormPostServer(t)
609 defer ts.Close()
610
611 c := dc()
612 c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
613 SetContentLength(true).
614 SetDebug(true)
615 c.outputLogTo(ioutil.Discard)
616
617 resp, err := c.R().
618 SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
619 SetBasicAuth("myuser", "mypass").
620 Post(ts.URL + "/profile")
621
622 assertError(t, err)
623 assertEqual(t, http.StatusOK, resp.StatusCode())
624 assertEqual(t, "Success", resp.String())
625 }
626
627 func TestMultiValueFormData(t *testing.T) {
628 ts := createFormPostServer(t)
629 defer ts.Close()
630
631 v := url.Values{
632 "search_criteria": []string{"book", "glass", "pencil"},
633 }
634
635 c := dc()
636 c.SetContentLength(true).SetDebug(true)
637 c.outputLogTo(ioutil.Discard)
638
639 resp, err := c.R().
640 SetQueryParamsFromValues(v).
641 Post(ts.URL + "/search")
642
643 assertError(t, err)
644 assertEqual(t, http.StatusOK, resp.StatusCode())
645 assertEqual(t, "Success", resp.String())
646 }
647
648 func TestFormDataDisableWarn(t *testing.T) {
649 ts := createFormPostServer(t)
650 defer ts.Close()
651
652 c := dc()
653 c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
654 SetContentLength(true).
655 SetDebug(true).
656 SetDisableWarn(true)
657 c.outputLogTo(ioutil.Discard)
658
659 resp, err := c.R().
660 SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
661 SetBasicAuth("myuser", "mypass").
662 Post(ts.URL + "/profile")
663
664 assertError(t, err)
665 assertEqual(t, http.StatusOK, resp.StatusCode())
666 assertEqual(t, "Success", resp.String())
667 }
668
669 func TestMultiPartUploadFile(t *testing.T) {
670 ts := createFormPostServer(t)
671 defer ts.Close()
672 defer cleanupFiles(".testdata/upload")
673
674 basePath := getTestDataPath()
675
676 c := dc()
677 c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
678
679 resp, err := c.R().
680 SetFile("profile_img", filepath.Join(basePath, "test-img.png")).
681 SetContentLength(true).
682 Post(ts.URL + "/upload")
683
684 assertError(t, err)
685 assertEqual(t, http.StatusOK, resp.StatusCode())
686 }
687
688 func TestMultiPartUploadFileError(t *testing.T) {
689 ts := createFormPostServer(t)
690 defer ts.Close()
691 defer cleanupFiles(".testdata/upload")
692
693 basePath := getTestDataPath()
694
695 c := dc()
696 c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
697
698 resp, err := c.R().
699 SetFile("profile_img", filepath.Join(basePath, "test-img-not-exists.png")).
700 Post(ts.URL + "/upload")
701
702 if err == nil {
703 t.Errorf("Expected [%v], got [%v]", nil, err)
704 }
705 if resp != nil {
706 t.Errorf("Expected [%v], got [%v]", nil, resp)
707 }
708 }
709
710 func TestMultiPartUploadFiles(t *testing.T) {
711 ts := createFormPostServer(t)
712 defer ts.Close()
713 defer cleanupFiles(".testdata/upload")
714
715 basePath := getTestDataPath()
716
717 resp, err := dclr().
718 SetFormDataFromValues(url.Values{
719 "first_name": []string{"Jeevanandam"},
720 "last_name": []string{"M"},
721 }).
722 SetFiles(map[string]string{"profile_img": filepath.Join(basePath, "test-img.png"), "notes": filepath.Join(basePath, "text-file.txt")}).
723 Post(ts.URL + "/upload")
724
725 responseStr := resp.String()
726
727 assertError(t, err)
728 assertEqual(t, http.StatusOK, resp.StatusCode())
729 assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
730 assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
731 }
732
733 func TestMultiPartIoReaderFiles(t *testing.T) {
734 ts := createFormPostServer(t)
735 defer ts.Close()
736 defer cleanupFiles(".testdata/upload")
737
738 basePath := getTestDataPath()
739 profileImgBytes, _ := ioutil.ReadFile(filepath.Join(basePath, "test-img.png"))
740 notesBytes, _ := ioutil.ReadFile(filepath.Join(basePath, "text-file.txt"))
741
742
743 file := File{
744 Name: "test_file_name.jpg",
745 ParamName: "test_param",
746 Reader: bytes.NewBuffer([]byte("test bytes")),
747 }
748 t.Logf("File Info: %v", file.String())
749
750 resp, err := dclr().
751 SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
752 SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)).
753 SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)).
754 Post(ts.URL + "/upload")
755
756 responseStr := resp.String()
757
758 assertError(t, err)
759 assertEqual(t, http.StatusOK, resp.StatusCode())
760 assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
761 assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
762 }
763
764 func TestMultiPartUploadFileNotOnGetOrDelete(t *testing.T) {
765 ts := createFormPostServer(t)
766 defer ts.Close()
767 defer cleanupFiles(".testdata/upload")
768
769 basePath := getTestDataPath()
770
771 _, err := dclr().
772 SetFile("profile_img", filepath.Join(basePath, "test-img.png")).
773 Get(ts.URL + "/upload")
774
775 assertEqual(t, "multipart content is not allowed in HTTP verb [GET]", err.Error())
776
777 _, err = dclr().
778 SetFile("profile_img", filepath.Join(basePath, "test-img.png")).
779 Delete(ts.URL + "/upload")
780
781 assertEqual(t, "multipart content is not allowed in HTTP verb [DELETE]", err.Error())
782 }
783
784 func TestMultiPartFormData(t *testing.T) {
785 ts := createFormPostServer(t)
786 defer ts.Close()
787 resp, err := dclr().
788 SetMultipartFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
789 SetBasicAuth("myuser", "mypass").
790 Post(ts.URL + "/profile")
791
792 assertError(t, err)
793 assertEqual(t, http.StatusOK, resp.StatusCode())
794 assertEqual(t, "Success", resp.String())
795 }
796
797 func TestMultiPartMultipartField(t *testing.T) {
798 ts := createFormPostServer(t)
799 defer ts.Close()
800 defer cleanupFiles(".testdata/upload")
801
802 jsonBytes := []byte(`{"input": {"name": "Uploaded document", "_filename" : ["file.txt"]}}`)
803
804 resp, err := dclr().
805 SetFormDataFromValues(url.Values{
806 "first_name": []string{"Jeevanandam"},
807 "last_name": []string{"M"},
808 }).
809 SetMultipartField("uploadManifest", "upload-file.json", "application/json", bytes.NewReader(jsonBytes)).
810 Post(ts.URL + "/upload")
811
812 responseStr := resp.String()
813
814 assertError(t, err)
815 assertEqual(t, http.StatusOK, resp.StatusCode())
816 assertEqual(t, true, strings.Contains(responseStr, "upload-file.json"))
817 }
818
819 func TestMultiPartMultipartFields(t *testing.T) {
820 ts := createFormPostServer(t)
821 defer ts.Close()
822 defer cleanupFiles(".testdata/upload")
823
824 jsonStr1 := `{"input": {"name": "Uploaded document 1", "_filename" : ["file1.txt"]}}`
825 jsonStr2 := `{"input": {"name": "Uploaded document 2", "_filename" : ["file2.txt"]}}`
826
827 fields := []*MultipartField{
828 {
829 Param: "uploadManifest1",
830 FileName: "upload-file-1.json",
831 ContentType: "application/json",
832 Reader: strings.NewReader(jsonStr1),
833 },
834 {
835 Param: "uploadManifest2",
836 FileName: "upload-file-2.json",
837 ContentType: "application/json",
838 Reader: strings.NewReader(jsonStr2),
839 },
840 {
841 Param: "uploadManifest3",
842 ContentType: "application/json",
843 Reader: strings.NewReader(jsonStr2),
844 },
845 }
846
847 resp, err := dclr().
848 SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
849 SetMultipartFields(fields...).
850 Post(ts.URL + "/upload")
851
852 responseStr := resp.String()
853
854 assertError(t, err)
855 assertEqual(t, http.StatusOK, resp.StatusCode())
856 assertEqual(t, true, strings.Contains(responseStr, "upload-file-1.json"))
857 assertEqual(t, true, strings.Contains(responseStr, "upload-file-2.json"))
858 }
859
860 func TestGetWithCookie(t *testing.T) {
861 ts := createGetServer(t)
862 defer ts.Close()
863
864 c := dcl()
865 c.SetHostURL(ts.URL)
866 c.SetCookie(&http.Cookie{
867 Name: "go-resty-1",
868 Value: "This is cookie 1 value",
869 })
870
871 resp, err := c.R().
872 SetCookie(&http.Cookie{
873 Name: "go-resty-2",
874 Value: "This is cookie 2 value",
875 }).
876 SetCookies([]*http.Cookie{
877 {
878 Name: "go-resty-1",
879 Value: "This is cookie 1 value additional append",
880 },
881 }).
882 Get("mypage2")
883
884 assertError(t, err)
885 assertEqual(t, http.StatusOK, resp.StatusCode())
886 assertEqual(t, "TestGet: text response from mypage2", resp.String())
887
888 logResponse(t, resp)
889 }
890
891 func TestGetWithCookies(t *testing.T) {
892 ts := createGetServer(t)
893 defer ts.Close()
894
895 c := dc()
896 c.SetHostURL(ts.URL).SetDebug(true)
897
898 tu, _ := url.Parse(ts.URL)
899 c.GetClient().Jar.SetCookies(tu, []*http.Cookie{
900 {
901 Name: "jar-go-resty-1",
902 Value: "From Jar - This is cookie 1 value",
903 },
904 {
905 Name: "jar-go-resty-2",
906 Value: "From Jar - This is cookie 2 value",
907 },
908 })
909
910 resp, err := c.R().SetHeader("Cookie", "").Get("mypage2")
911 assertError(t, err)
912 assertEqual(t, http.StatusOK, resp.StatusCode())
913
914
915 c.SetCookies([]*http.Cookie{
916 {
917 Name: "go-resty-1",
918 Value: "This is cookie 1 value",
919 },
920 {
921 Name: "go-resty-2",
922 Value: "This is cookie 2 value",
923 },
924 })
925
926 resp, err = c.R().
927 SetCookie(&http.Cookie{
928 Name: "req-go-resty-1",
929 Value: "This is request cookie 1 value additional append",
930 }).
931 Get("mypage2")
932
933 assertError(t, err)
934 assertEqual(t, http.StatusOK, resp.StatusCode())
935 assertEqual(t, "TestGet: text response from mypage2", resp.String())
936
937 logResponse(t, resp)
938 }
939
940 func TestPutPlainString(t *testing.T) {
941 ts := createGenServer(t)
942 defer ts.Close()
943
944 resp, err := dc().R().
945 SetBody("This is plain text body to server").
946 Put(ts.URL + "/plaintext")
947
948 assertError(t, err)
949 assertEqual(t, http.StatusOK, resp.StatusCode())
950 assertEqual(t, "TestPut: plain text response", resp.String())
951 }
952
953 func TestPutJSONString(t *testing.T) {
954 ts := createGenServer(t)
955 defer ts.Close()
956
957 client := dc()
958
959 client.OnBeforeRequest(func(c *Client, r *Request) error {
960 r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
961 return nil
962 })
963 client.OnBeforeRequest(func(c *Client, r *Request) error {
964 c.SetContentLength(true)
965 r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
966 return nil
967 })
968
969 client.SetDebug(true)
970 client.outputLogTo(ioutil.Discard)
971
972 resp, err := client.R().
973 SetHeaders(map[string]string{hdrContentTypeKey: "application/json; charset=utf-8", hdrAcceptKey: "application/json; charset=utf-8"}).
974 SetBody(`{"content":"json content sending to server"}`).
975 Put(ts.URL + "/json")
976
977 assertError(t, err)
978 assertEqual(t, http.StatusOK, resp.StatusCode())
979 assertEqual(t, `{"response":"json response"}`, resp.String())
980 }
981
982 func TestPutXMLString(t *testing.T) {
983 ts := createGenServer(t)
984 defer ts.Close()
985
986 resp, err := dc().R().
987 SetHeaders(map[string]string{hdrContentTypeKey: "application/xml", hdrAcceptKey: "application/xml"}).
988 SetBody(`<?xml version="1.0" encoding="UTF-8"?><Request>XML Content sending to server</Request>`).
989 Put(ts.URL + "/xml")
990
991 assertError(t, err)
992 assertEqual(t, http.StatusOK, resp.StatusCode())
993 assertEqual(t, `<?xml version="1.0" encoding="UTF-8"?><Response>XML response</Response>`, resp.String())
994 }
995
996 func TestOnBeforeMiddleware(t *testing.T) {
997 ts := createGenServer(t)
998 defer ts.Close()
999
1000 c := dc()
1001 c.OnBeforeRequest(func(c *Client, r *Request) error {
1002 r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
1003 return nil
1004 })
1005 c.OnBeforeRequest(func(c *Client, r *Request) error {
1006 c.SetContentLength(true)
1007 r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
1008 return nil
1009 })
1010
1011 resp, err := c.R().
1012 SetBody("OnBeforeRequest: This is plain text body to server").
1013 Put(ts.URL + "/plaintext")
1014
1015 assertError(t, err)
1016 assertEqual(t, http.StatusOK, resp.StatusCode())
1017 assertEqual(t, "TestPut: plain text response", resp.String())
1018 }
1019
1020 func TestHTTPAutoRedirectUpTo10(t *testing.T) {
1021 ts := createRedirectServer(t)
1022 defer ts.Close()
1023
1024 _, err := dc().R().Get(ts.URL + "/redirect-1")
1025
1026 assertEqual(t, true, ("Get /redirect-11: stopped after 10 redirects" == err.Error() ||
1027 "Get \"/redirect-11\": stopped after 10 redirects" == err.Error()))
1028 }
1029
1030 func TestHostCheckRedirectPolicy(t *testing.T) {
1031 ts := createRedirectServer(t)
1032 defer ts.Close()
1033
1034 c := dc().
1035 SetRedirectPolicy(DomainCheckRedirectPolicy("127.0.0.1"))
1036
1037 _, err := c.R().Get(ts.URL + "/redirect-host-check-1")
1038
1039 assertNotNil(t, err)
1040 assertEqual(t, true, strings.Contains(err.Error(), "redirect is not allowed as per DomainCheckRedirectPolicy"))
1041 }
1042
1043 func TestHeadMethod(t *testing.T) {
1044 ts := createGetServer(t)
1045 defer ts.Close()
1046
1047 resp, err := dclr().Head(ts.URL + "/")
1048
1049 assertError(t, err)
1050 assertEqual(t, http.StatusOK, resp.StatusCode())
1051 }
1052
1053 func TestOptionsMethod(t *testing.T) {
1054 ts := createGenServer(t)
1055 defer ts.Close()
1056
1057 resp, err := dclr().Options(ts.URL + "/options")
1058
1059 assertError(t, err)
1060 assertEqual(t, http.StatusOK, resp.StatusCode())
1061 assertEqual(t, resp.Header().Get("Access-Control-Expose-Headers"), "x-go-resty-id")
1062 }
1063
1064 func TestPatchMethod(t *testing.T) {
1065 ts := createGenServer(t)
1066 defer ts.Close()
1067
1068 resp, err := dclr().Patch(ts.URL + "/patch")
1069
1070 assertError(t, err)
1071 assertEqual(t, http.StatusOK, resp.StatusCode())
1072
1073 resp.body = nil
1074 assertEqual(t, "", resp.String())
1075 }
1076
1077 func TestSendMethod(t *testing.T) {
1078 ts := createGenServer(t)
1079 defer ts.Close()
1080
1081 t.Run("send-get", func(t *testing.T) {
1082 req := dclr()
1083 req.Method = http.MethodGet
1084 req.URL = ts.URL + "/gzip-test"
1085
1086 resp, err := req.Send()
1087
1088 assertError(t, err)
1089 assertEqual(t, http.StatusOK, resp.StatusCode())
1090
1091 assertEqual(t, "This is Gzip response testing", resp.String())
1092 })
1093
1094 t.Run("send-options", func(t *testing.T) {
1095 req := dclr()
1096 req.Method = http.MethodOptions
1097 req.URL = ts.URL + "/options"
1098
1099 resp, err := req.Send()
1100
1101 assertError(t, err)
1102 assertEqual(t, http.StatusOK, resp.StatusCode())
1103
1104 assertEqual(t, "", resp.String())
1105 assertEqual(t, "x-go-resty-id", resp.Header().Get("Access-Control-Expose-Headers"))
1106 })
1107
1108 t.Run("send-patch", func(t *testing.T) {
1109 req := dclr()
1110 req.Method = http.MethodPatch
1111 req.URL = ts.URL + "/patch"
1112
1113 resp, err := req.Send()
1114
1115 assertError(t, err)
1116 assertEqual(t, http.StatusOK, resp.StatusCode())
1117
1118 assertEqual(t, "", resp.String())
1119 })
1120
1121 t.Run("send-put", func(t *testing.T) {
1122 req := dclr()
1123 req.Method = http.MethodPut
1124 req.URL = ts.URL + "/plaintext"
1125
1126 resp, err := req.Send()
1127
1128 assertError(t, err)
1129 assertEqual(t, http.StatusOK, resp.StatusCode())
1130
1131 assertEqual(t, "TestPut: plain text response", resp.String())
1132 })
1133 }
1134
1135 func TestRawFileUploadByBody(t *testing.T) {
1136 ts := createFormPostServer(t)
1137 defer ts.Close()
1138
1139 file, err := os.Open(filepath.Join(getTestDataPath(), "test-img.png"))
1140 assertNil(t, err)
1141 fileBytes, err := ioutil.ReadAll(file)
1142 assertNil(t, err)
1143
1144 resp, err := dclr().
1145 SetBody(fileBytes).
1146 SetContentLength(true).
1147 SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF").
1148 Put(ts.URL + "/raw-upload")
1149
1150 assertError(t, err)
1151 assertEqual(t, http.StatusOK, resp.StatusCode())
1152 assertEqual(t, "image/png", resp.Request.Header.Get(hdrContentTypeKey))
1153 }
1154
1155 func TestProxySetting(t *testing.T) {
1156 c := dc()
1157
1158 transport, err := c.transport()
1159
1160 assertNil(t, err)
1161
1162 assertEqual(t, false, c.IsProxySet())
1163 assertNotNil(t, transport.Proxy)
1164
1165 c.SetProxy("http://sampleproxy:8888")
1166 assertEqual(t, true, c.IsProxySet())
1167 assertNotNil(t, transport.Proxy)
1168
1169 c.SetProxy("//not.a.user@%66%6f%6f.com:8888")
1170 assertEqual(t, true, c.IsProxySet())
1171 assertNotNil(t, transport.Proxy)
1172
1173 c.SetProxy("http://sampleproxy:8888")
1174 assertEqual(t, true, c.IsProxySet())
1175 c.RemoveProxy()
1176 assertNil(t, c.proxyURL)
1177 assertNil(t, transport.Proxy)
1178 }
1179
1180 func TestGetClient(t *testing.T) {
1181 client := New()
1182 custom := New()
1183 customClient := custom.GetClient()
1184
1185 assertNotNil(t, customClient)
1186 assertNotEqual(t, client, http.DefaultClient)
1187 assertNotEqual(t, customClient, http.DefaultClient)
1188 assertNotEqual(t, client, customClient)
1189 }
1190
1191 func TestIncorrectURL(t *testing.T) {
1192 c := dc()
1193 _, err := c.R().Get("//not.a.user@%66%6f%6f.com/just/a/path/also")
1194 assertEqual(t, true, (strings.Contains(err.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also") ||
1195 strings.Contains(err.Error(), "parse \"//not.a.user@%66%6f%6f.com/just/a/path/also\"")))
1196
1197 c.SetHostURL("//not.a.user@%66%6f%6f.com")
1198 _, err1 := c.R().Get("/just/a/path/also")
1199 assertEqual(t, true, (strings.Contains(err1.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also") ||
1200 strings.Contains(err1.Error(), "parse \"//not.a.user@%66%6f%6f.com/just/a/path/also\"")))
1201 }
1202
1203 func TestDetectContentTypeForPointer(t *testing.T) {
1204 ts := createPostServer(t)
1205 defer ts.Close()
1206
1207 user := &User{Username: "testuser", Password: "testpass"}
1208
1209 resp, err := dclr().
1210 SetBody(user).
1211 SetResult(AuthSuccess{}).
1212 Post(ts.URL + "/login")
1213
1214 assertError(t, err)
1215 assertEqual(t, http.StatusOK, resp.StatusCode())
1216
1217 t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
1218
1219 logResponse(t, resp)
1220 }
1221
1222 type ExampleUser struct {
1223 FirstName string `json:"frist_name"`
1224 LastName string `json:"last_name"`
1225 ZipCode string `json:"zip_code"`
1226 }
1227
1228 func TestDetectContentTypeForPointerWithSlice(t *testing.T) {
1229 ts := createPostServer(t)
1230 defer ts.Close()
1231
1232 users := &[]ExampleUser{
1233 {FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
1234 {FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
1235 {FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
1236 }
1237
1238 resp, err := dclr().
1239 SetBody(users).
1240 Post(ts.URL + "/users")
1241
1242 assertError(t, err)
1243 assertEqual(t, http.StatusAccepted, resp.StatusCode())
1244
1245 t.Logf("Result Success: %q", resp)
1246
1247 logResponse(t, resp)
1248 }
1249
1250 func TestDetectContentTypeForPointerWithSliceMap(t *testing.T) {
1251 ts := createPostServer(t)
1252 defer ts.Close()
1253
1254 usersmap := map[string]interface{}{
1255 "user1": ExampleUser{FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
1256 "user2": &ExampleUser{FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
1257 "user3": ExampleUser{FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
1258 }
1259
1260 var users []map[string]interface{}
1261 users = append(users, usersmap)
1262
1263 resp, err := dclr().
1264 SetBody(&users).
1265 Post(ts.URL + "/usersmap")
1266
1267 assertError(t, err)
1268 assertEqual(t, http.StatusAccepted, resp.StatusCode())
1269
1270 t.Logf("Result Success: %q", resp)
1271
1272 logResponse(t, resp)
1273 }
1274
1275 func TestDetectContentTypeForSlice(t *testing.T) {
1276 ts := createPostServer(t)
1277 defer ts.Close()
1278
1279 users := []ExampleUser{
1280 {FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
1281 {FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
1282 {FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
1283 }
1284
1285 resp, err := dclr().
1286 SetBody(users).
1287 Post(ts.URL + "/users")
1288
1289 assertError(t, err)
1290 assertEqual(t, http.StatusAccepted, resp.StatusCode())
1291
1292 t.Logf("Result Success: %q", resp)
1293
1294 logResponse(t, resp)
1295 }
1296
1297 func TestMultiParamsQueryString(t *testing.T) {
1298 ts1 := createGetServer(t)
1299 defer ts1.Close()
1300
1301 client := dc()
1302 req1 := client.R()
1303
1304 client.SetQueryParam("status", "open")
1305
1306 _, _ = req1.SetQueryParam("status", "pending").
1307 Get(ts1.URL)
1308
1309 assertEqual(t, true, strings.Contains(req1.URL, "status=pending"))
1310
1311 assertEqual(t, false, strings.Contains(req1.URL, "status=open"))
1312
1313 _, _ = req1.SetQueryParam("status", "approved").
1314 Get(ts1.URL)
1315
1316 assertEqual(t, true, strings.Contains(req1.URL, "status=approved"))
1317
1318 assertEqual(t, false, strings.Contains(req1.URL, "status=pending"))
1319
1320 ts2 := createGetServer(t)
1321 defer ts2.Close()
1322
1323 req2 := client.R()
1324
1325 v := url.Values{
1326 "status": []string{"pending", "approved", "reject"},
1327 }
1328
1329 _, _ = req2.SetQueryParamsFromValues(v).Get(ts2.URL)
1330
1331 assertEqual(t, true, strings.Contains(req2.URL, "status=pending"))
1332 assertEqual(t, true, strings.Contains(req2.URL, "status=approved"))
1333 assertEqual(t, true, strings.Contains(req2.URL, "status=reject"))
1334
1335
1336 assertEqual(t, false, strings.Contains(req2.URL, "status=open"))
1337 }
1338
1339 func TestSetQueryStringTypical(t *testing.T) {
1340 ts := createGetServer(t)
1341 defer ts.Close()
1342
1343 resp, err := dclr().
1344 SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
1345 Get(ts.URL)
1346
1347 assertError(t, err)
1348 assertEqual(t, http.StatusOK, resp.StatusCode())
1349 assertEqual(t, "200 OK", resp.Status())
1350 assertEqual(t, "TestGet: text response", resp.String())
1351
1352 resp, err = dclr().
1353 SetQueryString("&%%amp;").
1354 Get(ts.URL)
1355
1356 assertError(t, err)
1357 assertEqual(t, http.StatusOK, resp.StatusCode())
1358 assertEqual(t, "200 OK", resp.Status())
1359 assertEqual(t, "TestGet: text response", resp.String())
1360 }
1361
1362 func TestSetHeaderVerbatim(t *testing.T) {
1363 ts := createPostServer(t)
1364 defer ts.Close()
1365
1366 r := dclr().
1367 SetHeaderVerbatim("header-lowercase", "value_lowercase").
1368 SetHeader("header-lowercase", "value_standard")
1369
1370 assertEqual(t, "value_lowercase", strings.Join(r.Header["header-lowercase"], ""))
1371 assertEqual(t, "value_standard", r.Header.Get("Header-Lowercase"))
1372 }
1373
1374 func TestSetHeaderMultipleValue(t *testing.T) {
1375 ts := createPostServer(t)
1376 defer ts.Close()
1377
1378 r := dclr().
1379 SetHeaderMultiValues(map[string][]string{
1380 "Content": {"text/*", "text/html", "*"},
1381 "Authorization": {"Bearer xyz"},
1382 })
1383 assertEqual(t, "text/*, text/html, *", r.Header.Get("content"))
1384 assertEqual(t, "Bearer xyz", r.Header.Get("authorization"))
1385 }
1386
1387 func TestOutputFileWithBaseDirAndRelativePath(t *testing.T) {
1388 ts := createGetServer(t)
1389 defer ts.Close()
1390 defer cleanupFiles(".testdata/dir-sample")
1391
1392 client := dc().
1393 SetRedirectPolicy(FlexibleRedirectPolicy(10)).
1394 SetOutputDirectory(filepath.Join(getTestDataPath(), "dir-sample")).
1395 SetDebug(true)
1396 client.outputLogTo(ioutil.Discard)
1397
1398 resp, err := client.R().
1399 SetOutput("go-resty/test-img-success.png").
1400 Get(ts.URL + "/my-image.png")
1401
1402 assertError(t, err)
1403 assertEqual(t, true, resp.Size() != 0)
1404 assertEqual(t, true, resp.Time() > 0)
1405 }
1406
1407 func TestOutputFileWithBaseDirError(t *testing.T) {
1408 c := dc().SetRedirectPolicy(FlexibleRedirectPolicy(10)).
1409 SetOutputDirectory(filepath.Join(getTestDataPath(), `go-resty\0`))
1410
1411 _ = c
1412 }
1413
1414 func TestOutputPathDirNotExists(t *testing.T) {
1415 ts := createGetServer(t)
1416 defer ts.Close()
1417 defer cleanupFiles(filepath.Join(".testdata", "not-exists-dir"))
1418
1419 client := dc().
1420 SetRedirectPolicy(FlexibleRedirectPolicy(10)).
1421 SetOutputDirectory(filepath.Join(getTestDataPath(), "not-exists-dir"))
1422
1423 resp, err := client.R().
1424 SetOutput("test-img-success.png").
1425 Get(ts.URL + "/my-image.png")
1426
1427 assertError(t, err)
1428 assertEqual(t, true, resp.Size() != 0)
1429 assertEqual(t, true, resp.Time() > 0)
1430 }
1431
1432 func TestOutputFileAbsPath(t *testing.T) {
1433 ts := createGetServer(t)
1434 defer ts.Close()
1435 defer cleanupFiles(filepath.Join(".testdata", "go-resty"))
1436
1437 _, err := dcr().
1438 SetOutput(filepath.Join(getTestDataPath(), "go-resty", "test-img-success-2.png")).
1439 Get(ts.URL + "/my-image.png")
1440
1441 assertError(t, err)
1442 }
1443
1444 func TestContextInternal(t *testing.T) {
1445 ts := createGetServer(t)
1446 defer ts.Close()
1447
1448 r := dc().R().
1449 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10))
1450
1451 resp, err := r.Get(ts.URL + "/")
1452
1453 assertError(t, err)
1454 assertEqual(t, http.StatusOK, resp.StatusCode())
1455 }
1456
1457 func TestSRV(t *testing.T) {
1458 c := dc().
1459 SetRedirectPolicy(FlexibleRedirectPolicy(20)).
1460 SetScheme("http")
1461
1462 r := c.R().
1463 SetSRV(&SRVRecord{"xmpp-server", "google.com"})
1464
1465 assertEqual(t, "xmpp-server", r.SRV.Service)
1466 assertEqual(t, "google.com", r.SRV.Domain)
1467
1468 resp, err := r.Get("/")
1469 if err == nil {
1470 assertError(t, err)
1471 assertNotNil(t, resp)
1472 assertEqual(t, http.StatusOK, resp.StatusCode())
1473 }
1474 }
1475
1476 func TestSRVInvalidService(t *testing.T) {
1477 _, err := dc().R().
1478 SetSRV(&SRVRecord{"nonexistantservice", "sampledomain"}).
1479 Get("/")
1480
1481 assertNotNil(t, err)
1482 assertType(t, net.DNSError{}, err)
1483 }
1484
1485 func TestRequestDoNotParseResponse(t *testing.T) {
1486 ts := createGetServer(t)
1487 defer ts.Close()
1488
1489 client := dc().SetDoNotParseResponse(true)
1490 resp, err := client.R().
1491 SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
1492 Get(ts.URL + "/")
1493
1494 assertError(t, err)
1495
1496 buf := acquireBuffer()
1497 defer releaseBuffer(buf)
1498 _, _ = io.Copy(buf, resp.RawBody())
1499
1500 assertEqual(t, "TestGet: text response", buf.String())
1501 _ = resp.RawBody().Close()
1502
1503
1504 resp, err = dc().R().
1505 SetDoNotParseResponse(true).
1506 Get(ts.URL + "/")
1507
1508 assertError(t, err)
1509
1510 resp.RawResponse = nil
1511 assertNil(t, resp.RawBody())
1512 }
1513
1514 type noCtTest struct {
1515 Response string `json:"response"`
1516 }
1517
1518 func TestRequestExpectContentTypeTest(t *testing.T) {
1519 ts := createGenServer(t)
1520 defer ts.Close()
1521
1522 c := dc()
1523 resp, err := c.R().
1524 SetResult(noCtTest{}).
1525 ExpectContentType("application/json").
1526 Get(ts.URL + "/json-no-set")
1527
1528 assertError(t, err)
1529 assertEqual(t, http.StatusOK, resp.StatusCode())
1530 assertNotNil(t, resp.Result())
1531 assertEqual(t, "json response no content type set", resp.Result().(*noCtTest).Response)
1532
1533 assertEqual(t, "", firstNonEmpty("", ""))
1534 }
1535
1536 func TestGetPathParamAndPathParams(t *testing.T) {
1537 ts := createGetServer(t)
1538 defer ts.Close()
1539
1540 c := dc().
1541 SetHostURL(ts.URL).
1542 SetPathParam("userId", "sample@sample.com")
1543
1544 resp, err := c.R().SetPathParam("subAccountId", "100002").
1545 Get("/v1/users/{userId}/{subAccountId}/details")
1546
1547 assertError(t, err)
1548 assertEqual(t, http.StatusOK, resp.StatusCode())
1549 assertEqual(t, true, strings.Contains(resp.String(), "TestGetPathParams: text response"))
1550 assertEqual(t, true, strings.Contains(resp.String(), "/v1/users/sample@sample.com/100002/details"))
1551
1552 logResponse(t, resp)
1553 }
1554
1555 func TestReportMethodSupportsPayload(t *testing.T) {
1556 ts := createGenServer(t)
1557 defer ts.Close()
1558
1559 c := dc()
1560 resp, err := c.R().
1561 SetBody("body").
1562 Execute("REPORT", ts.URL+"/report")
1563
1564 assertError(t, err)
1565 assertEqual(t, http.StatusOK, resp.StatusCode())
1566 }
1567
1568 func TestRequestQueryStringOrder(t *testing.T) {
1569 ts := createGetServer(t)
1570 defer ts.Close()
1571
1572 resp, err := New().R().
1573 SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
1574 Get(ts.URL + "/?UniqueId=ead1d0ed-XXX-XXX-XXX-abb7612b3146&Translate=false&tempauth=eyJ0eXAiOiJKV1QiLC...HZEhwVnJ1d0NSUGVLaUpSaVNLRG5scz0&ApiVersion=2.0")
1575
1576 assertError(t, err)
1577 assertEqual(t, http.StatusOK, resp.StatusCode())
1578 assertEqual(t, "200 OK", resp.Status())
1579 assertNotNil(t, resp.Body())
1580 assertEqual(t, "TestGet: text response", resp.String())
1581
1582 logResponse(t, resp)
1583 }
1584
1585 func TestRequestOverridesClientAuthorizationHeader(t *testing.T) {
1586 ts := createAuthServer(t)
1587 defer ts.Close()
1588
1589 c := dc()
1590 c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
1591 SetHeader("Authorization", "some token").
1592 SetHostURL(ts.URL + "/")
1593
1594 resp, err := c.R().
1595 SetHeader("Authorization", "Bearer 004DDB79-6801-4587-B976-F093E6AC44FF").
1596 Get("/profile")
1597
1598 assertError(t, err)
1599 assertEqual(t, http.StatusOK, resp.StatusCode())
1600 }
1601
1602 func TestRequestFileUploadAsReader(t *testing.T) {
1603 ts := createFilePostServer(t)
1604 defer ts.Close()
1605
1606 file, _ := os.Open(filepath.Join(getTestDataPath(), "test-img.png"))
1607 defer file.Close()
1608
1609 resp, err := dclr().
1610 SetBody(file).
1611 SetHeader("Content-Type", "image/png").
1612 Post(ts.URL + "/upload")
1613
1614 assertError(t, err)
1615 assertEqual(t, http.StatusOK, resp.StatusCode())
1616 assertEqual(t, true, strings.Contains(resp.String(), "File Uploaded successfully"))
1617
1618 file, _ = os.Open(filepath.Join(getTestDataPath(), "test-img.png"))
1619 defer file.Close()
1620
1621 resp, err = dclr().
1622 SetBody(file).
1623 SetHeader("Content-Type", "image/png").
1624 SetContentLength(true).
1625 Post(ts.URL + "/upload")
1626
1627 assertError(t, err)
1628 assertEqual(t, http.StatusOK, resp.StatusCode())
1629 assertEqual(t, true, strings.Contains(resp.String(), "File Uploaded successfully"))
1630 }
1631
1632 func TestHostHeaderOverride(t *testing.T) {
1633 ts := createGetServer(t)
1634 defer ts.Close()
1635
1636 resp, err := dc().R().
1637 SetHeader("Host", "myhostname").
1638 Get(ts.URL + "/host-header")
1639
1640 assertError(t, err)
1641 assertEqual(t, http.StatusOK, resp.StatusCode())
1642 assertEqual(t, "200 OK", resp.Status())
1643 assertNotNil(t, resp.Body())
1644 assertEqual(t, "myhostname", resp.String())
1645
1646 logResponse(t, resp)
1647 }
1648
1649 func TestPathParamURLInput(t *testing.T) {
1650 ts := createGetServer(t)
1651 defer ts.Close()
1652
1653 c := dc().SetDebug(true).
1654 SetHostURL(ts.URL).
1655 SetPathParams(map[string]string{
1656 "userId": "sample@sample.com",
1657 })
1658
1659 resp, err := c.R().
1660 SetPathParams(map[string]string{
1661 "subAccountId": "100002",
1662 "website": "https://example.com",
1663 }).Get("/v1/users/{userId}/{subAccountId}/{website}")
1664
1665 assertError(t, err)
1666 assertEqual(t, http.StatusOK, resp.StatusCode())
1667 assertEqual(t, true, strings.Contains(resp.String(), "TestPathParamURLInput: text response"))
1668 assertEqual(t, true, strings.Contains(resp.String(), "/v1/users/sample@sample.com/100002/https:%2F%2Fexample.com"))
1669
1670 logResponse(t, resp)
1671 }
1672
1673
1674 func TestTraceInfo(t *testing.T) {
1675 ts := createGetServer(t)
1676 defer ts.Close()
1677
1678 serverAddr := ts.URL[strings.LastIndex(ts.URL, "/")+1:]
1679
1680 client := dc()
1681 client.SetHostURL(ts.URL).EnableTrace()
1682 for _, u := range []string{"/", "/json", "/long-text", "/long-json"} {
1683 resp, err := client.R().Get(u)
1684 assertNil(t, err)
1685 assertNotNil(t, resp)
1686
1687 tr := resp.Request.TraceInfo()
1688 assertEqual(t, true, tr.DNSLookup >= 0)
1689 assertEqual(t, true, tr.ConnTime >= 0)
1690 assertEqual(t, true, tr.TLSHandshake >= 0)
1691 assertEqual(t, true, tr.ServerTime >= 0)
1692 assertEqual(t, true, tr.ResponseTime >= 0)
1693 assertEqual(t, true, tr.TotalTime >= 0)
1694 assertEqual(t, true, tr.TotalTime < time.Hour)
1695 assertEqual(t, true, tr.TotalTime == resp.Time())
1696 assertEqual(t, tr.RemoteAddr.String(), serverAddr)
1697 }
1698
1699 client.DisableTrace()
1700
1701 for _, u := range []string{"/", "/json", "/long-text", "/long-json"} {
1702 resp, err := client.R().EnableTrace().Get(u)
1703 assertNil(t, err)
1704 assertNotNil(t, resp)
1705
1706 tr := resp.Request.TraceInfo()
1707 assertEqual(t, true, tr.DNSLookup >= 0)
1708 assertEqual(t, true, tr.ConnTime >= 0)
1709 assertEqual(t, true, tr.TLSHandshake >= 0)
1710 assertEqual(t, true, tr.ServerTime >= 0)
1711 assertEqual(t, true, tr.ResponseTime >= 0)
1712 assertEqual(t, true, tr.TotalTime >= 0)
1713 assertEqual(t, true, tr.TotalTime == resp.Time())
1714 assertEqual(t, tr.RemoteAddr.String(), serverAddr)
1715 }
1716
1717
1718 _, _ = client.R().EnableTrace().Get("https://httpbin.org/get")
1719 }
1720
1721 func TestTraceInfoWithoutEnableTrace(t *testing.T) {
1722 ts := createGetServer(t)
1723 defer ts.Close()
1724
1725 client := dc()
1726 client.SetHostURL(ts.URL)
1727 for _, u := range []string{"/", "/json", "/long-text", "/long-json"} {
1728 resp, err := client.R().Get(u)
1729 assertNil(t, err)
1730 assertNotNil(t, resp)
1731
1732 tr := resp.Request.TraceInfo()
1733 assertEqual(t, true, tr.DNSLookup == 0)
1734 assertEqual(t, true, tr.ConnTime == 0)
1735 assertEqual(t, true, tr.TLSHandshake == 0)
1736 assertEqual(t, true, tr.ServerTime == 0)
1737 assertEqual(t, true, tr.ResponseTime == 0)
1738 assertEqual(t, true, tr.TotalTime == 0)
1739 }
1740 }
1741
1742 func TestTraceInfoOnTimeout(t *testing.T) {
1743 client := dc()
1744 client.SetHostURL("http://resty-nowhere.local").EnableTrace()
1745
1746 resp, err := client.R().Get("/")
1747 assertNotNil(t, err)
1748 assertNotNil(t, resp)
1749
1750 tr := resp.Request.TraceInfo()
1751 assertEqual(t, true, tr.DNSLookup >= 0)
1752 assertEqual(t, true, tr.ConnTime == 0)
1753 assertEqual(t, true, tr.TLSHandshake == 0)
1754 assertEqual(t, true, tr.TCPConnTime == 0)
1755 assertEqual(t, true, tr.ServerTime == 0)
1756 assertEqual(t, true, tr.ResponseTime == 0)
1757 assertEqual(t, true, tr.TotalTime > 0)
1758 assertEqual(t, true, tr.TotalTime == resp.Time())
1759 }
1760
1761 func TestDebugLoggerRequestBodyTooLarge(t *testing.T) {
1762 ts := createFilePostServer(t)
1763 defer ts.Close()
1764
1765 debugBodySizeLimit := int64(512)
1766
1767
1768 output := bytes.NewBufferString("")
1769 resp, err := New().SetDebug(true).outputLogTo(output).SetDebugBodyLimit(debugBodySizeLimit).R().
1770 SetFile("file", filepath.Join(getTestDataPath(), "test-img.png")).
1771 SetHeader("Content-Type", "image/png").
1772 Post(ts.URL + "/upload")
1773 assertNil(t, err)
1774 assertNotNil(t, resp)
1775 assertEqual(t, true, strings.Contains(output.String(), "REQUEST TOO LARGE"))
1776
1777
1778 output = bytes.NewBufferString("")
1779 resp, err = New().SetDebug(true).outputLogTo(output).SetDebugBodyLimit(debugBodySizeLimit).R().
1780 SetFile("file", filepath.Join(getTestDataPath(), "text-file.txt")).
1781 SetHeader("Content-Type", "text/plain").
1782 Post(ts.URL + "/upload")
1783 assertNil(t, err)
1784 assertNotNil(t, resp)
1785 assertEqual(t, true, strings.Contains(output.String(), " THIS IS TEXT FILE FOR MULTIPART UPLOAD TEST "))
1786
1787 formTs := createFormPostServer(t)
1788 defer formTs.Close()
1789
1790
1791 output = bytes.NewBufferString("")
1792 resp, err = New().SetDebug(true).outputLogTo(output).SetDebugBodyLimit(debugBodySizeLimit).R().
1793 SetFormData(map[string]string{
1794 "first_name": "Alex",
1795 "last_name": strings.Repeat("C", int(debugBodySizeLimit)),
1796 "zip_code": "00001",
1797 }).
1798 SetBasicAuth("myuser", "mypass").
1799 Post(formTs.URL + "/profile")
1800 assertNil(t, err)
1801 assertNotNil(t, resp)
1802 assertEqual(t, true, strings.Contains(output.String(), "REQUEST TOO LARGE"))
1803
1804
1805 output = bytes.NewBufferString("")
1806 resp, err = New().SetDebug(true).outputLogTo(output).SetDebugBodyLimit(debugBodySizeLimit).R().
1807 SetFormData(map[string]string{
1808 "first_name": "Alex",
1809 "last_name": "C",
1810 "zip_code": "00001",
1811 }).
1812 SetBasicAuth("myuser", "mypass").
1813 Post(formTs.URL + "/profile")
1814 assertNil(t, err)
1815 assertNotNil(t, resp)
1816 assertEqual(t, true, strings.Contains(output.String(), "Alex"))
1817
1818
1819 output = bytes.NewBufferString("")
1820 resp, err = New().SetDebug(true).outputLogTo(output).SetDebugBodyLimit(debugBodySizeLimit).R().
1821 SetBody(`{
1822 "first_name": "Alex",
1823 "last_name": "`+strings.Repeat("C", int(debugBodySizeLimit))+`C",
1824 "zip_code": "00001"}`).
1825 SetBasicAuth("myuser", "mypass").
1826 Post(formTs.URL + "/profile")
1827 assertNil(t, err)
1828 assertNotNil(t, resp)
1829 assertEqual(t, true, strings.Contains(output.String(), "REQUEST TOO LARGE"))
1830
1831
1832 output = bytes.NewBufferString("")
1833 resp, err = New().SetDebug(true).outputLogTo(output).SetDebugBodyLimit(debugBodySizeLimit).R().
1834 SetBody([]string{strings.Repeat("C", int(debugBodySizeLimit))}).
1835 SetBasicAuth("myuser", "mypass").
1836 Post(formTs.URL + "/profile")
1837 assertNil(t, err)
1838 assertNotNil(t, resp)
1839 assertEqual(t, true, strings.Contains(output.String(), "REQUEST TOO LARGE"))
1840 }
1841
1842 func TestPostMapTemporaryRedirect(t *testing.T) {
1843 ts := createPostServer(t)
1844 defer ts.Close()
1845
1846 c := dc()
1847 resp, err := c.R().SetBody(map[string]string{"username": "testuser", "password": "testpass"}).
1848 Post(ts.URL + "/redirect")
1849
1850 assertNil(t, err)
1851 assertNotNil(t, resp)
1852 assertEqual(t, http.StatusOK, resp.StatusCode())
1853 }
1854
1855 type brokenReadCloser struct{}
1856
1857 func (b brokenReadCloser) Read(p []byte) (n int, err error) {
1858 return 0, errors.New("read error")
1859 }
1860
1861 func (b brokenReadCloser) Close() error {
1862 return nil
1863 }
1864
1865 func TestPostBodyError(t *testing.T) {
1866 ts := createPostServer(t)
1867 defer ts.Close()
1868
1869 c := dc()
1870 resp, err := c.R().SetBody(brokenReadCloser{}).Post(ts.URL + "/redirect")
1871 assertNotNil(t, err)
1872 assertEqual(t, "read error", err.Error())
1873 assertNil(t, resp)
1874 }
1875
View as plain text