From b9a489d7d4a47bc59237ae800ce5a018e1ed396e Mon Sep 17 00:00:00 2001 From: Jeevanandam M Date: Wed, 21 Sep 2016 21:15:29 -0700 Subject: [PATCH 1/3] #33 SetMultiValueFormData method added --- middleware.go | 38 +++++++++++++++++++++++++------------- request.go | 18 ++++++++++++++++++ resty_test.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/middleware.go b/middleware.go index 7fc0fc41..7ebe8450 100644 --- a/middleware.go +++ b/middleware.go @@ -269,18 +269,22 @@ func handleMultipart(c *Client, r *Request) (err error) { r.bodyBuf = &bytes.Buffer{} w := multipart.NewWriter(r.bodyBuf) - for p := range c.FormData { - w.WriteField(p, c.FormData.Get(p)) + for k, v := range c.FormData { + for _, iv := range v { + w.WriteField(k, iv) + } } - for p := range r.FormData { - if strings.HasPrefix(p, "@") { // file - err = addFile(w, p[1:], r.FormData.Get(p)) - if err != nil { - return + for k, v := range r.FormData { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return + } + } else { // form value + w.WriteField(k, iv) } - } else { // form value - w.WriteField(p, r.FormData.Get(p)) } } @@ -303,12 +307,20 @@ func handleMultipart(c *Client, r *Request) (err error) { func handleFormData(c *Client, r *Request) { formData := url.Values{} - for p := range c.FormData { - formData.Set(p, c.FormData.Get(p)) + for k, v := range c.FormData { + for _, iv := range v { + formData.Add(k, iv) + } } - for p := range r.FormData { // takes precedence - formData.Set(p, r.FormData.Get(p)) + for k, v := range r.FormData { + // remove form data field from client level by key + // since overrides happens for that key in the request + formData.Del(k) + + for _, iv := range v { + formData.Add(k, iv) + } } r.bodyBuf = bytes.NewBuffer([]byte(formData.Encode())) diff --git a/request.go b/request.go index 4a6173bc..3aece431 100644 --- a/request.go +++ b/request.go @@ -165,6 +165,24 @@ func (r *Request) SetFormData(data map[string]string) *Request { return r } +// SetMultiValueFormData method sets multiple form paramaters with multi-value +// at one go in the current request. +// resty.R(). +// SetMultiValueFormData(url.Values{ +// "search_criteria": []string{"book", "glass", "pencil"}, +// }) +// Also you can override form data value, which was set at client instance level +// +func (r *Request) SetMultiValueFormData(params url.Values) *Request { + for k, v := range params { + for _, kv := range v { + r.FormData.Add(k, kv) + } + } + + return r +} + // SetBody method sets the request body for the request. It supports various realtime need easy. // We can say its quite handy or powerful. Supported request body data types is `string`, `[]byte`, // `struct` and `map`. Body value can be pointer or non-pointer. Automatic marshalling diff --git a/resty_test.go b/resty_test.go index 7db48ac7..92abc7d5 100644 --- a/resty_test.go +++ b/resty_test.go @@ -508,6 +508,28 @@ func TestFormData(t *testing.T) { 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() @@ -1542,6 +1564,15 @@ func createFormPostServer(t *testing.T) *httptest.Server { t.Logf("City: %v", r.FormValue("city")) t.Logf("Zip Code: %v", r.FormValue("zip_code")) + w.Write([]byte("Success")) + return + } else if r.URL.Path == "/search" { + formEncodedData := r.Form.Encode() + t.Logf("Recevied Form Encoded values: %v", formEncodedData) + + assertEqual(t, true, strings.Contains(formEncodedData, "search_criteria=pencil")) + assertEqual(t, true, strings.Contains(formEncodedData, "search_criteria=glass")) + w.Write([]byte("Success")) return } else if r.URL.Path == "/upload" { From 44ccfc6a4bf9be61b8b338f2dc2b503d716e0ff1 Mon Sep 17 00:00:00 2001 From: Jeevanandam M Date: Wed, 21 Sep 2016 21:23:10 -0700 Subject: [PATCH 2/3] added go1.7 in travis config --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 059c7996..028f54d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ go: - 1.4 - 1.5 - 1.6 + - 1.7 - tip before_install: From 2a437bcef7416c3eab90bcb86d0554ba406169dd Mon Sep 17 00:00:00 2001 From: Jeevanandam M Date: Wed, 21 Sep 2016 21:29:55 -0700 Subject: [PATCH 3/3] readme update for form data [ci skip] --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 3e2d2629..304b2631 100644 --- a/README.md +++ b/README.md @@ -304,6 +304,14 @@ resp, err := resty.R(). "city": "new city update", }). Post("http://myapp.com/profile") + +// Multi value form data +criteria := url.Values{ + "search_criteria": []string{"book", "glass", "pencil"}, +} +resp, err := resty.R(). + SetMultiValueFormData(criteria). + Post("http://myapp.com/search") ``` #### Save HTTP Response into File