diff --git a/client.go b/client.go
index e0c3ce58..be9f4377 100644
--- a/client.go
+++ b/client.go
@@ -95,6 +95,7 @@ type Client struct {
notParseResponse bool
debugBodySizeLimit int64
logPrefix string
+ pathParams map[string]string
beforeRequest []func(*Client, *Request) error
udBeforeRequest []func(*Client, *Request) error
preReqHook func(*Client, *Request) error
@@ -311,6 +312,7 @@ func (c *Client) R() *Request {
client: c,
bodyBuf: nil,
multipartFiles: []*File{},
+ pathParams: make(map[string]string),
}
return r
@@ -719,6 +721,25 @@ func (c *Client) SetLogPrefix(prefix string) *Client {
return c
}
+// SetPathParams method sets multiple URL path key-value pairs at one go in the
+// resty client instance.
+// resty.SetPathParams(map[string]string{
+// "userId": "sample@sample.com",
+// "subAccountId": "100002",
+// })
+//
+// Result:
+// URL - /v1/users/{userId}/{subAccountId}/details
+// Composed URL - /v1/users/sample@sample.com/100002/details
+// It replace the value of the key while composing request URL. Also it can be
+// overridden at request level Path Params options, see `Request.SetPathParams`.
+func (c *Client) SetPathParams(params map[string]string) *Client {
+ for p, v := range params {
+ c.pathParams[p] = v
+ }
+ return c
+}
+
// IsProxySet method returns the true if proxy is set on client otherwise false.
func (c *Client) IsProxySet() bool {
return c.proxyURL != nil
diff --git a/default.go b/default.go
index c7a1145f..43ea1982 100644
--- a/default.go
+++ b/default.go
@@ -251,6 +251,12 @@ func SetDoNotParseResponse(parse bool) *Client {
return DefaultClient.SetDoNotParseResponse(parse)
}
+// SetPathParams method sets the Request path parameter key-value pairs. See
+// `Client.SetPathParams` for more information.
+func SetPathParams(params map[string]string) *Client {
+ return DefaultClient.SetPathParams(params)
+}
+
// IsProxySet method returns the true if proxy is set on client otherwise false.
// See `Client.IsProxySet` for more information.
func IsProxySet() bool {
@@ -284,9 +290,12 @@ func createClient(hc *http.Client) *Client {
JSONUnmarshal: json.Unmarshal,
httpClient: hc,
debugBodySizeLimit: math.MaxInt32,
- logPrefix: "RESTY ",
+ pathParams: make(map[string]string),
}
+ // Log Prefix
+ c.SetLogPrefix("RESTY ")
+
// Default transport
c.SetTransport(&http.Transport{})
diff --git a/middleware.go b/middleware.go
index 75470a8e..3fd997e3 100644
--- a/middleware.go
+++ b/middleware.go
@@ -31,14 +31,13 @@ func parseRequestURL(c *Client, r *Request) error {
return err
}
+ // GitHub #103 Path Params
+ reqURL.Path = composeRequestURL(reqURL.Path, c, r)
+
// If Request.Url is relative path then added c.HostUrl into
// the request URL otherwise Request.Url will be used as-is
if !reqURL.IsAbs() {
- if !strings.HasPrefix(r.URL, "/") {
- r.URL = "/" + r.URL
- }
-
- reqURL, err = url.Parse(c.HostURL + r.URL)
+ reqURL, err = url.Parse(c.HostURL + reqURL.Path)
if err != nil {
return err
}
diff --git a/request.go b/request.go
index e13bc7d4..c2ae6713 100644
--- a/request.go
+++ b/request.go
@@ -354,6 +354,25 @@ func (r *Request) SetDoNotParseResponse(parse bool) *Request {
return r
}
+// SetPathParams method sets multiple URL path key-value pairs at one go in the
+// resty current request instance.
+// resty.R().SetPathParams(map[string]string{
+// "userId": "sample@sample.com",
+// "subAccountId": "100002",
+// })
+//
+// Result:
+// URL - /v1/users/{userId}/{subAccountId}/details
+// Composed URL - /v1/users/sample@sample.com/100002/details
+// It replace the value of the key while composing request URL. Also you can
+// override Path Params value, which was set at client instance level.
+func (r *Request) SetPathParams(params map[string]string) *Request {
+ for p, v := range params {
+ r.pathParams[p] = v
+ }
+ return r
+}
+
// ExpectContentType method allows to provide fallback `Content-Type` for automatic unmarshalling
// when `Content-Type` response header is unavailable.
func (r *Request) ExpectContentType(contentType string) *Request {
diff --git a/request16.go b/request16.go
index 325a7d16..2b06766c 100644
--- a/request16.go
+++ b/request16.go
@@ -45,6 +45,7 @@ type Request struct {
multipartFiles []*File
notParseResponse bool
fallbackContentType string
+ pathParams map[string]string
}
func (r *Request) addContextIfAvailable() {
diff --git a/request17.go b/request17.go
index 3819e84c..387957e3 100644
--- a/request17.go
+++ b/request17.go
@@ -47,6 +47,7 @@ type Request struct {
notParseResponse bool
ctx context.Context
fallbackContentType string
+ pathParams map[string]string
}
// SetContext method sets the context.Context for current Request. It allows
diff --git a/request_test.go b/request_test.go
new file mode 100644
index 00000000..e4caf48f
--- /dev/null
+++ b/request_test.go
@@ -0,0 +1,1248 @@
+// Copyright (c) 2015-2018 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// resty source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package resty
+
+import (
+ "bytes"
+ "crypto/tls"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "os"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+)
+
+type AuthSuccess struct {
+ ID, Message string
+}
+
+type AuthError struct {
+ ID, Message string
+}
+
+func TestGet(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ resp, err := R().
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
+ Get(ts.URL + "/")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "200 OK", resp.Status())
+ assertNotNil(t, resp.Body())
+ assertEqual(t, "TestGet: text response", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestGetCustomUserAgent(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ resp, err := dcr().
+ SetHeader(hdrUserAgentKey, "Test Custom User agent").
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
+ Get(ts.URL + "/")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "200 OK", resp.Status())
+ assertEqual(t, "TestGet: text response", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestGetClientParamRequestParam(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetQueryParam("client_param", "true").
+ SetQueryParams(map[string]string{"req_1": "jeeva", "req_3": "jeeva3"}).
+ SetDebug(true).
+ SetLogger(ioutil.Discard)
+
+ resp, err := c.R().
+ SetQueryParams(map[string]string{"req_1": "req 1 value", "req_2": "req 2 value"}).
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
+ SetHeader(hdrUserAgentKey, "Test Custom User agent").
+ Get(ts.URL + "/")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "200 OK", resp.Status())
+ assertEqual(t, "TestGet: text response", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestGetRelativePath(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHostURL(ts.URL)
+
+ resp, err := c.R().Get("mypage2")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "TestGet: text response from mypage2", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestGet400Error(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ resp, err := dcr().Get(ts.URL + "/mypage")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusBadRequest, resp.StatusCode())
+ assertEqual(t, "", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONStringSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHeader(hdrContentTypeKey, jsonContentType).
+ SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.1", hdrAcceptKey: jsonContentType})
+
+ resp, err := c.R().
+ SetBody(`{"username":"testuser", "password":"testpass"}`).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ logResponse(t, resp)
+
+ // PostJSONStringError
+ resp, err = c.R().
+ SetBody(`{"username":"testuser" "password":"testpass"}`).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusBadRequest, resp.StatusCode())
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONBytesSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHeader(hdrContentTypeKey, jsonContentType).
+ SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.7", hdrAcceptKey: jsonContentType})
+
+ resp, err := c.R().
+ SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONBytesIoReader(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHeader(hdrContentTypeKey, jsonContentType)
+
+ bodyBytes := []byte(`{"username":"testuser", "password":"testpass"}`)
+
+ resp, err := c.R().
+ SetBody(bytes.NewReader(bodyBytes)).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONStructSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ user := &User{Username: "testuser", Password: "testpass"}
+
+ c := dc()
+ resp, err := c.R().
+ SetHeader(hdrContentTypeKey, jsonContentType).
+ SetBody(user).
+ SetResult(&AuthSuccess{}).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONStructInvalidLogin(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetDebug(false)
+
+ resp, err := c.R().
+ SetHeader(hdrContentTypeKey, jsonContentType).
+ SetBody(User{Username: "testuser", Password: "testpass1"}).
+ SetError(AuthError{}).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
+ assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm")
+
+ t.Logf("Result Error: %q", resp.Error().(*AuthError))
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONMapSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetDebug(false)
+
+ resp, err := c.R().
+ SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
+ SetResult(AuthSuccess{}).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+
+ logResponse(t, resp)
+}
+
+func TestPostJSONMapInvalidResponseJson(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().
+ SetBody(map[string]interface{}{"username": "testuser", "password": "invalidjson"}).
+ SetResult(&AuthSuccess{}).
+ Post(ts.URL + "/login")
+
+ assertEqual(t, "invalid character '}' looking for beginning of object key string", err.Error())
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLStringSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetDebug(false)
+
+ resp, err := c.R().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody(`testusertestpass`).
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLStringError(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody(`testusertestpass`).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusBadRequest, resp.StatusCode())
+ assertEqual(t, `bad_requestUnable to read user info`, resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLBytesSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetDebug(false)
+
+ resp, err := c.R().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody([]byte(`testusertestpass`)).
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
+ SetContentLength(true).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLStructSuccess(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody(User{Username: "testuser", Password: "testpass"}).
+ SetContentLength(true).
+ SetResult(&AuthSuccess{}).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLStructInvalidLogin(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetError(&AuthError{})
+
+ resp, err := c.R().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody(User{Username: "testuser", Password: "testpass1"}).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
+ assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm")
+
+ t.Logf("Result Error: %q", resp.Error().(*AuthError))
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLStructInvalidResponseXml(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody(User{Username: "testuser", Password: "invalidxml"}).
+ SetResult(&AuthSuccess{}).
+ Post(ts.URL + "/login")
+
+ assertEqual(t, "XML syntax error on line 1: element closed by ", err.Error())
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+
+ logResponse(t, resp)
+}
+
+func TestPostXMLMapNotSupported(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ _, err := dclr().
+ SetHeader(hdrContentTypeKey, "application/xml").
+ SetBody(map[string]interface{}{"Username": "testuser", "Password": "testpass"}).
+ Post(ts.URL + "/login")
+
+ assertEqual(t, "Unsupported 'Body' type/value", err.Error())
+}
+
+func TestRequestBasicAuth(t *testing.T) {
+ ts := createAuthServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHostURL(ts.URL).
+ SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
+
+ resp, err := c.R().
+ SetBasicAuth("myuser", "basicauth").
+ SetResult(&AuthSuccess{}).
+ Post("/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+ logResponse(t, resp)
+}
+
+func TestRequestBasicAuthFail(t *testing.T) {
+ ts := createAuthServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
+ SetError(AuthError{})
+
+ resp, err := c.R().
+ SetBasicAuth("myuser", "basicauth1").
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
+
+ t.Logf("Result Error: %q", resp.Error().(*AuthError))
+ logResponse(t, resp)
+}
+
+func TestRequestAuthToken(t *testing.T) {
+ ts := createAuthServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
+ SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF")
+
+ resp, err := c.R().
+ SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF-Request").
+ Get(ts.URL + "/profile")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+}
+
+func TestFormData(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
+ SetContentLength(true).
+ SetDebug(true).
+ SetLogger(ioutil.Discard)
+
+ resp, err := c.R().
+ SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
+ SetBasicAuth("myuser", "mypass").
+ Post(ts.URL + "/profile")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "Success", resp.String())
+}
+
+func TestMultiValueFormData(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+
+ v := url.Values{
+ "search_criteria": []string{"book", "glass", "pencil"},
+ }
+
+ c := dc()
+ c.SetContentLength(true).
+ SetDebug(true).
+ SetLogger(ioutil.Discard)
+
+ resp, err := c.R().
+ SetMultiValueFormData(v).
+ Post(ts.URL + "/search")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "Success", resp.String())
+}
+
+func TestFormDataDisableWarn(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
+ SetContentLength(true).
+ SetDebug(true).
+ SetLogger(ioutil.Discard).
+ SetDisableWarn(true)
+
+ resp, err := c.R().
+ SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
+ SetBasicAuth("myuser", "mypass").
+ Post(ts.URL + "/profile")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "Success", resp.String())
+}
+
+func TestMultiPartUploadFile(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/upload")
+
+ basePath := getTestDataPath()
+
+ c := dc()
+ c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
+
+ resp, err := c.R().
+ SetFile("profile_img", basePath+"/test-img.png").
+ SetContentLength(true).
+ Post(ts.URL + "/upload")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+}
+
+func TestMultiPartUploadFileError(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/upload")
+
+ basePath := getTestDataPath()
+
+ c := dc()
+ c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
+
+ resp, err := c.R().
+ SetFile("profile_img", basePath+"/test-img-not-exists.png").
+ Post(ts.URL + "/upload")
+
+ if err == nil {
+ t.Errorf("Expected [%v], got [%v]", nil, err)
+ }
+ if resp != nil {
+ t.Errorf("Expected [%v], got [%v]", nil, resp)
+ }
+}
+
+func TestMultiPartUploadFiles(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/upload")
+
+ basePath := getTestDataPath()
+
+ resp, err := dclr().
+ SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
+ SetFiles(map[string]string{"profile_img": basePath + "/test-img.png", "notes": basePath + "/text-file.txt"}).
+ Post(ts.URL + "/upload")
+
+ responseStr := resp.String()
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
+ assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
+}
+
+func TestMultiPartIoReaderFiles(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/upload")
+
+ basePath := getTestDataPath()
+ profileImgBytes, _ := ioutil.ReadFile(basePath + "/test-img.png")
+ notesBytes, _ := ioutil.ReadFile(basePath + "/text-file.txt")
+
+ // Just info values
+ file := File{
+ Name: "test_file_name.jpg",
+ ParamName: "test_param",
+ Reader: bytes.NewBuffer([]byte("test bytes")),
+ }
+ t.Logf("File Info: %v", file.String())
+
+ resp, err := dclr().
+ SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
+ SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)).
+ SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)).
+ Post(ts.URL + "/upload")
+
+ responseStr := resp.String()
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
+ assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
+}
+
+func TestMultiPartUploadFileNotOnGetOrDelete(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/upload")
+
+ basePath := getTestDataPath()
+
+ _, err := dclr().
+ SetFile("profile_img", basePath+"/test-img.png").
+ Get(ts.URL + "/upload")
+
+ assertEqual(t, "Multipart content is not allowed in HTTP verb [GET]", err.Error())
+
+ _, err = dclr().
+ SetFile("profile_img", basePath+"/test-img.png").
+ Delete(ts.URL + "/upload")
+
+ assertEqual(t, "Multipart content is not allowed in HTTP verb [DELETE]", err.Error())
+}
+
+func TestGetWithCookie(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHostURL(ts.URL)
+ c.SetCookie(&http.Cookie{
+ Name: "go-resty-1",
+ Value: "This is cookie 1 value",
+ Path: "/",
+ Domain: "localhost",
+ MaxAge: 36000,
+ HttpOnly: true,
+ Secure: false,
+ })
+
+ resp, err := c.R().Get("mypage2")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "TestGet: text response from mypage2", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestGetWithCookies(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ var cookies []*http.Cookie
+
+ cookies = append(cookies, &http.Cookie{
+ Name: "go-resty-1",
+ Value: "This is cookie 1 value",
+ Path: "/",
+ Domain: "sample.com",
+ MaxAge: 36000,
+ HttpOnly: true,
+ Secure: false,
+ })
+
+ cookies = append(cookies, &http.Cookie{
+ Name: "go-resty-2",
+ Value: "This is cookie 2 value",
+ Path: "/",
+ Domain: "sample.com",
+ MaxAge: 36000,
+ HttpOnly: true,
+ Secure: false,
+ })
+
+ c := dc()
+ c.SetHostURL(ts.URL).
+ SetCookies(cookies)
+
+ resp, err := c.R().Get("mypage2")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "TestGet: text response from mypage2", resp.String())
+
+ logResponse(t, resp)
+}
+
+func TestPutPlainString(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ resp, err := R().
+ SetBody("This is plain text body to server").
+ Put(ts.URL + "/plaintext")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "TestPut: plain text response", resp.String())
+}
+
+func TestPutJSONString(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ DefaultClient.OnBeforeRequest(func(c *Client, r *Request) error {
+ r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
+ return nil
+ })
+ DefaultClient.OnBeforeRequest(func(c *Client, r *Request) error {
+ c.SetContentLength(true)
+ r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
+ return nil
+ })
+
+ DefaultClient.SetDebug(true).SetLogger(ioutil.Discard)
+
+ resp, err := R().
+ SetHeaders(map[string]string{hdrContentTypeKey: jsonContentType, hdrAcceptKey: jsonContentType}).
+ SetBody(`{"content":"json content sending to server"}`).
+ Put(ts.URL + "/json")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, `{"response":"json response"}`, resp.String())
+}
+
+func TestPutXMLString(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ resp, err := R().
+ SetHeaders(map[string]string{hdrContentTypeKey: "application/xml", hdrAcceptKey: "application/xml"}).
+ SetBody(`XML Content sending to server`).
+ Put(ts.URL + "/xml")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, `XML response`, resp.String())
+}
+
+func TestOnBeforeMiddleware(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.OnBeforeRequest(func(c *Client, r *Request) error {
+ r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
+ return nil
+ })
+ c.OnBeforeRequest(func(c *Client, r *Request) error {
+ c.SetContentLength(true)
+ r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
+ return nil
+ })
+
+ resp, err := c.R().
+ SetBody("OnBeforeRequest: This is plain text body to server").
+ Put(ts.URL + "/plaintext")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "TestPut: plain text response", resp.String())
+}
+
+func TestNoAutoRedirect(t *testing.T) {
+ ts := createRedirectServer(t)
+ defer ts.Close()
+
+ _, err := R().Get(ts.URL + "/redirect-1")
+
+ assertEqual(t, "Get /redirect-2: Auto redirect is disabled", err.Error())
+}
+
+func TestHTTPAutoRedirectUpTo10(t *testing.T) {
+ ts := createRedirectServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHTTPMode()
+ _, err := c.R().Get(ts.URL + "/redirect-1")
+
+ assertEqual(t, "Get /redirect-11: Stopped after 10 redirects", err.Error())
+}
+
+func TestHostCheckRedirectPolicy(t *testing.T) {
+ ts := createRedirectServer(t)
+ defer ts.Close()
+
+ c := dc().
+ SetRedirectPolicy(DomainCheckRedirectPolicy("127.0.0.1"))
+
+ _, err := c.R().Get(ts.URL + "/redirect-host-check-1")
+
+ assertNotNil(t, err)
+ assertEqual(t, true, strings.Contains(err.Error(), "Redirect is not allowed as per DomainCheckRedirectPolicy"))
+}
+
+func TestHeadMethod(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().Head(ts.URL + "/")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+}
+
+func TestOptionsMethod(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().Options(ts.URL + "/options")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, resp.Header().Get("Access-Control-Expose-Headers"), "x-go-resty-id")
+}
+
+func TestPatchMethod(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().Patch(ts.URL + "/patch")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ resp.body = nil
+ assertEqual(t, "", resp.String())
+}
+
+func TestRawFileUploadByBody(t *testing.T) {
+ ts := createFormPostServer(t)
+ defer ts.Close()
+
+ file, _ := os.Open(getTestDataPath() + "/test-img.png")
+ fileBytes, _ := ioutil.ReadAll(file)
+
+ resp, err := dclr().
+ SetBody(fileBytes).
+ SetContentLength(true).
+ SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF").
+ Put(ts.URL + "/raw-upload")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "image/png", resp.Request.Header.Get(hdrContentTypeKey))
+}
+
+func TestProxySetting(t *testing.T) {
+ c := dc()
+
+ transport, err := c.getTransport()
+
+ assertNil(t, err)
+
+ assertEqual(t, false, c.IsProxySet())
+ assertNil(t, transport.Proxy)
+
+ c.SetProxy("http://sampleproxy:8888")
+ assertEqual(t, true, c.IsProxySet())
+ assertNotNil(t, transport.Proxy)
+
+ c.SetProxy("//not.a.user@%66%6f%6f.com:8888")
+ assertEqual(t, false, c.IsProxySet())
+ assertNil(t, transport.Proxy)
+
+ SetProxy("http://sampleproxy:8888")
+ assertEqual(t, true, IsProxySet())
+ RemoveProxy()
+ assertNil(t, DefaultClient.proxyURL)
+ assertNil(t, transport.Proxy)
+}
+
+func TestGetClient(t *testing.T) {
+ client := GetClient()
+ custom := New()
+ customClient := custom.GetClient()
+
+ assertNotNil(t, client)
+ assertNotNil(t, customClient)
+
+ assertNotEqual(t, client, http.DefaultClient)
+ assertNotEqual(t, customClient, http.DefaultClient)
+ assertNotEqual(t, client, customClient)
+
+ assertEqual(t, DefaultClient.httpClient, client)
+}
+
+func TestIncorrectURL(t *testing.T) {
+ _, err := R().Get("//not.a.user@%66%6f%6f.com/just/a/path/also")
+ assertEqual(t, true, strings.Contains(err.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also"))
+
+ c := dc()
+ c.SetHostURL("//not.a.user@%66%6f%6f.com")
+ _, err1 := c.R().Get("/just/a/path/also")
+ assertEqual(t, true, strings.Contains(err1.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also"))
+}
+
+func TestDetectContentTypeForPointer(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ user := &User{Username: "testuser", Password: "testpass"}
+
+ resp, err := dclr().
+ SetBody(user).
+ SetResult(AuthSuccess{}).
+ Post(ts.URL + "/login")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
+
+ logResponse(t, resp)
+}
+
+type ExampleUser struct {
+ FirstName string `json:"frist_name"`
+ LastName string `json:"last_name"`
+ ZipCode string `json:"zip_code"`
+}
+
+func TestDetectContentTypeForPointerWithSlice(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ users := &[]ExampleUser{
+ {FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
+ {FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
+ {FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
+ }
+
+ resp, err := dclr().
+ SetBody(users).
+ Post(ts.URL + "/users")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusAccepted, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp)
+
+ logResponse(t, resp)
+}
+
+func TestDetectContentTypeForPointerWithSliceMap(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ usersmap := map[string]interface{}{
+ "user1": ExampleUser{FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
+ "user2": &ExampleUser{FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
+ "user3": ExampleUser{FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
+ }
+
+ var users []map[string]interface{}
+ users = append(users, usersmap)
+
+ resp, err := dclr().
+ SetBody(&users).
+ Post(ts.URL + "/usersmap")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusAccepted, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp)
+
+ logResponse(t, resp)
+}
+
+func TestDetectContentTypeForSlice(t *testing.T) {
+ ts := createPostServer(t)
+ defer ts.Close()
+
+ users := []ExampleUser{
+ {FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
+ {FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
+ {FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
+ }
+
+ resp, err := dclr().
+ SetBody(users).
+ Post(ts.URL + "/users")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusAccepted, resp.StatusCode())
+
+ t.Logf("Result Success: %q", resp)
+
+ logResponse(t, resp)
+}
+
+func TestMultiParamsQueryString(t *testing.T) {
+ ts1 := createGetServer(t)
+ defer ts1.Close()
+
+ client := dc()
+ req1 := client.R()
+
+ client.SetQueryParam("status", "open")
+
+ _, _ = req1.SetQueryParam("status", "pending").
+ Get(ts1.URL)
+
+ assertEqual(t, true, strings.Contains(req1.URL, "status=pending"))
+ // pending overrides open
+ assertEqual(t, false, strings.Contains(req1.URL, "status=open"))
+
+ _, _ = req1.SetQueryParam("status", "approved").
+ Get(ts1.URL)
+
+ assertEqual(t, true, strings.Contains(req1.URL, "status=approved"))
+ // approved overrides pending
+ assertEqual(t, false, strings.Contains(req1.URL, "status=pending"))
+
+ ts2 := createGetServer(t)
+ defer ts2.Close()
+
+ req2 := client.R()
+
+ v := url.Values{
+ "status": []string{"pending", "approved", "reject"},
+ }
+
+ _, _ = req2.SetMultiValueQueryParams(v).Get(ts2.URL)
+
+ assertEqual(t, true, strings.Contains(req2.URL, "status=pending"))
+ assertEqual(t, true, strings.Contains(req2.URL, "status=approved"))
+ assertEqual(t, true, strings.Contains(req2.URL, "status=reject"))
+
+ // because it's removed by key
+ assertEqual(t, false, strings.Contains(req2.URL, "status=open"))
+}
+
+func TestSetQueryStringTypical(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ resp, err := dclr().
+ SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
+ Get(ts.URL)
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "200 OK", resp.Status())
+ assertEqual(t, "TestGet: text response", resp.String())
+
+ resp, err = dclr().
+ SetQueryString("&%%amp;").
+ Get(ts.URL)
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "200 OK", resp.Status())
+ assertEqual(t, "TestGet: text response", resp.String())
+}
+
+func TestOutputFileWithBaseDirAndRelativePath(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/dir-sample")
+
+ DefaultClient = dc()
+ SetRedirectPolicy(FlexibleRedirectPolicy(10))
+ SetOutputDirectory(getTestDataPath() + "/dir-sample")
+ SetDebug(true)
+
+ resp, err := R().
+ SetOutput("go-resty/test-img-success.png").
+ Get(ts.URL + "/my-image.png")
+
+ assertError(t, err)
+ assertEqual(t, true, resp.Size() != 0)
+}
+
+func TestOutputFileWithBaseDirError(t *testing.T) {
+ c := dc().SetRedirectPolicy(FlexibleRedirectPolicy(10)).
+ SetOutputDirectory(getTestDataPath() + `/go-resty\0`)
+
+ _ = c
+}
+
+func TestOutputPathDirNotExists(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/not-exists-dir")
+
+ DefaultClient = dc()
+ SetRedirectPolicy(FlexibleRedirectPolicy(10))
+ SetOutputDirectory(getTestDataPath() + "/not-exists-dir")
+
+ resp, err := R().
+ SetOutput("test-img-success.png").
+ Get(ts.URL + "/my-image.png")
+
+ assertError(t, err)
+ assertEqual(t, true, resp.Size() != 0)
+}
+
+func TestOutputFileAbsPath(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+ defer cleaupFiles("test-data/go-resty")
+
+ _, err := dcr().
+ SetOutput(getTestDataPath() + "/go-resty/test-img-success-2.png").
+ Get(ts.URL + "/my-image.png")
+
+ assertError(t, err)
+}
+
+func TestContextInternal(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ r := R().
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10))
+
+ if r.isContextCancelledIfAvailable() {
+ t.Error("isContextCancelledIfAvailable != false for vanilla R()")
+ }
+ r.addContextIfAvailable()
+
+ resp, err := r.Get(ts.URL + "/")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+}
+
+func TestSRV(t *testing.T) {
+ c := dc().
+ SetRedirectPolicy(FlexibleRedirectPolicy(20)).
+ SetScheme("http")
+
+ r := c.R().
+ SetSRV(&SRVRecord{"xmpp-server", "google.com"})
+
+ assertEqual(t, "xmpp-server", r.SRV.Service)
+ assertEqual(t, "google.com", r.SRV.Domain)
+
+ resp, err := r.Get("/")
+ if err == nil {
+ assertError(t, err)
+ assertNotNil(t, resp)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ }
+}
+
+func TestSRVInvalidService(t *testing.T) {
+ _, err := R().
+ SetSRV(&SRVRecord{"nonexistantservice", "sampledomain"}).
+ Get("/")
+
+ assertNotNil(t, err)
+ assertEqual(t, true, strings.Contains(err.Error(), "no such host"))
+}
+
+func TestDeprecatedCodeCovergae(t *testing.T) {
+ var user1 User
+ err := Unmarshal("application/json",
+ []byte(`{"username":"testuser", "password":"testpass"}`), &user1)
+ assertError(t, err)
+ assertEqual(t, "testuser", user1.Username)
+ assertEqual(t, "testpass", user1.Password)
+
+ var user2 User
+ err = Unmarshal("application/xml",
+ []byte(`testusertestpass`),
+ &user2)
+ assertError(t, err)
+ assertEqual(t, "testuser", user1.Username)
+ assertEqual(t, "testpass", user1.Password)
+}
+
+func TestRequestDoNotParseResponse(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ resp, err := dc().R().
+ SetDoNotParseResponse(true).
+ SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
+ Get(ts.URL + "/")
+
+ assertError(t, err)
+
+ buf := acquireBuffer()
+ defer releaseBuffer(buf)
+ _, _ = io.Copy(buf, resp.RawBody())
+
+ assertEqual(t, "TestGet: text response", buf.String())
+ _ = resp.RawBody().Close()
+
+ // Manually setting RawResponse as nil
+ resp, err = dc().R().
+ SetDoNotParseResponse(true).
+ Get(ts.URL + "/")
+
+ assertError(t, err)
+
+ resp.RawResponse = nil
+ assertNil(t, resp.RawBody())
+
+ // just set test part
+ SetDoNotParseResponse(true)
+ assertEqual(t, true, DefaultClient.notParseResponse)
+ SetDoNotParseResponse(false)
+}
+
+type noCtTest struct {
+ Response string `json:"response"`
+}
+
+func TestRequestExpectContentTypeTest(t *testing.T) {
+ ts := createGenServer(t)
+ defer ts.Close()
+
+ c := dc()
+ resp, err := c.R().
+ SetResult(noCtTest{}).
+ ExpectContentType("application/json").
+ Get(ts.URL + "/json-no-set")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertNotNil(t, resp.Result())
+ assertEqual(t, "json response no content type set", resp.Result().(*noCtTest).Response)
+
+ assertEqual(t, "", firstNonEmpty("", ""))
+}
+
+func TestGetPathParams(t *testing.T) {
+ ts := createGetServer(t)
+ defer ts.Close()
+
+ c := dc()
+ c.SetHostURL(ts.URL).
+ SetPathParams(map[string]string{
+ "userId": "sample@sample.com",
+ })
+
+ resp, err := c.R().SetPathParams(map[string]string{
+ "subAccountId": "100002",
+ }).
+ Get("v1/users/{userId}/{subAccountId}/details")
+
+ assertError(t, err)
+ assertEqual(t, http.StatusOK, resp.StatusCode())
+ assertEqual(t, "TestPathParams: text response", resp.String())
+
+ logResponse(t, resp)
+
+ SetPathParams(map[string]string{
+ "userId": "sample@sample.com",
+ })
+}
diff --git a/resty_test.go b/resty_test.go
index ceaf610c..0372681a 100644
--- a/resty_test.go
+++ b/resty_test.go
@@ -5,8 +5,6 @@
package resty
import (
- "bytes"
- "crypto/tls"
"encoding/base64"
"encoding/json"
"encoding/xml"
@@ -15,7 +13,6 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
- "net/url"
"os"
"path/filepath"
"reflect"
@@ -26,1209 +23,6 @@ import (
"time"
)
-type AuthSuccess struct {
- ID, Message string
-}
-
-type AuthError struct {
- ID, Message string
-}
-
-func TestGet(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- resp, err := R().
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
- Get(ts.URL + "/")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "200 OK", resp.Status())
- assertNotNil(t, resp.Body())
- assertEqual(t, "TestGet: text response", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestGetCustomUserAgent(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- resp, err := dcr().
- SetHeader(hdrUserAgentKey, "Test Custom User agent").
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
- Get(ts.URL + "/")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "200 OK", resp.Status())
- assertEqual(t, "TestGet: text response", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestGetClientParamRequestParam(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetQueryParam("client_param", "true").
- SetQueryParams(map[string]string{"req_1": "jeeva", "req_3": "jeeva3"}).
- SetDebug(true).
- SetLogger(ioutil.Discard)
-
- resp, err := c.R().
- SetQueryParams(map[string]string{"req_1": "req 1 value", "req_2": "req 2 value"}).
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
- SetHeader(hdrUserAgentKey, "Test Custom User agent").
- Get(ts.URL + "/")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "200 OK", resp.Status())
- assertEqual(t, "TestGet: text response", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestGetRelativePath(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHostURL(ts.URL)
-
- resp, err := c.R().Get("mypage2")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "TestGet: text response from mypage2", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestGet400Error(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- resp, err := dcr().Get(ts.URL + "/mypage")
-
- assertError(t, err)
- assertEqual(t, http.StatusBadRequest, resp.StatusCode())
- assertEqual(t, "", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestPostJSONStringSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHeader(hdrContentTypeKey, jsonContentType).
- SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.1", hdrAcceptKey: jsonContentType})
-
- resp, err := c.R().
- SetBody(`{"username":"testuser", "password":"testpass"}`).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- logResponse(t, resp)
-
- // PostJSONStringError
- resp, err = c.R().
- SetBody(`{"username":"testuser" "password":"testpass"}`).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusBadRequest, resp.StatusCode())
-
- logResponse(t, resp)
-}
-
-func TestPostJSONBytesSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHeader(hdrContentTypeKey, jsonContentType).
- SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.7", hdrAcceptKey: jsonContentType})
-
- resp, err := c.R().
- SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- logResponse(t, resp)
-}
-
-func TestPostJSONBytesIoReader(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHeader(hdrContentTypeKey, jsonContentType)
-
- bodyBytes := []byte(`{"username":"testuser", "password":"testpass"}`)
-
- resp, err := c.R().
- SetBody(bytes.NewReader(bodyBytes)).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- logResponse(t, resp)
-}
-
-func TestPostJSONStructSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- user := &User{Username: "testuser", Password: "testpass"}
-
- c := dc()
- resp, err := c.R().
- SetHeader(hdrContentTypeKey, jsonContentType).
- SetBody(user).
- SetResult(&AuthSuccess{}).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
-
- logResponse(t, resp)
-}
-
-func TestPostJSONStructInvalidLogin(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetDebug(false)
-
- resp, err := c.R().
- SetHeader(hdrContentTypeKey, jsonContentType).
- SetBody(User{Username: "testuser", Password: "testpass1"}).
- SetError(AuthError{}).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
- assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm")
-
- t.Logf("Result Error: %q", resp.Error().(*AuthError))
-
- logResponse(t, resp)
-}
-
-func TestPostJSONMapSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetDebug(false)
-
- resp, err := c.R().
- SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
- SetResult(AuthSuccess{}).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
-
- logResponse(t, resp)
-}
-
-func TestPostJSONMapInvalidResponseJson(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- resp, err := dclr().
- SetBody(map[string]interface{}{"username": "testuser", "password": "invalidjson"}).
- SetResult(&AuthSuccess{}).
- Post(ts.URL + "/login")
-
- assertEqual(t, "invalid character '}' looking for beginning of object key string", err.Error())
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
-
- logResponse(t, resp)
-}
-
-func TestPostXMLStringSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetDebug(false)
-
- resp, err := c.R().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody(`testusertestpass`).
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- logResponse(t, resp)
-}
-
-func TestPostXMLStringError(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- resp, err := dclr().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody(`testusertestpass`).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusBadRequest, resp.StatusCode())
- assertEqual(t, `bad_requestUnable to read user info`, resp.String())
-
- logResponse(t, resp)
-}
-
-func TestPostXMLBytesSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetDebug(false)
-
- resp, err := c.R().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody([]byte(`testusertestpass`)).
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
- SetContentLength(true).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- logResponse(t, resp)
-}
-
-func TestPostXMLStructSuccess(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- resp, err := dclr().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody(User{Username: "testuser", Password: "testpass"}).
- SetContentLength(true).
- SetResult(&AuthSuccess{}).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
-
- logResponse(t, resp)
-}
-
-func TestPostXMLStructInvalidLogin(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetError(&AuthError{})
-
- resp, err := c.R().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody(User{Username: "testuser", Password: "testpass1"}).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
- assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm")
-
- t.Logf("Result Error: %q", resp.Error().(*AuthError))
-
- logResponse(t, resp)
-}
-
-func TestPostXMLStructInvalidResponseXml(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- resp, err := dclr().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody(User{Username: "testuser", Password: "invalidxml"}).
- SetResult(&AuthSuccess{}).
- Post(ts.URL + "/login")
-
- assertEqual(t, "XML syntax error on line 1: element closed by ", err.Error())
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
-
- logResponse(t, resp)
-}
-
-func TestPostXMLMapNotSupported(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- _, err := dclr().
- SetHeader(hdrContentTypeKey, "application/xml").
- SetBody(map[string]interface{}{"Username": "testuser", "Password": "testpass"}).
- Post(ts.URL + "/login")
-
- assertEqual(t, "Unsupported 'Body' type/value", err.Error())
-}
-
-func TestRequestBasicAuth(t *testing.T) {
- ts := createAuthServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHostURL(ts.URL).
- SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
-
- resp, err := c.R().
- SetBasicAuth("myuser", "basicauth").
- SetResult(&AuthSuccess{}).
- Post("/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
- logResponse(t, resp)
-}
-
-func TestRequestBasicAuthFail(t *testing.T) {
- ts := createAuthServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
- SetError(AuthError{})
-
- resp, err := c.R().
- SetBasicAuth("myuser", "basicauth1").
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
-
- t.Logf("Result Error: %q", resp.Error().(*AuthError))
- logResponse(t, resp)
-}
-
-func TestRequestAuthToken(t *testing.T) {
- ts := createAuthServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
- SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF")
-
- resp, err := c.R().
- SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF-Request").
- Get(ts.URL + "/profile")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-}
-
-func TestFormData(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
- SetContentLength(true).
- SetDebug(true).
- SetLogger(ioutil.Discard)
-
- resp, err := c.R().
- SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
- SetBasicAuth("myuser", "mypass").
- Post(ts.URL + "/profile")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "Success", resp.String())
-}
-
-func TestMultiValueFormData(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
-
- v := url.Values{
- "search_criteria": []string{"book", "glass", "pencil"},
- }
-
- c := dc()
- c.SetContentLength(true).
- SetDebug(true).
- SetLogger(ioutil.Discard)
-
- resp, err := c.R().
- SetMultiValueFormData(v).
- Post(ts.URL + "/search")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "Success", resp.String())
-}
-
-func TestFormDataDisableWarn(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
- SetContentLength(true).
- SetDebug(true).
- SetLogger(ioutil.Discard).
- SetDisableWarn(true)
-
- resp, err := c.R().
- SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
- SetBasicAuth("myuser", "mypass").
- Post(ts.URL + "/profile")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "Success", resp.String())
-}
-
-func TestMultiPartUploadFile(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/upload")
-
- basePath := getTestDataPath()
-
- c := dc()
- c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
-
- resp, err := c.R().
- SetFile("profile_img", basePath+"/test-img.png").
- SetContentLength(true).
- Post(ts.URL + "/upload")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-}
-
-func TestMultiPartUploadFileError(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/upload")
-
- basePath := getTestDataPath()
-
- c := dc()
- c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
-
- resp, err := c.R().
- SetFile("profile_img", basePath+"/test-img-not-exists.png").
- Post(ts.URL + "/upload")
-
- if err == nil {
- t.Errorf("Expected [%v], got [%v]", nil, err)
- }
- if resp != nil {
- t.Errorf("Expected [%v], got [%v]", nil, resp)
- }
-}
-
-func TestMultiPartUploadFiles(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/upload")
-
- basePath := getTestDataPath()
-
- resp, err := dclr().
- SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
- SetFiles(map[string]string{"profile_img": basePath + "/test-img.png", "notes": basePath + "/text-file.txt"}).
- Post(ts.URL + "/upload")
-
- responseStr := resp.String()
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
- assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
-}
-
-func TestMultiPartIoReaderFiles(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/upload")
-
- basePath := getTestDataPath()
- profileImgBytes, _ := ioutil.ReadFile(basePath + "/test-img.png")
- notesBytes, _ := ioutil.ReadFile(basePath + "/text-file.txt")
-
- // Just info values
- file := File{
- Name: "test_file_name.jpg",
- ParamName: "test_param",
- Reader: bytes.NewBuffer([]byte("test bytes")),
- }
- t.Logf("File Info: %v", file.String())
-
- resp, err := dclr().
- SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
- SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)).
- SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)).
- Post(ts.URL + "/upload")
-
- responseStr := resp.String()
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
- assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
-}
-
-func TestMultiPartUploadFileNotOnGetOrDelete(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/upload")
-
- basePath := getTestDataPath()
-
- _, err := dclr().
- SetFile("profile_img", basePath+"/test-img.png").
- Get(ts.URL + "/upload")
-
- assertEqual(t, "Multipart content is not allowed in HTTP verb [GET]", err.Error())
-
- _, err = dclr().
- SetFile("profile_img", basePath+"/test-img.png").
- Delete(ts.URL + "/upload")
-
- assertEqual(t, "Multipart content is not allowed in HTTP verb [DELETE]", err.Error())
-}
-
-func TestGetWithCookie(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHostURL(ts.URL)
- c.SetCookie(&http.Cookie{
- Name: "go-resty-1",
- Value: "This is cookie 1 value",
- Path: "/",
- Domain: "localhost",
- MaxAge: 36000,
- HttpOnly: true,
- Secure: false,
- })
-
- resp, err := c.R().Get("mypage2")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "TestGet: text response from mypage2", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestGetWithCookies(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- var cookies []*http.Cookie
-
- cookies = append(cookies, &http.Cookie{
- Name: "go-resty-1",
- Value: "This is cookie 1 value",
- Path: "/",
- Domain: "sample.com",
- MaxAge: 36000,
- HttpOnly: true,
- Secure: false,
- })
-
- cookies = append(cookies, &http.Cookie{
- Name: "go-resty-2",
- Value: "This is cookie 2 value",
- Path: "/",
- Domain: "sample.com",
- MaxAge: 36000,
- HttpOnly: true,
- Secure: false,
- })
-
- c := dc()
- c.SetHostURL(ts.URL).
- SetCookies(cookies)
-
- resp, err := c.R().Get("mypage2")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "TestGet: text response from mypage2", resp.String())
-
- logResponse(t, resp)
-}
-
-func TestPutPlainString(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- resp, err := R().
- SetBody("This is plain text body to server").
- Put(ts.URL + "/plaintext")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "TestPut: plain text response", resp.String())
-}
-
-func TestPutJSONString(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- DefaultClient.OnBeforeRequest(func(c *Client, r *Request) error {
- r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
- return nil
- })
- DefaultClient.OnBeforeRequest(func(c *Client, r *Request) error {
- c.SetContentLength(true)
- r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
- return nil
- })
-
- DefaultClient.SetDebug(true).SetLogger(ioutil.Discard)
-
- resp, err := R().
- SetHeaders(map[string]string{hdrContentTypeKey: jsonContentType, hdrAcceptKey: jsonContentType}).
- SetBody(`{"content":"json content sending to server"}`).
- Put(ts.URL + "/json")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, `{"response":"json response"}`, resp.String())
-}
-
-func TestPutXMLString(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- resp, err := R().
- SetHeaders(map[string]string{hdrContentTypeKey: "application/xml", hdrAcceptKey: "application/xml"}).
- SetBody(`XML Content sending to server`).
- Put(ts.URL + "/xml")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, `XML response`, resp.String())
-}
-
-func TestOnBeforeMiddleware(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- c := dc()
- c.OnBeforeRequest(func(c *Client, r *Request) error {
- r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
- return nil
- })
- c.OnBeforeRequest(func(c *Client, r *Request) error {
- c.SetContentLength(true)
- r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
- return nil
- })
-
- resp, err := c.R().
- SetBody("OnBeforeRequest: This is plain text body to server").
- Put(ts.URL + "/plaintext")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "TestPut: plain text response", resp.String())
-}
-
-func TestNoAutoRedirect(t *testing.T) {
- ts := createRedirectServer(t)
- defer ts.Close()
-
- _, err := R().Get(ts.URL + "/redirect-1")
-
- assertEqual(t, "Get /redirect-2: Auto redirect is disabled", err.Error())
-}
-
-func TestHTTPAutoRedirectUpTo10(t *testing.T) {
- ts := createRedirectServer(t)
- defer ts.Close()
-
- c := dc()
- c.SetHTTPMode()
- _, err := c.R().Get(ts.URL + "/redirect-1")
-
- assertEqual(t, "Get /redirect-11: Stopped after 10 redirects", err.Error())
-}
-
-func TestHostCheckRedirectPolicy(t *testing.T) {
- ts := createRedirectServer(t)
- defer ts.Close()
-
- c := dc().
- SetRedirectPolicy(DomainCheckRedirectPolicy("127.0.0.1"))
-
- _, err := c.R().Get(ts.URL + "/redirect-host-check-1")
-
- assertNotNil(t, err)
- assertEqual(t, true, strings.Contains(err.Error(), "Redirect is not allowed as per DomainCheckRedirectPolicy"))
-}
-
-func TestHeadMethod(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- resp, err := dclr().Head(ts.URL + "/")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-}
-
-func TestOptionsMethod(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- resp, err := dclr().Options(ts.URL + "/options")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, resp.Header().Get("Access-Control-Expose-Headers"), "x-go-resty-id")
-}
-
-func TestPatchMethod(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- resp, err := dclr().Patch(ts.URL + "/patch")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- resp.body = nil
- assertEqual(t, "", resp.String())
-}
-
-func TestRawFileUploadByBody(t *testing.T) {
- ts := createFormPostServer(t)
- defer ts.Close()
-
- file, _ := os.Open(getTestDataPath() + "/test-img.png")
- fileBytes, _ := ioutil.ReadAll(file)
-
- resp, err := dclr().
- SetBody(fileBytes).
- SetContentLength(true).
- SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF").
- Put(ts.URL + "/raw-upload")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "image/png", resp.Request.Header.Get(hdrContentTypeKey))
-}
-
-func TestProxySetting(t *testing.T) {
- c := dc()
-
- transport, err := c.getTransport()
-
- assertNil(t, err)
-
- assertEqual(t, false, c.IsProxySet())
- assertNil(t, transport.Proxy)
-
- c.SetProxy("http://sampleproxy:8888")
- assertEqual(t, true, c.IsProxySet())
- assertNotNil(t, transport.Proxy)
-
- c.SetProxy("//not.a.user@%66%6f%6f.com:8888")
- assertEqual(t, false, c.IsProxySet())
- assertNil(t, transport.Proxy)
-
- SetProxy("http://sampleproxy:8888")
- assertEqual(t, true, IsProxySet())
- RemoveProxy()
- assertNil(t, DefaultClient.proxyURL)
- assertNil(t, transport.Proxy)
-}
-
-func TestGetClient(t *testing.T) {
- client := GetClient()
- custom := New()
- customClient := custom.GetClient()
-
- assertNotNil(t, client)
- assertNotNil(t, customClient)
-
- assertNotEqual(t, client, http.DefaultClient)
- assertNotEqual(t, customClient, http.DefaultClient)
- assertNotEqual(t, client, customClient)
-
- assertEqual(t, DefaultClient.httpClient, client)
-}
-
-func TestIncorrectURL(t *testing.T) {
- _, err := R().Get("//not.a.user@%66%6f%6f.com/just/a/path/also")
- assertEqual(t, true, strings.Contains(err.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also"))
-
- c := dc()
- c.SetHostURL("//not.a.user@%66%6f%6f.com")
- _, err1 := c.R().Get("/just/a/path/also")
- assertEqual(t, true, strings.Contains(err1.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also"))
-}
-
-func TestDetectContentTypeForPointer(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- user := &User{Username: "testuser", Password: "testpass"}
-
- resp, err := dclr().
- SetBody(user).
- SetResult(AuthSuccess{}).
- Post(ts.URL + "/login")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
-
- logResponse(t, resp)
-}
-
-type ExampleUser struct {
- FirstName string `json:"frist_name"`
- LastName string `json:"last_name"`
- ZipCode string `json:"zip_code"`
-}
-
-func TestDetectContentTypeForPointerWithSlice(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- users := &[]ExampleUser{
- {FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
- {FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
- {FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
- }
-
- resp, err := dclr().
- SetBody(users).
- Post(ts.URL + "/users")
-
- assertError(t, err)
- assertEqual(t, http.StatusAccepted, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp)
-
- logResponse(t, resp)
-}
-
-func TestDetectContentTypeForPointerWithSliceMap(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- usersmap := map[string]interface{}{
- "user1": ExampleUser{FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
- "user2": &ExampleUser{FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
- "user3": ExampleUser{FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
- }
-
- var users []map[string]interface{}
- users = append(users, usersmap)
-
- resp, err := dclr().
- SetBody(&users).
- Post(ts.URL + "/usersmap")
-
- assertError(t, err)
- assertEqual(t, http.StatusAccepted, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp)
-
- logResponse(t, resp)
-}
-
-func TestDetectContentTypeForSlice(t *testing.T) {
- ts := createPostServer(t)
- defer ts.Close()
-
- users := []ExampleUser{
- {FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
- {FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
- {FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
- }
-
- resp, err := dclr().
- SetBody(users).
- Post(ts.URL + "/users")
-
- assertError(t, err)
- assertEqual(t, http.StatusAccepted, resp.StatusCode())
-
- t.Logf("Result Success: %q", resp)
-
- logResponse(t, resp)
-}
-
-func TestMultiParamsQueryString(t *testing.T) {
- ts1 := createGetServer(t)
- defer ts1.Close()
-
- client := dc()
- req1 := client.R()
-
- client.SetQueryParam("status", "open")
-
- _, _ = req1.SetQueryParam("status", "pending").
- Get(ts1.URL)
-
- assertEqual(t, true, strings.Contains(req1.URL, "status=pending"))
- // pending overrides open
- assertEqual(t, false, strings.Contains(req1.URL, "status=open"))
-
- _, _ = req1.SetQueryParam("status", "approved").
- Get(ts1.URL)
-
- assertEqual(t, true, strings.Contains(req1.URL, "status=approved"))
- // approved overrides pending
- assertEqual(t, false, strings.Contains(req1.URL, "status=pending"))
-
- ts2 := createGetServer(t)
- defer ts2.Close()
-
- req2 := client.R()
-
- v := url.Values{
- "status": []string{"pending", "approved", "reject"},
- }
-
- _, _ = req2.SetMultiValueQueryParams(v).Get(ts2.URL)
-
- assertEqual(t, true, strings.Contains(req2.URL, "status=pending"))
- assertEqual(t, true, strings.Contains(req2.URL, "status=approved"))
- assertEqual(t, true, strings.Contains(req2.URL, "status=reject"))
-
- // because it's removed by key
- assertEqual(t, false, strings.Contains(req2.URL, "status=open"))
-}
-
-func TestSetQueryStringTypical(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- resp, err := dclr().
- SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
- Get(ts.URL)
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "200 OK", resp.Status())
- assertEqual(t, "TestGet: text response", resp.String())
-
- resp, err = dclr().
- SetQueryString("&%%amp;").
- Get(ts.URL)
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertEqual(t, "200 OK", resp.Status())
- assertEqual(t, "TestGet: text response", resp.String())
-}
-
-func TestOutputFileWithBaseDirAndRelativePath(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/dir-sample")
-
- DefaultClient = dc()
- SetRedirectPolicy(FlexibleRedirectPolicy(10))
- SetOutputDirectory(getTestDataPath() + "/dir-sample")
- SetDebug(true)
-
- resp, err := R().
- SetOutput("go-resty/test-img-success.png").
- Get(ts.URL + "/my-image.png")
-
- assertError(t, err)
- assertEqual(t, true, resp.Size() != 0)
-}
-
-func TestOutputFileWithBaseDirError(t *testing.T) {
- c := dc().SetRedirectPolicy(FlexibleRedirectPolicy(10)).
- SetOutputDirectory(getTestDataPath() + `/go-resty\0`)
-
- _ = c
-}
-
-func TestOutputPathDirNotExists(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/not-exists-dir")
-
- DefaultClient = dc()
- SetRedirectPolicy(FlexibleRedirectPolicy(10))
- SetOutputDirectory(getTestDataPath() + "/not-exists-dir")
-
- resp, err := R().
- SetOutput("test-img-success.png").
- Get(ts.URL + "/my-image.png")
-
- assertError(t, err)
- assertEqual(t, true, resp.Size() != 0)
-}
-
-func TestOutputFileAbsPath(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
- defer cleaupFiles("test-data/go-resty")
-
- _, err := dcr().
- SetOutput(getTestDataPath() + "/go-resty/test-img-success-2.png").
- Get(ts.URL + "/my-image.png")
-
- assertError(t, err)
-}
-
-func TestContextInternal(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- r := R().
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10))
-
- if r.isContextCancelledIfAvailable() {
- t.Error("isContextCancelledIfAvailable != false for vanilla R()")
- }
- r.addContextIfAvailable()
-
- resp, err := r.Get(ts.URL + "/")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
-}
-
-func TestSRV(t *testing.T) {
- c := dc().
- SetRedirectPolicy(FlexibleRedirectPolicy(20)).
- SetScheme("http")
-
- r := c.R().
- SetSRV(&SRVRecord{"xmpp-server", "google.com"})
-
- assertEqual(t, "xmpp-server", r.SRV.Service)
- assertEqual(t, "google.com", r.SRV.Domain)
-
- resp, err := r.Get("/")
- if err == nil {
- assertError(t, err)
- assertNotNil(t, resp)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- }
-}
-
-func TestSRVInvalidService(t *testing.T) {
- _, err := R().
- SetSRV(&SRVRecord{"nonexistantservice", "sampledomain"}).
- Get("/")
-
- assertNotNil(t, err)
- assertEqual(t, true, strings.Contains(err.Error(), "no such host"))
-}
-
-func TestDeprecatedCodeCovergae(t *testing.T) {
- var user1 User
- err := Unmarshal("application/json",
- []byte(`{"username":"testuser", "password":"testpass"}`), &user1)
- assertError(t, err)
- assertEqual(t, "testuser", user1.Username)
- assertEqual(t, "testpass", user1.Password)
-
- var user2 User
- err = Unmarshal("application/xml",
- []byte(`testusertestpass`),
- &user2)
- assertError(t, err)
- assertEqual(t, "testuser", user1.Username)
- assertEqual(t, "testpass", user1.Password)
-}
-
-func TestRequestDoNotParseResponse(t *testing.T) {
- ts := createGetServer(t)
- defer ts.Close()
-
- resp, err := dc().R().
- SetDoNotParseResponse(true).
- SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
- Get(ts.URL + "/")
-
- assertError(t, err)
-
- buf := acquireBuffer()
- defer releaseBuffer(buf)
- _, _ = io.Copy(buf, resp.RawBody())
-
- assertEqual(t, "TestGet: text response", buf.String())
- _ = resp.RawBody().Close()
-
- // Manually setting RawResponse as nil
- resp, err = dc().R().
- SetDoNotParseResponse(true).
- Get(ts.URL + "/")
-
- assertError(t, err)
-
- resp.RawResponse = nil
- assertNil(t, resp.RawBody())
-
- // just set test part
- SetDoNotParseResponse(true)
- assertEqual(t, true, DefaultClient.notParseResponse)
- SetDoNotParseResponse(false)
-}
-
-type noCtTest struct {
- Response string `json:"response"`
-}
-
-func TestRequestExpectContentTypeTest(t *testing.T) {
- ts := createGenServer(t)
- defer ts.Close()
-
- c := dc()
- resp, err := c.R().
- SetResult(noCtTest{}).
- ExpectContentType("application/json").
- Get(ts.URL + "/json-no-set")
-
- assertError(t, err)
- assertEqual(t, http.StatusOK, resp.StatusCode())
- assertNotNil(t, resp.Result())
- assertEqual(t, "json response no content type set", resp.Result().(*noCtTest).Response)
-
- assertEqual(t, "", firstNonEmpty("", ""))
-}
-
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Testing Unexported methods
//___________________________________
@@ -1304,6 +98,8 @@ func createGetServer(t *testing.T) *httptest.Server {
t.Errorf("Error: could not read get body: %s", err.Error())
}
_, _ = w.Write(body)
+ case "/v1/users/sample@sample.com/100002/details":
+ _, _ = w.Write([]byte("TestPathParams: text response"))
}
}
})
diff --git a/util.go b/util.go
index d939b471..edf81d2b 100644
--- a/util.go
+++ b/util.go
@@ -15,6 +15,7 @@ import (
"net/http"
"net/textproto"
"os"
+ "path"
"path/filepath"
"reflect"
"runtime"
@@ -204,3 +205,29 @@ func releaseBuffer(buf *bytes.Buffer) {
bufPool.Put(buf)
}
}
+
+func composeRequestURL(pathURL string, c *Client, r *Request) string {
+ if !strings.HasPrefix(pathURL, "/") {
+ pathURL = "/" + pathURL
+ }
+
+ reqURL := "/"
+ for _, segment := range strings.Split(pathURL, "/") {
+ if strings.HasPrefix(segment, "{") && strings.HasSuffix(segment, "}") {
+ key := segment[1 : len(segment)-1]
+ if val, found := r.pathParams[key]; found {
+ reqURL = path.Join(reqURL, val)
+ continue
+ }
+
+ if val, found := c.pathParams[key]; found {
+ reqURL = path.Join(reqURL, val)
+ continue
+ }
+ }
+
+ reqURL = path.Join(reqURL, segment)
+ }
+
+ return reqURL
+}