summaryrefslogtreecommitdiff
path: root/vendor/github.com/gin-gonic/gin/binding
diff options
context:
space:
mode:
authorLibravatar Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com>2021-08-12 21:03:24 +0200
committerLibravatar GitHub <noreply@github.com>2021-08-12 21:03:24 +0200
commit98263a7de64269898a2f81207e38943b5c8e8653 (patch)
tree743c90f109a6c5d27832d1dcef2388d939f0f77a /vendor/github.com/gin-gonic/gin/binding
parentText duplication fix (#137) (diff)
downloadgotosocial-98263a7de64269898a2f81207e38943b5c8e8653.tar.xz
Grand test fixup (#138)
* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
Diffstat (limited to 'vendor/github.com/gin-gonic/gin/binding')
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/binding.go118
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go112
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/default_validator.go97
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/form.go61
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/form_mapping.go404
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/header.go34
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/json.go56
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/msgpack.go38
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go74
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/protobuf.go36
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/query.go21
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/uri.go18
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/xml.go33
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/yaml.go35
14 files changed, 1137 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 000000000..deb71661b
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/binding.go
@@ -0,0 +1,118 @@
+// 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.
+
+//go:build !nomsgpack
+// +build !nomsgpack
+
+package binding
+
+import "net/http"
+
+// Content-Type MIME of the most common data formats.
+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"
+ MIMEPROTOBUF = "application/x-protobuf"
+ MIMEMSGPACK = "application/x-msgpack"
+ MIMEMSGPACK2 = "application/msgpack"
+ MIMEYAML = "application/x-yaml"
+)
+
+// Binding describes the interface which needs to be implemented for binding the
+// data present in the request such as JSON request body, query parameters or
+// the form POST.
+type Binding interface {
+ Name() string
+ Bind(*http.Request, interface{}) error
+}
+
+// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
+// but it reads the body from supplied bytes instead of req.Body.
+type BindingBody interface {
+ Binding
+ BindBody([]byte, interface{}) error
+}
+
+// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
+// but it read the Params.
+type BindingUri interface {
+ Name() string
+ BindUri(map[string][]string, interface{}) error
+}
+
+// StructValidator is the minimal interface which needs to be implemented in
+// order for it to be used as the validator engine for ensuring the correctness
+// of the request. Gin provides a default implementation for this using
+// https://github.com/go-playground/validator/tree/v10.6.1.
+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 a slice|array, the validation should be performed travel on every element.
+ // If the received type is not a struct or slice|array, 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
+
+ // Engine returns the underlying validator engine which powers the
+ // StructValidator implementation.
+ Engine() interface{}
+}
+
+// Validator is the default validator which implements the StructValidator
+// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1
+// under the hood.
+var Validator StructValidator = &defaultValidator{}
+
+// These implement the Binding interface and can be used to bind the data
+// present in the request to struct instances.
+var (
+ JSON = jsonBinding{}
+ XML = xmlBinding{}
+ Form = formBinding{}
+ Query = queryBinding{}
+ FormPost = formPostBinding{}
+ FormMultipart = formMultipartBinding{}
+ ProtoBuf = protobufBinding{}
+ MsgPack = msgpackBinding{}
+ YAML = yamlBinding{}
+ Uri = uriBinding{}
+ Header = headerBinding{}
+)
+
+// Default returns the appropriate Binding instance based on the HTTP method
+// and the content type.
+func Default(method, contentType string) Binding {
+ if method == http.MethodGet {
+ return Form
+ }
+
+ switch contentType {
+ case MIMEJSON:
+ return JSON
+ case MIMEXML, MIMEXML2:
+ return XML
+ case MIMEPROTOBUF:
+ return ProtoBuf
+ case MIMEMSGPACK, MIMEMSGPACK2:
+ return MsgPack
+ case MIMEYAML:
+ return YAML
+ case MIMEMultipartPOSTForm:
+ return FormMultipart
+ default: // case MIMEPOSTForm:
+ 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/binding_nomsgpack.go b/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go
new file mode 100644
index 000000000..234244707
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go
@@ -0,0 +1,112 @@
+// Copyright 2020 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build nomsgpack
+// +build nomsgpack
+
+package binding
+
+import "net/http"
+
+// Content-Type MIME of the most common data formats.
+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"
+ MIMEPROTOBUF = "application/x-protobuf"
+ MIMEYAML = "application/x-yaml"
+)
+
+// Binding describes the interface which needs to be implemented for binding the
+// data present in the request such as JSON request body, query parameters or
+// the form POST.
+type Binding interface {
+ Name() string
+ Bind(*http.Request, interface{}) error
+}
+
+// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
+// but it reads the body from supplied bytes instead of req.Body.
+type BindingBody interface {
+ Binding
+ BindBody([]byte, interface{}) error
+}
+
+// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
+// but it read the Params.
+type BindingUri interface {
+ Name() string
+ BindUri(map[string][]string, interface{}) error
+}
+
+// StructValidator is the minimal interface which needs to be implemented in
+// order for it to be used as the validator engine for ensuring the correctness
+// of the request. Gin provides a default implementation for this using
+// https://github.com/go-playground/validator/tree/v10.6.1.
+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
+
+ // Engine returns the underlying validator engine which powers the
+ // StructValidator implementation.
+ Engine() interface{}
+}
+
+// Validator is the default validator which implements the StructValidator
+// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1
+// under the hood.
+var Validator StructValidator = &defaultValidator{}
+
+// These implement the Binding interface and can be used to bind the data
+// present in the request to struct instances.
+var (
+ JSON = jsonBinding{}
+ XML = xmlBinding{}
+ Form = formBinding{}
+ Query = queryBinding{}
+ FormPost = formPostBinding{}
+ FormMultipart = formMultipartBinding{}
+ ProtoBuf = protobufBinding{}
+ YAML = yamlBinding{}
+ Uri = uriBinding{}
+ Header = headerBinding{}
+)
+
+// Default returns the appropriate Binding instance based on the HTTP method
+// and the content type.
+func Default(method, contentType string) Binding {
+ if method == "GET" {
+ return Form
+ }
+
+ switch contentType {
+ case MIMEJSON:
+ return JSON
+ case MIMEXML, MIMEXML2:
+ return XML
+ case MIMEPROTOBUF:
+ return ProtoBuf
+ case MIMEYAML:
+ return YAML
+ case MIMEMultipartPOSTForm:
+ return FormMultipart
+ default: // case MIMEPOSTForm:
+ 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 000000000..87fc4c665
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/default_validator.go
@@ -0,0 +1,97 @@
+// Copyright 2017 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 (
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+
+ "github.com/go-playground/validator/v10"
+)
+
+type defaultValidator struct {
+ once sync.Once
+ validate *validator.Validate
+}
+
+type sliceValidateError []error
+
+// Error concatenates all error elements in sliceValidateError into a single string separated by \n.
+func (err sliceValidateError) Error() string {
+ n := len(err)
+ switch n {
+ case 0:
+ return ""
+ default:
+ var b strings.Builder
+ if err[0] != nil {
+ fmt.Fprintf(&b, "[%d]: %s", 0, err[0].Error())
+ }
+ if n > 1 {
+ for i := 1; i < n; i++ {
+ if err[i] != nil {
+ b.WriteString("\n")
+ fmt.Fprintf(&b, "[%d]: %s", i, err[i].Error())
+ }
+ }
+ }
+ return b.String()
+ }
+}
+
+var _ StructValidator = &defaultValidator{}
+
+// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
+func (v *defaultValidator) ValidateStruct(obj interface{}) error {
+ if obj == nil {
+ return nil
+ }
+
+ value := reflect.ValueOf(obj)
+ switch value.Kind() {
+ case reflect.Ptr:
+ return v.ValidateStruct(value.Elem().Interface())
+ case reflect.Struct:
+ return v.validateStruct(obj)
+ case reflect.Slice, reflect.Array:
+ count := value.Len()
+ validateRet := make(sliceValidateError, 0)
+ for i := 0; i < count; i++ {
+ if err := v.ValidateStruct(value.Index(i).Interface()); err != nil {
+ validateRet = append(validateRet, err)
+ }
+ }
+ if len(validateRet) == 0 {
+ return nil
+ }
+ return validateRet
+ default:
+ return nil
+ }
+}
+
+// validateStruct receives struct type
+func (v *defaultValidator) validateStruct(obj interface{}) error {
+ v.lazyinit()
+ return v.validate.Struct(obj)
+}
+
+// Engine returns the underlying validator engine which powers the default
+// Validator instance. This is useful if you want to register custom validations
+// or struct level validations. See validator GoDoc for more info -
+// https://pkg.go.dev/github.com/go-playground/validator/v10
+func (v *defaultValidator) Engine() interface{} {
+ v.lazyinit()
+ return v.validate
+}
+
+func (v *defaultValidator) lazyinit() {
+ v.once.Do(func() {
+ v.validate = validator.New()
+ v.validate.SetTagName("binding")
+ })
+}
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 000000000..040af9e20
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/form.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 defaultMemory = 32 << 20
+
+type formBinding struct{}
+type formPostBinding struct{}
+type formMultipartBinding struct{}
+
+func (formBinding) Name() string {
+ return "form"
+}
+
+func (formBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := req.ParseForm(); err != nil {
+ return err
+ }
+ if err := req.ParseMultipartForm(defaultMemory); err != nil && err != http.ErrNotMultipart {
+ return err
+ }
+ if err := mapForm(obj, req.Form); err != nil {
+ return err
+ }
+ 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(defaultMemory); err != nil {
+ return err
+ }
+ if err := mappingByPtr(obj, (*multipartRequest)(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 000000000..cb66dd4a7
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
@@ -0,0 +1,404 @@
+// 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"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/gin-gonic/gin/internal/bytesconv"
+ "github.com/gin-gonic/gin/internal/json"
+)
+
+var (
+ errUnknownType = errors.New("unknown type")
+
+ // ErrConvertMapStringSlice can not covert to map[string][]string
+ ErrConvertMapStringSlice = errors.New("can not convert to map slices of strings")
+
+ // ErrConvertToMapString can not convert to map[string]string
+ ErrConvertToMapString = errors.New("can not convert to map of strings")
+)
+
+func mapUri(ptr interface{}, m map[string][]string) error {
+ return mapFormByTag(ptr, m, "uri")
+}
+
+func mapForm(ptr interface{}, form map[string][]string) error {
+ return mapFormByTag(ptr, form, "form")
+}
+
+func MapFormWithTag(ptr interface{}, form map[string][]string, tag string) error {
+ return mapFormByTag(ptr, form, tag)
+}
+
+var emptyField = reflect.StructField{}
+
+func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
+ // Check if ptr is a map
+ ptrVal := reflect.ValueOf(ptr)
+ var pointed interface{}
+ if ptrVal.Kind() == reflect.Ptr {
+ ptrVal = ptrVal.Elem()
+ pointed = ptrVal.Interface()
+ }
+ if ptrVal.Kind() == reflect.Map &&
+ ptrVal.Type().Key().Kind() == reflect.String {
+ if pointed != nil {
+ ptr = pointed
+ }
+ return setFormMap(ptr, form)
+ }
+
+ return mappingByPtr(ptr, formSource(form), tag)
+}
+
+// setter tries to set value on a walking by fields of a struct
+type setter interface {
+ TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error)
+}
+
+type formSource map[string][]string
+
+var _ setter = formSource(nil)
+
+// TrySet tries to set a value by request's form source (like map[string][]string)
+func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSetted bool, err error) {
+ return setByForm(value, field, form, tagValue, opt)
+}
+
+func mappingByPtr(ptr interface{}, setter setter, tag string) error {
+ _, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag)
+ return err
+}
+
+func mapping(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) {
+ if field.Tag.Get(tag) == "-" { // just ignoring this field
+ return false, nil
+ }
+
+ var vKind = value.Kind()
+
+ if vKind == reflect.Ptr {
+ var isNew bool
+ vPtr := value
+ if value.IsNil() {
+ isNew = true
+ vPtr = reflect.New(value.Type().Elem())
+ }
+ isSetted, err := mapping(vPtr.Elem(), field, setter, tag)
+ if err != nil {
+ return false, err
+ }
+ if isNew && isSetted {
+ value.Set(vPtr)
+ }
+ return isSetted, nil
+ }
+
+ if vKind != reflect.Struct || !field.Anonymous {
+ ok, err := tryToSetValue(value, field, setter, tag)
+ if err != nil {
+ return false, err
+ }
+ if ok {
+ return true, nil
+ }
+ }
+
+ if vKind == reflect.Struct {
+ tValue := value.Type()
+
+ var isSetted bool
+ for i := 0; i < value.NumField(); i++ {
+ sf := tValue.Field(i)
+ if sf.PkgPath != "" && !sf.Anonymous { // unexported
+ continue
+ }
+ ok, err := mapping(value.Field(i), sf, setter, tag)
+ if err != nil {
+ return false, err
+ }
+ isSetted = isSetted || ok
+ }
+ return isSetted, nil
+ }
+ return false, nil
+}
+
+type setOptions struct {
+ isDefaultExists bool
+ defaultValue string
+}
+
+func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) {
+ var tagValue string
+ var setOpt setOptions
+
+ tagValue = field.Tag.Get(tag)
+ tagValue, opts := head(tagValue, ",")
+
+ if tagValue == "" { // default value is FieldName
+ tagValue = field.Name
+ }
+ if tagValue == "" { // when field is "emptyField" variable
+ return false, nil
+ }
+
+ var opt string
+ for len(opts) > 0 {
+ opt, opts = head(opts, ",")
+
+ if k, v := head(opt, "="); k == "default" {
+ setOpt.isDefaultExists = true
+ setOpt.defaultValue = v
+ }
+ }
+
+ return setter.TrySet(value, field, tagValue, setOpt)
+}
+
+func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSetted bool, err error) {
+ vs, ok := form[tagValue]
+ if !ok && !opt.isDefaultExists {
+ return false, nil
+ }
+
+ switch value.Kind() {
+ case reflect.Slice:
+ if !ok {
+ vs = []string{opt.defaultValue}
+ }
+ return true, setSlice(vs, value, field)
+ case reflect.Array:
+ if !ok {
+ vs = []string{opt.defaultValue}
+ }
+ if len(vs) != value.Len() {
+ return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
+ }
+ return true, setArray(vs, value, field)
+ default:
+ var val string
+ if !ok {
+ val = opt.defaultValue
+ }
+
+ if len(vs) > 0 {
+ val = vs[0]
+ }
+ return true, setWithProperType(val, value, field)
+ }
+}
+
+func setWithProperType(val string, value reflect.Value, field reflect.StructField) error {
+ switch value.Kind() {
+ case reflect.Int:
+ return setIntField(val, 0, value)
+ case reflect.Int8:
+ return setIntField(val, 8, value)
+ case reflect.Int16:
+ return setIntField(val, 16, value)
+ case reflect.Int32:
+ return setIntField(val, 32, value)
+ case reflect.Int64:
+ switch value.Interface().(type) {
+ case time.Duration:
+ return setTimeDuration(val, value, field)
+ }
+ return setIntField(val, 64, value)
+ case reflect.Uint:
+ return setUintField(val, 0, value)
+ case reflect.Uint8:
+ return setUintField(val, 8, value)
+ case reflect.Uint16:
+ return setUintField(val, 16, value)
+ case reflect.Uint32:
+ return setUintField(val, 32, value)
+ case reflect.Uint64:
+ return setUintField(val, 64, value)
+ case reflect.Bool:
+ return setBoolField(val, value)
+ case reflect.Float32:
+ return setFloatField(val, 32, value)
+ case reflect.Float64:
+ return setFloatField(val, 64, value)
+ case reflect.String:
+ value.SetString(val)
+ case reflect.Struct:
+ switch value.Interface().(type) {
+ case time.Time:
+ return setTimeField(val, field, value)
+ }
+ return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface())
+ case reflect.Map:
+ return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface())
+ default:
+ return errUnknownType
+ }
+ 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 err
+}
+
+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
+}
+
+func setTimeField(val string, structField reflect.StructField, value reflect.Value) error {
+ timeFormat := structField.Tag.Get("time_format")
+ if timeFormat == "" {
+ timeFormat = time.RFC3339
+ }
+
+ switch tf := strings.ToLower(timeFormat); tf {
+ case "unix", "unixnano":
+ tv, err := strconv.ParseInt(val, 10, 64)
+ if err != nil {
+ return err
+ }
+
+ d := time.Duration(1)
+ if tf == "unixnano" {
+ d = time.Second
+ }
+
+ t := time.Unix(tv/int64(d), tv%int64(d))
+ value.Set(reflect.ValueOf(t))
+ return nil
+
+ }
+
+ if val == "" {
+ value.Set(reflect.ValueOf(time.Time{}))
+ return nil
+ }
+
+ l := time.Local
+ if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC {
+ l = time.UTC
+ }
+
+ if locTag := structField.Tag.Get("time_location"); locTag != "" {
+ loc, err := time.LoadLocation(locTag)
+ if err != nil {
+ return err
+ }
+ l = loc
+ }
+
+ t, err := time.ParseInLocation(timeFormat, val, l)
+ if err != nil {
+ return err
+ }
+
+ value.Set(reflect.ValueOf(t))
+ return nil
+}
+
+func setArray(vals []string, value reflect.Value, field reflect.StructField) error {
+ for i, s := range vals {
+ err := setWithProperType(s, value.Index(i), field)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func setSlice(vals []string, value reflect.Value, field reflect.StructField) error {
+ slice := reflect.MakeSlice(value.Type(), len(vals), len(vals))
+ err := setArray(vals, slice, field)
+ if err != nil {
+ return err
+ }
+ value.Set(slice)
+ return nil
+}
+
+func setTimeDuration(val string, value reflect.Value, field reflect.StructField) error {
+ d, err := time.ParseDuration(val)
+ if err != nil {
+ return err
+ }
+ value.Set(reflect.ValueOf(d))
+ return nil
+}
+
+func head(str, sep string) (head string, tail string) {
+ idx := strings.Index(str, sep)
+ if idx < 0 {
+ return str, ""
+ }
+ return str[:idx], str[idx+len(sep):]
+}
+
+func setFormMap(ptr interface{}, form map[string][]string) error {
+ el := reflect.TypeOf(ptr).Elem()
+
+ if el.Kind() == reflect.Slice {
+ ptrMap, ok := ptr.(map[string][]string)
+ if !ok {
+ return ErrConvertMapStringSlice
+ }
+ for k, v := range form {
+ ptrMap[k] = v
+ }
+
+ return nil
+ }
+
+ ptrMap, ok := ptr.(map[string]string)
+ if !ok {
+ return ErrConvertToMapString
+ }
+ for k, v := range form {
+ ptrMap[k] = v[len(v)-1] // pick last
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/header.go b/vendor/github.com/gin-gonic/gin/binding/header.go
new file mode 100644
index 000000000..b99302af8
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/header.go
@@ -0,0 +1,34 @@
+package binding
+
+import (
+ "net/http"
+ "net/textproto"
+ "reflect"
+)
+
+type headerBinding struct{}
+
+func (headerBinding) Name() string {
+ return "header"
+}
+
+func (headerBinding) Bind(req *http.Request, obj interface{}) error {
+
+ if err := mapHeader(obj, req.Header); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func mapHeader(ptr interface{}, h map[string][]string) error {
+ return mappingByPtr(ptr, headerSource(h), "header")
+}
+
+type headerSource map[string][]string
+
+var _ setter = headerSource(nil)
+
+func (hs headerSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (bool, error) {
+ return setByForm(value, field, hs, textproto.CanonicalMIMEHeaderKey(tagValue), opt)
+}
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 000000000..45aaa4948
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/json.go
@@ -0,0 +1,56 @@
+// 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 (
+ "bytes"
+ "errors"
+ "io"
+ "net/http"
+
+ "github.com/gin-gonic/gin/internal/json"
+)
+
+// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
+// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an
+// interface{} as a Number instead of as a float64.
+var EnableDecoderUseNumber = false
+
+// EnableDecoderDisallowUnknownFields is used to call the DisallowUnknownFields method
+// on the JSON Decoder instance. DisallowUnknownFields causes the Decoder to
+// return an error when the destination is a struct and the input contains object
+// keys which do not match any non-ignored, exported fields in the destination.
+var EnableDecoderDisallowUnknownFields = false
+
+type jsonBinding struct{}
+
+func (jsonBinding) Name() string {
+ return "json"
+}
+
+func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
+ if req == nil || req.Body == nil {
+ return errors.New("invalid request")
+ }
+ return decodeJSON(req.Body, obj)
+}
+
+func (jsonBinding) BindBody(body []byte, obj interface{}) error {
+ return decodeJSON(bytes.NewReader(body), obj)
+}
+
+func decodeJSON(r io.Reader, obj interface{}) error {
+ decoder := json.NewDecoder(r)
+ if EnableDecoderUseNumber {
+ decoder.UseNumber()
+ }
+ if EnableDecoderDisallowUnknownFields {
+ decoder.DisallowUnknownFields()
+ }
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/msgpack.go b/vendor/github.com/gin-gonic/gin/binding/msgpack.go
new file mode 100644
index 000000000..2a442996a
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/msgpack.go
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+//go:build !nomsgpack
+// +build !nomsgpack
+
+package binding
+
+import (
+ "bytes"
+ "io"
+ "net/http"
+
+ "github.com/ugorji/go/codec"
+)
+
+type msgpackBinding struct{}
+
+func (msgpackBinding) Name() string {
+ return "msgpack"
+}
+
+func (msgpackBinding) Bind(req *http.Request, obj interface{}) error {
+ return decodeMsgPack(req.Body, obj)
+}
+
+func (msgpackBinding) BindBody(body []byte, obj interface{}) error {
+ return decodeMsgPack(bytes.NewReader(body), obj)
+}
+
+func decodeMsgPack(r io.Reader, obj interface{}) error {
+ cdc := new(codec.MsgpackHandle)
+ if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go
new file mode 100644
index 000000000..69c0a5443
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go
@@ -0,0 +1,74 @@
+// Copyright 2019 Gin Core Team. 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"
+ "mime/multipart"
+ "net/http"
+ "reflect"
+)
+
+type multipartRequest http.Request
+
+var _ setter = (*multipartRequest)(nil)
+
+var (
+ // ErrMultiFileHeader multipart.FileHeader invalid
+ ErrMultiFileHeader = errors.New("unsupported field type for multipart.FileHeader")
+
+ // ErrMultiFileHeaderLenInvalid array for []*multipart.FileHeader len invalid
+ ErrMultiFileHeaderLenInvalid = errors.New("unsupported len of array for []*multipart.FileHeader")
+)
+
+// TrySet tries to set a value by the multipart request with the binding a form file
+func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (bool, error) {
+ if files := r.MultipartForm.File[key]; len(files) != 0 {
+ return setByMultipartFormFile(value, field, files)
+ }
+
+ return setByForm(value, field, r.MultipartForm.Value, key, opt)
+}
+
+func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
+ switch value.Kind() {
+ case reflect.Ptr:
+ switch value.Interface().(type) {
+ case *multipart.FileHeader:
+ value.Set(reflect.ValueOf(files[0]))
+ return true, nil
+ }
+ case reflect.Struct:
+ switch value.Interface().(type) {
+ case multipart.FileHeader:
+ value.Set(reflect.ValueOf(*files[0]))
+ return true, nil
+ }
+ case reflect.Slice:
+ slice := reflect.MakeSlice(value.Type(), len(files), len(files))
+ isSetted, err = setArrayOfMultipartFormFiles(slice, field, files)
+ if err != nil || !isSetted {
+ return isSetted, err
+ }
+ value.Set(slice)
+ return true, nil
+ case reflect.Array:
+ return setArrayOfMultipartFormFiles(value, field, files)
+ }
+ return false, ErrMultiFileHeader
+}
+
+func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
+ if value.Len() != len(files) {
+ return false, ErrMultiFileHeaderLenInvalid
+ }
+ for i := range files {
+ setted, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1])
+ if err != nil || !setted {
+ return setted, err
+ }
+ }
+ return true, nil
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/protobuf.go b/vendor/github.com/gin-gonic/gin/binding/protobuf.go
new file mode 100644
index 000000000..f9ece928d
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/protobuf.go
@@ -0,0 +1,36 @@
+// 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 (
+ "io/ioutil"
+ "net/http"
+
+ "github.com/golang/protobuf/proto"
+)
+
+type protobufBinding struct{}
+
+func (protobufBinding) Name() string {
+ return "protobuf"
+}
+
+func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
+ buf, err := ioutil.ReadAll(req.Body)
+ if err != nil {
+ return err
+ }
+ return b.BindBody(buf, obj)
+}
+
+func (protobufBinding) BindBody(body []byte, obj interface{}) error {
+ if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil {
+ return err
+ }
+ // Here it's same to return validate(obj), but util now we can't add
+ // `binding:""` to the struct which automatically generate by gen-proto
+ return nil
+ // return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/query.go b/vendor/github.com/gin-gonic/gin/binding/query.go
new file mode 100644
index 000000000..219743f2a
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/query.go
@@ -0,0 +1,21 @@
+// Copyright 2017 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 queryBinding struct{}
+
+func (queryBinding) Name() string {
+ return "query"
+}
+
+func (queryBinding) Bind(req *http.Request, obj interface{}) error {
+ values := req.URL.Query()
+ if err := mapForm(obj, values); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/uri.go b/vendor/github.com/gin-gonic/gin/binding/uri.go
new file mode 100644
index 000000000..f91ec3819
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/uri.go
@@ -0,0 +1,18 @@
+// Copyright 2018 Gin Core Team. 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
+
+type uriBinding struct{}
+
+func (uriBinding) Name() string {
+ return "uri"
+}
+
+func (uriBinding) BindUri(m map[string][]string, obj interface{}) error {
+ if err := mapUri(obj, m); 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 000000000..4e9011496
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/xml.go
@@ -0,0 +1,33 @@
+// 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 (
+ "bytes"
+ "encoding/xml"
+ "io"
+ "net/http"
+)
+
+type xmlBinding struct{}
+
+func (xmlBinding) Name() string {
+ return "xml"
+}
+
+func (xmlBinding) Bind(req *http.Request, obj interface{}) error {
+ return decodeXML(req.Body, obj)
+}
+
+func (xmlBinding) BindBody(body []byte, obj interface{}) error {
+ return decodeXML(bytes.NewReader(body), obj)
+}
+func decodeXML(r io.Reader, obj interface{}) error {
+ decoder := xml.NewDecoder(r)
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/yaml.go b/vendor/github.com/gin-gonic/gin/binding/yaml.go
new file mode 100644
index 000000000..a2d36d6a5
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/yaml.go
@@ -0,0 +1,35 @@
+// Copyright 2018 Gin Core Team. 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 (
+ "bytes"
+ "io"
+ "net/http"
+
+ "gopkg.in/yaml.v2"
+)
+
+type yamlBinding struct{}
+
+func (yamlBinding) Name() string {
+ return "yaml"
+}
+
+func (yamlBinding) Bind(req *http.Request, obj interface{}) error {
+ return decodeYAML(req.Body, obj)
+}
+
+func (yamlBinding) BindBody(body []byte, obj interface{}) error {
+ return decodeYAML(bytes.NewReader(body), obj)
+}
+
+func decodeYAML(r io.Reader, obj interface{}) error {
+ decoder := yaml.NewDecoder(r)
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}