aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/gin-gonic/gin/binding
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gin-gonic/gin/binding')
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/binding.go61
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/default_validator.go40
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/form.go24
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/form_mapping.go151
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/json.go25
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/xml.go24
6 files changed, 325 insertions, 0 deletions
diff --git a/vendor/github.com/gin-gonic/gin/binding/binding.go b/vendor/github.com/gin-gonic/gin/binding/binding.go
new file mode 100644
index 0000000..f719fbc
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/binding.go
@@ -0,0 +1,61 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import "net/http"
+
+const (
+ MIMEJSON = "application/json"
+ MIMEHTML = "text/html"
+ MIMEXML = "application/xml"
+ MIMEXML2 = "text/xml"
+ MIMEPlain = "text/plain"
+ MIMEPOSTForm = "application/x-www-form-urlencoded"
+ MIMEMultipartPOSTForm = "multipart/form-data"
+)
+
+type Binding interface {
+ Name() string
+ Bind(*http.Request, interface{}) error
+}
+
+type StructValidator interface {
+ // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
+ // If the received type is not a struct, any validation should be skipped and nil must be returned.
+ // If the received type is a struct or pointer to a struct, the validation should be performed.
+ // If the struct is not valid or the validation itself fails, a descriptive error should be returned.
+ // Otherwise nil must be returned.
+ ValidateStruct(interface{}) error
+}
+
+var Validator StructValidator = &defaultValidator{}
+
+var (
+ JSON = jsonBinding{}
+ XML = xmlBinding{}
+ Form = formBinding{}
+)
+
+func Default(method, contentType string) Binding {
+ if method == "GET" {
+ return Form
+ } else {
+ switch contentType {
+ case MIMEJSON:
+ return JSON
+ case MIMEXML, MIMEXML2:
+ return XML
+ default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
+ return Form
+ }
+ }
+}
+
+func validate(obj interface{}) error {
+ if Validator == nil {
+ return nil
+ }
+ return Validator.ValidateStruct(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/default_validator.go b/vendor/github.com/gin-gonic/gin/binding/default_validator.go
new file mode 100644
index 0000000..7f12152
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/default_validator.go
@@ -0,0 +1,40 @@
+package binding
+
+import (
+ "reflect"
+ "sync"
+
+ "gopkg.in/bluesuncorp/validator.v5"
+)
+
+type defaultValidator struct {
+ once sync.Once
+ validate *validator.Validate
+}
+
+var _ StructValidator = &defaultValidator{}
+
+func (v *defaultValidator) ValidateStruct(obj interface{}) error {
+ if kindOfData(obj) == reflect.Struct {
+ v.lazyinit()
+ if err := v.validate.Struct(obj); err != nil {
+ return error(err)
+ }
+ }
+ return nil
+}
+
+func (v *defaultValidator) lazyinit() {
+ v.once.Do(func() {
+ v.validate = validator.New("binding", validator.BakedInValidators)
+ })
+}
+
+func kindOfData(data interface{}) reflect.Kind {
+ value := reflect.ValueOf(data)
+ valueType := value.Kind()
+ if valueType == reflect.Ptr {
+ valueType = value.Elem().Kind()
+ }
+ return valueType
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/form.go b/vendor/github.com/gin-gonic/gin/binding/form.go
new file mode 100644
index 0000000..ff00b0d
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/form.go
@@ -0,0 +1,24 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import "net/http"
+
+type formBinding struct{}
+
+func (_ formBinding) Name() string {
+ return "form"
+}
+
+func (_ formBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := req.ParseForm(); err != nil {
+ return err
+ }
+ req.ParseMultipartForm(32 << 10) // 32 MB
+ if err := mapForm(obj, req.Form); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
new file mode 100644
index 0000000..d8b13b1
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
@@ -0,0 +1,151 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import (
+ "errors"
+ "reflect"
+ "strconv"
+)
+
+func mapForm(ptr interface{}, form map[string][]string) error {
+ typ := reflect.TypeOf(ptr).Elem()
+ val := reflect.ValueOf(ptr).Elem()
+ for i := 0; i < typ.NumField(); i++ {
+ typeField := typ.Field(i)
+ structField := val.Field(i)
+ if !structField.CanSet() {
+ continue
+ }
+
+ structFieldKind := structField.Kind()
+ inputFieldName := typeField.Tag.Get("form")
+ if inputFieldName == "" {
+ inputFieldName = typeField.Name
+
+ // if "form" tag is nil, we inspect if the field is a struct.
+ // this would not make sense for JSON parsing but it does for a form
+ // since data is flatten
+ if structFieldKind == reflect.Struct {
+ err := mapForm(structField.Addr().Interface(), form)
+ if err != nil {
+ return err
+ }
+ continue
+ }
+ }
+ inputValue, exists := form[inputFieldName]
+ if !exists {
+ continue
+ }
+
+ numElems := len(inputValue)
+ if structFieldKind == reflect.Slice && numElems > 0 {
+ sliceOf := structField.Type().Elem().Kind()
+ slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
+ for i := 0; i < numElems; i++ {
+ if err := setWithProperType(sliceOf, inputValue[i], slice.Index(i)); err != nil {
+ return err
+ }
+ }
+ val.Field(i).Set(slice)
+ } else {
+ if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
+ return err
+ }
+ }
+
+ }
+ return nil
+}
+
+func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error {
+ switch valueKind {
+ case reflect.Int:
+ return setIntField(val, 0, structField)
+ case reflect.Int8:
+ return setIntField(val, 8, structField)
+ case reflect.Int16:
+ return setIntField(val, 16, structField)
+ case reflect.Int32:
+ return setIntField(val, 32, structField)
+ case reflect.Int64:
+ return setIntField(val, 64, structField)
+ case reflect.Uint:
+ return setUintField(val, 0, structField)
+ case reflect.Uint8:
+ return setUintField(val, 8, structField)
+ case reflect.Uint16:
+ return setUintField(val, 16, structField)
+ case reflect.Uint32:
+ return setUintField(val, 32, structField)
+ case reflect.Uint64:
+ return setUintField(val, 64, structField)
+ case reflect.Bool:
+ return setBoolField(val, structField)
+ case reflect.Float32:
+ return setFloatField(val, 32, structField)
+ case reflect.Float64:
+ return setFloatField(val, 64, structField)
+ case reflect.String:
+ structField.SetString(val)
+ default:
+ return errors.New("Unknown type")
+ }
+ return nil
+}
+
+func setIntField(val string, bitSize int, field reflect.Value) error {
+ if val == "" {
+ val = "0"
+ }
+ intVal, err := strconv.ParseInt(val, 10, bitSize)
+ if err == nil {
+ field.SetInt(intVal)
+ }
+ return err
+}
+
+func setUintField(val string, bitSize int, field reflect.Value) error {
+ if val == "" {
+ val = "0"
+ }
+ uintVal, err := strconv.ParseUint(val, 10, bitSize)
+ if err == nil {
+ field.SetUint(uintVal)
+ }
+ return err
+}
+
+func setBoolField(val string, field reflect.Value) error {
+ if val == "" {
+ val = "false"
+ }
+ boolVal, err := strconv.ParseBool(val)
+ if err == nil {
+ field.SetBool(boolVal)
+ }
+ return nil
+}
+
+func setFloatField(val string, bitSize int, field reflect.Value) error {
+ if val == "" {
+ val = "0.0"
+ }
+ floatVal, err := strconv.ParseFloat(val, bitSize)
+ if err == nil {
+ field.SetFloat(floatVal)
+ }
+ return err
+}
+
+// Don't pass in pointers to bind to. Can lead to bugs. See:
+// https://github.com/codegangsta/martini-contrib/issues/40
+// https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659
+func ensureNotPointer(obj interface{}) {
+ if reflect.TypeOf(obj).Kind() == reflect.Ptr {
+ panic("Pointers are not accepted as binding models")
+ }
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/json.go b/vendor/github.com/gin-gonic/gin/binding/json.go
new file mode 100644
index 0000000..25c5a06
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/json.go
@@ -0,0 +1,25 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import (
+ "encoding/json"
+
+ "net/http"
+)
+
+type jsonBinding struct{}
+
+func (_ jsonBinding) Name() string {
+ return "json"
+}
+
+func (_ jsonBinding) Bind(req *http.Request, obj interface{}) error {
+ decoder := json.NewDecoder(req.Body)
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/xml.go b/vendor/github.com/gin-gonic/gin/binding/xml.go
new file mode 100644
index 0000000..cac4be8
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/xml.go
@@ -0,0 +1,24 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import (
+ "encoding/xml"
+ "net/http"
+)
+
+type xmlBinding struct{}
+
+func (_ xmlBinding) Name() string {
+ return "xml"
+}
+
+func (_ xmlBinding) Bind(req *http.Request, obj interface{}) error {
+ decoder := xml.NewDecoder(req.Body)
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}