Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SetMultiValueFormData method added #38

Merged
merged 3 commits into from
Sep 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ go:
- 1.4
- 1.5
- 1.6
- 1.7
- tip

before_install:
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 25 additions & 13 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
}

Expand All @@ -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()))
Expand Down
18 changes: 18 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions resty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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" {
Expand Down