github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/resty/request_test.go (about)

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