From 4194adce4cd5c971281999706b801a643750bfaa Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Fri, 3 Jul 2015 04:20:00 +0200 Subject: [PATCH] Adds additional bindings for multipart and form --- binding/binding.go | 8 +++++--- binding/binding_test.go | 39 +++++++++++++++++++++++++++++++++++++++ binding/form.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/binding/binding.go b/binding/binding.go index f719fbc..9cf701d 100644 --- a/binding/binding.go +++ b/binding/binding.go @@ -33,9 +33,11 @@ type StructValidator interface { var Validator StructValidator = &defaultValidator{} var ( - JSON = jsonBinding{} - XML = xmlBinding{} - Form = formBinding{} + JSON = jsonBinding{} + XML = xmlBinding{} + Form = formBinding{} + FormPost = formPostBinding{} + FormMultipart = formMultipartBinding{} ) func Default(method, contentType string) Binding { diff --git a/binding/binding_test.go b/binding/binding_test.go index db1678e..713e2e5 100644 --- a/binding/binding_test.go +++ b/binding/binding_test.go @@ -6,6 +6,7 @@ package binding import ( "bytes" + "mime/multipart" "net/http" "testing" @@ -64,6 +65,44 @@ func TestBindingXML(t *testing.T) { "bar", "foo") } +func createFormPostRequest() *http.Request { + req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo")) + req.Header.Set("Content-Type", MIMEPOSTForm) + return req +} + +func createFormMultipartRequest() *http.Request { + boundary := "--testboundary" + body := new(bytes.Buffer) + mw := multipart.NewWriter(body) + defer mw.Close() + + mw.SetBoundary(boundary) + mw.WriteField("foo", "bar") + mw.WriteField("bar", "foo") + req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body) + req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary) + return req +} + +func TestBindingFormPost(t *testing.T) { + req := createFormPostRequest() + var obj FooBarStruct + FormPost.Bind(req, &obj) + + assert.Equal(t, obj.Foo, "bar") + assert.Equal(t, obj.Bar, "foo") +} + +func TestBindingFormMultipart(t *testing.T) { + req := createFormMultipartRequest() + var obj FooBarStruct + FormMultipart.Bind(req, &obj) + + assert.Equal(t, obj.Foo, "bar") + assert.Equal(t, obj.Bar, "foo") +} + func TestValidationFails(t *testing.T) { var obj FooStruct req := requestWithBody("POST", "/", `{"bar": "foo"}`) diff --git a/binding/form.go b/binding/form.go index ff00b0d..2e26c0a 100644 --- a/binding/form.go +++ b/binding/form.go @@ -7,6 +7,8 @@ package binding import "net/http" type formBinding struct{} +type formPostBinding struct{} +type formMultipartBinding struct{} func (_ formBinding) Name() string { return "form" @@ -22,3 +24,31 @@ func (_ formBinding) Bind(req *http.Request, obj interface{}) error { } return validate(obj) } + +func (_ formPostBinding) Name() string { + return "form-urlencoded" +} + +func (_ formPostBinding) Bind(req *http.Request, obj interface{}) error { + if err := req.ParseForm(); err != nil { + return err + } + if err := mapForm(obj, req.PostForm); err != nil { + return err + } + return validate(obj) +} + +func (_ formMultipartBinding) Name() string { + return "multipart/form-data" +} + +func (_ formMultipartBinding) Bind(req *http.Request, obj interface{}) error { + if err := req.ParseMultipartForm(32 << 10); err != nil { + return err + } + if err := mapForm(obj, req.MultipartForm.Value); err != nil { + return err + } + return validate(obj) +}