Skip to content

Commit

Permalink
Allow decoding same request multiple times
Browse files Browse the repository at this point in the history
  • Loading branch information
razonyang committed May 12, 2020
1 parent 4d67945 commit 4fe0723
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 27 deletions.
21 changes: 10 additions & 11 deletions form.go
Expand Up @@ -6,9 +6,11 @@
package form

import (
"bytes"
"encoding/json"
"encoding/xml"
"errors"
"io"
"io/ioutil"
"mime"
"net/http"
Expand Down Expand Up @@ -105,21 +107,18 @@ func parseContentType(r *http.Request) (string, error) {

// JSON is a JSON decoder.
func JSON(r *http.Request, v interface{}) error {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return err
}
return json.Unmarshal(body, v)
var buf bytes.Buffer
reader := io.TeeReader(r.Body, &buf)
r.Body = ioutil.NopCloser(&buf)
return json.NewDecoder(reader).Decode(v)
}

// XML is an XML decoder.
func XML(r *http.Request, v interface{}) error {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return err
}

return xml.Unmarshal(body, v)
var buf bytes.Buffer
reader := io.TeeReader(r.Body, &buf)
r.Body = ioutil.NopCloser(&buf)
return xml.NewDecoder(reader).Decode(v)
}

// NewForm returns a post form decoder with the given schema decoder.
Expand Down
36 changes: 20 additions & 16 deletions form_test.go
Expand Up @@ -58,15 +58,17 @@ func TestJSON(t *testing.T) {
actual := login{}
r := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(test.body))
r.Header.Set("Content-Type", ContentTypeJSON)
err := Decode(r, &actual)
if test.shouldErr {
assert.NotNil(t, err)
continue
for i := 0; i < 3; i++ {
err := Decode(r, &actual)
if test.shouldErr {
assert.NotNil(t, err)
continue
}
assert.Nil(t, err)
expected := login{validated: true}
assert.Nil(t, json.Unmarshal(test.body, &expected))
assert.Equal(t, expected, actual)
}
assert.Nil(t, err)
expected := login{validated: true}
assert.Nil(t, json.Unmarshal(test.body, &expected))
assert.Equal(t, expected, actual)
}
}

Expand All @@ -86,15 +88,17 @@ func TestXML(t *testing.T) {
actual := login{}
r := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(test.body))
r.Header.Set("Content-Type", ContentTypeXML)
err := Decode(r, &actual)
if test.shouldErr {
assert.NotNil(t, err)
continue
for i := 0; i < 3; i++ {
err := Decode(r, &actual)
if test.shouldErr {
assert.NotNil(t, err)
continue
}
assert.Nil(t, err)
expected := login{validated: true}
assert.Nil(t, xml.Unmarshal(test.body, &expected))
assert.Equal(t, expected, actual)
}
assert.Nil(t, err)
expected := login{validated: true}
assert.Nil(t, xml.Unmarshal(test.body, &expected))
assert.Equal(t, expected, actual)
}
}

Expand Down

0 comments on commit 4fe0723

Please sign in to comment.