...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package middleware
16
17 import (
18 "net/http"
19 "reflect"
20
21 "github.com/go-openapi/errors"
22 "github.com/go-openapi/runtime"
23 "github.com/go-openapi/runtime/logger"
24 "github.com/go-openapi/spec"
25 "github.com/go-openapi/strfmt"
26 )
27
28
29 type UntypedRequestBinder struct {
30 Spec *spec.Swagger
31 Parameters map[string]spec.Parameter
32 Formats strfmt.Registry
33 paramBinders map[string]*untypedParamBinder
34 debugLogf func(string, ...any)
35 }
36
37
38 func NewUntypedRequestBinder(parameters map[string]spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *UntypedRequestBinder {
39 binders := make(map[string]*untypedParamBinder)
40 for fieldName, param := range parameters {
41 binders[fieldName] = newUntypedParamBinder(param, spec, formats)
42 }
43 return &UntypedRequestBinder{
44 Parameters: parameters,
45 paramBinders: binders,
46 Spec: spec,
47 Formats: formats,
48 debugLogf: debugLogfFunc(nil),
49 }
50 }
51
52
53 func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, data interface{}) error {
54 val := reflect.Indirect(reflect.ValueOf(data))
55 isMap := val.Kind() == reflect.Map
56 var result []error
57 o.debugLogf("binding %d parameters for %s %s", len(o.Parameters), request.Method, request.URL.EscapedPath())
58 for fieldName, param := range o.Parameters {
59 binder := o.paramBinders[fieldName]
60 o.debugLogf("binding parameter %s for %s %s", fieldName, request.Method, request.URL.EscapedPath())
61 var target reflect.Value
62 if !isMap {
63 binder.Name = fieldName
64 target = val.FieldByName(fieldName)
65 }
66
67 if isMap {
68 tpe := binder.Type()
69 if tpe == nil {
70 if param.Schema.Type.Contains(typeArray) {
71 tpe = reflect.TypeOf([]interface{}{})
72 } else {
73 tpe = reflect.TypeOf(map[string]interface{}{})
74 }
75 }
76 target = reflect.Indirect(reflect.New(tpe))
77 }
78
79 if !target.IsValid() {
80 result = append(result, errors.New(500, "parameter name %q is an unknown field", binder.Name))
81 continue
82 }
83
84 if err := binder.Bind(request, routeParams, consumer, target); err != nil {
85 result = append(result, err)
86 continue
87 }
88
89 if binder.validator != nil {
90 rr := binder.validator.Validate(target.Interface())
91 if rr != nil && rr.HasErrors() {
92 result = append(result, rr.AsError())
93 }
94 }
95
96 if isMap {
97 val.SetMapIndex(reflect.ValueOf(param.Name), target)
98 }
99 }
100
101 if len(result) > 0 {
102 return errors.CompositeValidationError(result...)
103 }
104
105 return nil
106 }
107
108
109
110
111 func (o *UntypedRequestBinder) SetLogger(lg logger.Logger) {
112 o.debugLogf = debugLogfFunc(lg)
113 }
114
115 func (o *UntypedRequestBinder) setDebugLogf(fn func(string, ...any)) {
116 o.debugLogf = fn
117 }
118
View as plain text