Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Commit

Permalink
Allow for new binders to be registered with Buffalo closes #222 closes
Browse files Browse the repository at this point in the history
  • Loading branch information
markbates committed Feb 3, 2017
1 parent 657fc3b commit fcbf104
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 17 deletions.
65 changes: 65 additions & 0 deletions binding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package buffalo

import (
"encoding/json"
"encoding/xml"
"net/http"
"reflect"
"sync"

"github.com/gorilla/schema"
"github.com/markbates/pop/nulls"
"github.com/pkg/errors"
)

var binderLock = &sync.Mutex{}
var binders = map[string]BinderFunc{}
var schemaDecoder *schema.Decoder

type BinderFunc func(*http.Request, interface{}) error

func RegisterBinder(contentType string, fn BinderFunc) {
binderLock.Lock()
defer binderLock.Unlock()
binders[contentType] = fn
}

func init() {
schemaDecoder = schema.NewDecoder()
schemaDecoder.IgnoreUnknownKeys(true)
schemaDecoder.ZeroEmpty(true)

// register the types in the nulls package with the decoder
nulls.RegisterWithSchema(func(i interface{}, fn func(s string) reflect.Value) {
schemaDecoder.RegisterConverter(i, fn)
})

sb := func(req *http.Request, value interface{}) error {
err := req.ParseForm()
if err != nil {
return errors.WithStack(err)
}
return schemaDecoder.Decode(value, req.PostForm)
}
binders["application/html"] = sb
binders["text/html"] = sb
binders["application/x-www-form-urlencoded"] = sb
}

func init() {
jb := func(req *http.Request, value interface{}) error {
return json.NewDecoder(req.Body).Decode(value)
}
binders["application/json"] = jb
binders["text/json"] = jb
binders["json"] = jb
}

func init() {
xb := func(req *http.Request, value interface{}) error {
return xml.NewDecoder(req.Body).Decode(value)
}
binders["application/xml"] = xb
binders["text/xml"] = xb
binders["xml"] = xb
}
21 changes: 4 additions & 17 deletions default_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package buffalo
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"net/http"
Expand All @@ -15,7 +13,6 @@ import (
"time"

"github.com/gobuffalo/buffalo/render"
"github.com/gorilla/schema"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -163,21 +160,11 @@ func (d *DefaultContext) Render(status int, rr render.Renderer) error {
// is "application/xml" it will use "xml.NewDecoder". The default
// binder is "http://www.gorillatoolkit.org/pkg/schema".
func (d *DefaultContext) Bind(value interface{}) error {
switch strings.ToLower(d.Request().Header.Get("Content-Type")) {
case "application/json", "text/json", "json":
return json.NewDecoder(d.Request().Body).Decode(value)
case "application/xml", "text/xml", "xml":
return xml.NewDecoder(d.Request().Body).Decode(value)
default:
err := d.Request().ParseForm()
if err != nil {
return errors.WithStack(err)
}
dec := schema.NewDecoder()
dec.IgnoreUnknownKeys(true)
dec.ZeroEmpty(true)
return dec.Decode(value, d.Request().PostForm)
ct := strings.ToLower(d.Request().Header.Get("Content-Type"))
if b, ok := binders[ct]; ok {
return b(d.Request(), value)
}
return errors.Errorf("could not find a binder for %s", ct)
}

// LogField adds the key/value pair onto the Logger to be printed out
Expand Down

0 comments on commit fcbf104

Please sign in to comment.