github.com/lenfree/buffalo@v0.7.3-0.20170207163156-891616ea4064/binding.go (about) 1 package buffalo 2 3 import ( 4 "encoding/json" 5 "encoding/xml" 6 "net/http" 7 "reflect" 8 "sync" 9 10 "github.com/gorilla/schema" 11 "github.com/markbates/pop/nulls" 12 "github.com/pkg/errors" 13 ) 14 15 var binderLock = &sync.Mutex{} 16 var binders = map[string]BinderFunc{} 17 var schemaDecoder *schema.Decoder 18 19 // BinderFunc takes a request and binds it to an interface. 20 // If there is a problem it should return an error. 21 type BinderFunc func(*http.Request, interface{}) error 22 23 // RegisterBinder maps a request Content-Type (application/json) 24 // to a BinderFunc. 25 func RegisterBinder(contentType string, fn BinderFunc) { 26 binderLock.Lock() 27 defer binderLock.Unlock() 28 binders[contentType] = fn 29 } 30 31 func init() { 32 schemaDecoder = schema.NewDecoder() 33 schemaDecoder.IgnoreUnknownKeys(true) 34 schemaDecoder.ZeroEmpty(true) 35 36 // register the types in the nulls package with the decoder 37 nulls.RegisterWithSchema(func(i interface{}, fn func(s string) reflect.Value) { 38 schemaDecoder.RegisterConverter(i, fn) 39 }) 40 41 sb := func(req *http.Request, value interface{}) error { 42 err := req.ParseForm() 43 if err != nil { 44 return errors.WithStack(err) 45 } 46 return schemaDecoder.Decode(value, req.PostForm) 47 } 48 binders["application/html"] = sb 49 binders["text/html"] = sb 50 binders["application/x-www-form-urlencoded"] = sb 51 } 52 53 func init() { 54 jb := func(req *http.Request, value interface{}) error { 55 return json.NewDecoder(req.Body).Decode(value) 56 } 57 binders["application/json"] = jb 58 binders["text/json"] = jb 59 binders["json"] = jb 60 } 61 62 func init() { 63 xb := func(req *http.Request, value interface{}) error { 64 return xml.NewDecoder(req.Body).Decode(value) 65 } 66 binders["application/xml"] = xb 67 binders["text/xml"] = xb 68 binders["xml"] = xb 69 }