Update all dependencies

Note: should we ditch vendoring?

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2025-09-29 10:20:26 +00:00 committed by Gabriel
parent 22fde8d30e
commit 0093393bc3
371 changed files with 91052 additions and 25816 deletions

View file

@ -218,8 +218,8 @@ func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Ro
// If a nil Router is provided, the DefaultRouter (denco-based) will be used.
func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context {
// Either there are no spec doc and analysis, or both of them.
if !((spec == nil && an == nil) || (spec != nil && an != nil)) {
panic(errors.New(http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
if (spec != nil || an != nil) && (spec == nil || an == nil) {
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
}
return &Context{
@ -307,6 +307,9 @@ type contentTypeValue struct {
// BasePath returns the base path for this API
func (c *Context) BasePath() string {
if c.spec == nil {
return ""
}
return c.spec.BasePath()
}
@ -341,7 +344,7 @@ func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, b
if len(res) == 0 {
cons, ok := route.Consumers[ct]
if !ok {
res = append(res, errors.New(500, "no consumer registered for %s", ct))
res = append(res, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct))
} else {
route.Consumer = cons
requestContentType = ct
@ -486,7 +489,7 @@ func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interfa
return nil, nil, err
}
return nil, nil, errors.New(http.StatusForbidden, err.Error())
return nil, nil, errors.New(http.StatusForbidden, "%v", err)
}
}
@ -552,7 +555,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
pr, ok := prods[c.api.DefaultProduces()]
if !ok {
panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format)))
}
prod = pr
}
@ -585,7 +588,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
producers := c.api.ProducersFor(normalizeOffers(offers))
prod, ok := producers[format]
if !ok {
panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format)))
}
if err := prod.Produce(rw, data); err != nil {
panic(err) // let the recovery middleware deal with this
@ -606,7 +609,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
pr, ok := prods[c.api.DefaultProduces()]
if !ok {
panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format)))
}
prod = pr
}
@ -617,7 +620,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
return
}
c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
c.api.ServeErrorFor(route.Operation.ID)(rw, r, fmt.Errorf("%d: %s", http.StatusInternalServerError, "can't produce response"))
}
// APIHandlerSwaggerUI returns a handler to serve the API.
@ -677,6 +680,15 @@ func (c *Context) APIHandler(builder Builder, opts ...UIOption) http.Handler {
return Spec(specPath, c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)), specOpts...)
}
// RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec
func (c *Context) RoutesHandler(builder Builder) http.Handler {
b := builder
if b == nil {
b = PassthroughBuilder
}
return NewRouter(c, b(NewOperationExecutor(c)))
}
func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []SpecOption) {
var title string
sp := c.spec.Spec()
@ -708,15 +720,6 @@ func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []Spec
return pth, uiOpts, []SpecOption{WithSpecDocument(doc)}
}
// RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec
func (c *Context) RoutesHandler(builder Builder) http.Handler {
b := builder
if b == nil {
b = PassthroughBuilder
}
return NewRouter(c, b(NewOperationExecutor(c)))
}
func cantFindProducer(format string) string {
return "can't find a producer for " + format
}

View file

@ -25,7 +25,7 @@ const (
PathParamCharacter = '='
// MaxSize is max size of records and internal slice.
MaxSize = (1 << 22) - 1
MaxSize = (1 << 22) - 1 //nolint:mnd
)
// Router represents a URL router.
@ -62,7 +62,7 @@ func (rt *Router) Lookup(path string) (data interface{}, params Params, found bo
if !found {
return nil, nil, false
}
for i := 0; i < len(params); i++ {
for i := range params {
params[i].Name = nd.paramNames[i]
}
return nd.data, params, true
@ -138,12 +138,17 @@ func newDoubleArray() *doubleArray {
// 32 10 8 0
type baseCheck uint32
const (
flagsBits = 10
checkBits = 8
)
func (bc baseCheck) Base() int {
return int(bc >> 10)
return int(bc >> flagsBits)
}
func (bc *baseCheck) SetBase(base int) {
*bc |= baseCheck(base) << 10
*bc |= baseCheck(base) << flagsBits //nolint:gosec // integer conversion is ok
}
func (bc baseCheck) Check() byte {
@ -171,24 +176,27 @@ func (bc baseCheck) IsAnyParam() bool {
}
func (bc *baseCheck) SetSingleParam() {
*bc |= (1 << 8)
*bc |= (1 << checkBits)
}
func (bc *baseCheck) SetWildcardParam() {
*bc |= (1 << 9)
*bc |= (1 << (checkBits + 1))
}
const (
paramTypeSingle = 0x0100
paramTypeWildcard = 0x0200
paramTypeAny = 0x0300
indexOffset = 32
indexMask = uint64(0xffffffff)
)
func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Param, bool) {
indices := make([]uint64, 0, 1)
for i := 0; i < len(path); i++ {
for i := range len(path) {
if da.bc[idx].IsAnyParam() {
indices = append(indices, (uint64(i)<<32)|(uint64(idx)&0xffffffff))
indices = append(indices, (uint64(i)<<indexOffset)|(uint64(idx)&indexMask)) //nolint:gosec // integer conversion is okay
}
c := path[i]
if idx = nextIndex(da.bc[idx].Base(), c); idx >= len(da.bc) || da.bc[idx].Check() != c {
@ -201,7 +209,7 @@ func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Pa
BACKTRACKING:
for j := len(indices) - 1; j >= 0; j-- {
i, idx := int(indices[j]>>32), int(indices[j]&0xffffffff)
i, idx := int(indices[j]>>indexOffset), int(indices[j]&indexMask) //nolint:gosec // integer conversion is okay
if da.bc[idx].IsSingleParam() {
nextIdx := nextIndex(da.bc[idx].Base(), ParamCharacter)
if nextIdx >= len(da.bc) {
@ -428,6 +436,7 @@ func NewRecord(key string, value interface{}) Record {
// record represents a record that use to build the Double-Array.
type record struct {
Record
paramNames []string
}

View file

@ -25,6 +25,11 @@ const (
isSpace
)
const (
asciiMaxControlChar = 31
asciiMaxChar = 127
)
func init() {
// OCTET = <any 8-bit sequence of data>
// CHAR = <any US-ASCII character (octets 0 - 127)>
@ -42,10 +47,10 @@ func init() {
// token = 1*<any CHAR except CTLs or separators>
// qdtext = <any TEXT except <">>
for c := 0; c < 256; c++ {
for c := range 256 {
var t octetType
isCtl := c <= 31 || c == 127
isChar := 0 <= c && c <= 127
isCtl := c <= asciiMaxControlChar || c == asciiMaxChar
isChar := 0 <= c && c <= asciiMaxChar
isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
if strings.ContainsRune(" \t\r\n", rune(c)) {
t |= isSpace
@ -92,7 +97,7 @@ func ParseList(header http.Header, key string) []string {
end := 0
escape := false
quote := false
for i := 0; i < len(s); i++ {
for i := range len(s) {
b := s[i]
switch {
case escape:

View file

@ -94,5 +94,6 @@ func normalizeOffers(orig []string) (norm []string) {
}
func normalizeOffer(orig string) string {
return strings.SplitN(orig, ";", 2)[0]
const maxParts = 2
return strings.SplitN(orig, ";", maxParts)[0]
}

View file

@ -24,12 +24,12 @@ import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/spec"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/swag/conv"
"github.com/go-openapi/swag/stringutils"
"github.com/go-openapi/validate"
"github.com/go-openapi/runtime"
)
const defaultMaxMemory = 32 << 20
@ -66,85 +66,6 @@ func (p *untypedParamBinder) Type() reflect.Type {
return p.typeForSchema(p.parameter.Type, p.parameter.Format, p.parameter.Items)
}
func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type {
switch tpe {
case "boolean":
return reflect.TypeOf(true)
case typeString:
if tt, ok := p.formats.GetType(format); ok {
return tt
}
return reflect.TypeOf("")
case "integer":
switch format {
case "int8":
return reflect.TypeOf(int8(0))
case "int16":
return reflect.TypeOf(int16(0))
case "int32":
return reflect.TypeOf(int32(0))
case "int64":
return reflect.TypeOf(int64(0))
default:
return reflect.TypeOf(int64(0))
}
case "number":
switch format {
case "float":
return reflect.TypeOf(float32(0))
case "double":
return reflect.TypeOf(float64(0))
}
case typeArray:
if items == nil {
return nil
}
itemsType := p.typeForSchema(items.Type, items.Format, items.Items)
if itemsType == nil {
return nil
}
return reflect.MakeSlice(reflect.SliceOf(itemsType), 0, 0).Type()
case "file":
return reflect.TypeOf(&runtime.File{}).Elem()
case "object":
return reflect.TypeOf(map[string]interface{}{})
}
return nil
}
func (p *untypedParamBinder) allowsMulti() bool {
return p.parameter.In == "query" || p.parameter.In == "formData"
}
func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
if tpe == typeArray {
if cf == "multi" {
if !p.allowsMulti() {
return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
}
vv, hasKey, _ := values.GetOK(name)
return vv, false, hasKey, nil
}
v, hk, hv := values.GetOK(name)
if !hv {
return nil, false, hk, nil
}
d, c, e := p.readFormattedSliceFieldValue(v[len(v)-1], target)
return d, c, hk, e
}
vv, hk, _ := values.GetOK(name)
return vv, false, hk, nil
}
func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, target reflect.Value) error {
// fmt.Println("binding", p.name, "as", p.Type())
switch p.parameter.In {
@ -264,10 +185,89 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
target.Set(reflect.Indirect(newValue))
return nil
default:
return errors.New(500, fmt.Sprintf("invalid parameter location %q", p.parameter.In))
return fmt.Errorf("%d: invalid parameter location %q", http.StatusInternalServerError, p.parameter.In)
}
}
func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type {
switch tpe {
case "boolean":
return reflect.TypeOf(true)
case typeString:
if tt, ok := p.formats.GetType(format); ok {
return tt
}
return reflect.TypeOf("")
case "integer":
switch format {
case "int8":
return reflect.TypeOf(int8(0))
case "int16":
return reflect.TypeOf(int16(0))
case "int32":
return reflect.TypeOf(int32(0))
case "int64":
return reflect.TypeOf(int64(0))
default:
return reflect.TypeOf(int64(0))
}
case "number":
switch format {
case "float":
return reflect.TypeOf(float32(0))
case "double":
return reflect.TypeOf(float64(0))
}
case typeArray:
if items == nil {
return nil
}
itemsType := p.typeForSchema(items.Type, items.Format, items.Items)
if itemsType == nil {
return nil
}
return reflect.MakeSlice(reflect.SliceOf(itemsType), 0, 0).Type()
case "file":
return reflect.TypeOf(&runtime.File{}).Elem()
case "object":
return reflect.TypeOf(map[string]interface{}{})
}
return nil
}
func (p *untypedParamBinder) allowsMulti() bool {
return p.parameter.In == "query" || p.parameter.In == "formData"
}
func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
if tpe == typeArray {
if cf == "multi" {
if !p.allowsMulti() {
return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
}
vv, hasKey, _ := values.GetOK(name)
return vv, false, hasKey, nil
}
v, hk, hv := values.GetOK(name)
if !hv {
return nil, false, hk, nil
}
d, c, e := p.readFormattedSliceFieldValue(v[len(v)-1], target)
return d, c, hk, e
}
vv, hk, _ := values.GetOK(name)
return vv, false, hk, nil
}
func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflect.Value) error {
if p.parameter.Type == typeArray {
return p.setSliceFieldValue(target, p.parameter.Default, data, hasKey)
@ -331,7 +331,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue in
}
return nil
}
b, err := swag.ConvertBool(data)
b, err := conv.ConvertBool(data)
if err != nil {
return err
}
@ -431,7 +431,7 @@ func (p *untypedParamBinder) tryUnmarshaler(target reflect.Value, defaultValue i
return false, nil
}
// When a type implements encoding.TextUnmarshaler we'll use that instead of reflecting some more
if reflect.PtrTo(target.Type()).Implements(textUnmarshalType) {
if reflect.PointerTo(target.Type()).Implements(textUnmarshalType) {
if defaultValue != nil && len(data) == 0 {
target.Set(reflect.ValueOf(defaultValue))
return true, nil
@ -455,7 +455,7 @@ func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target re
return nil, true, nil
}
return swag.SplitByFormat(data, p.parameter.CollectionFormat), false, nil
return stringutils.SplitByFormat(data, p.parameter.CollectionFormat), false, nil
}
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
@ -479,7 +479,7 @@ func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultVal
value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz)
for i := 0; i < sz; i++ {
for i := range sz {
if err := p.setFieldValue(value.Index(i), nil, data[i], hasKey); err != nil {
return err
}

View file

@ -77,7 +77,7 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara
}
if !target.IsValid() {
result = append(result, errors.New(500, "parameter name %q is an unknown field", binder.Name))
result = append(result, errors.New(http.StatusInternalServerError, "parameter name %q is an unknown field", binder.Name))
continue
}

View file

@ -22,18 +22,16 @@ import (
"regexp"
"strings"
"github.com/go-openapi/runtime/logger"
"github.com/go-openapi/runtime/security"
"github.com/go-openapi/swag"
"github.com/go-openapi/analysis"
"github.com/go-openapi/errors"
"github.com/go-openapi/loads"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/logger"
"github.com/go-openapi/runtime/middleware/denco"
"github.com/go-openapi/runtime/security"
"github.com/go-openapi/spec"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware/denco"
"github.com/go-openapi/swag/stringutils"
)
// RouteParam is a object to capture route params in a framework agnostic way.
@ -336,6 +334,7 @@ type routeEntry struct {
// MatchedRoute represents the route that was matched in this request
type MatchedRoute struct {
routeEntry
Params RouteParams
Consumer runtime.Consumer
Producer runtime.Producer
@ -377,7 +376,8 @@ func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
}
// a workaround to handle fragment/composing parameters until they are supported in denco router
// check if this parameter is a fragment within a path segment
if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + 2; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' {
const enclosureSize = 2
if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + enclosureSize; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' {
// extract fragment parameters
ep := strings.Split(entry.PathPattern[xpos:], "/")[0]
pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil)
@ -460,11 +460,11 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp))
// add API defaults if not part of the spec
if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !swag.ContainsStringsCI(consumes, defConsumes) {
if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !stringutils.ContainsStringsCI(consumes, defConsumes) {
consumes = append(consumes, defConsumes)
}
if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) {
if defProduces := d.api.DefaultProduces(); defProduces != "" && !stringutils.ContainsStringsCI(produces, defProduces) {
produces = append(produces, defProduces)
}
@ -489,6 +489,20 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
}
}
func (d *defaultRouteBuilder) Build() *defaultRouter {
routers := make(map[string]*denco.Router)
for method, records := range d.records {
router := denco.New()
_ = router.Build(records)
routers[method] = router
}
return &defaultRouter{
spec: d.spec,
routers: routers,
debugLogf: d.debugLogf,
}
}
func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) RouteAuthenticators {
requirements := d.analyzer.SecurityRequirementsFor(operation)
auths := make([]RouteAuthenticator, 0, len(requirements))
@ -515,17 +529,3 @@ func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) Rou
}
return auths
}
func (d *defaultRouteBuilder) Build() *defaultRouter {
routers := make(map[string]*denco.Router)
for method, records := range d.records {
router := denco.New()
_ = router.Build(records)
routers[method] = router
}
return &defaultRouter{
spec: d.spec,
routers: routers,
debugLogf: d.debugLogf,
}
}

View file

@ -168,6 +168,6 @@ func serveUI(pth string, assets []byte, next http.Handler) http.Handler {
rw.Header().Set(contentTypeHeader, "text/plain")
rw.WriteHeader(http.StatusNotFound)
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
_, _ = fmt.Fprintf(rw, "%q not found", pth)
})
}

View file

@ -29,25 +29,10 @@ import (
"github.com/go-openapi/runtime"
)
// NewAPI creates the default untyped API
func NewAPI(spec *loads.Document) *API {
var an *analysis.Spec
if spec != nil && spec.Spec() != nil {
an = analysis.New(spec.Spec())
}
api := &API{
spec: spec,
analyzer: an,
consumers: make(map[string]runtime.Consumer, 10),
producers: make(map[string]runtime.Producer, 10),
authenticators: make(map[string]runtime.Authenticator),
operations: make(map[string]map[string]runtime.OperationHandler),
ServeError: errors.ServeError,
Models: make(map[string]func() interface{}),
formats: strfmt.NewFormats(),
}
return api.WithJSONDefaults()
}
const (
smallPreallocatedSlots = 10
mediumPreallocatedSlots = 30
)
// API represents an untyped mux for a swagger spec
type API struct {
@ -61,10 +46,31 @@ type API struct {
authorizer runtime.Authorizer
operations map[string]map[string]runtime.OperationHandler
ServeError func(http.ResponseWriter, *http.Request, error)
Models map[string]func() interface{}
Models map[string]func() any
formats strfmt.Registry
}
// NewAPI creates the default untyped API
func NewAPI(spec *loads.Document) *API {
var an *analysis.Spec
if spec != nil && spec.Spec() != nil {
an = analysis.New(spec.Spec())
}
api := &API{
spec: spec,
analyzer: an,
consumers: make(map[string]runtime.Consumer, smallPreallocatedSlots),
producers: make(map[string]runtime.Producer, smallPreallocatedSlots),
authenticators: make(map[string]runtime.Authenticator),
operations: make(map[string]map[string]runtime.OperationHandler),
ServeError: errors.ServeError,
Models: make(map[string]func() any),
formats: strfmt.NewFormats(),
}
return api.WithJSONDefaults()
}
// WithJSONDefaults loads the json defaults for this api
func (d *API) WithJSONDefaults() *API {
d.DefaultConsumes = runtime.JSONMime
@ -115,7 +121,7 @@ func (d *API) RegisterAuthorizer(handler runtime.Authorizer) {
// RegisterConsumer registers a consumer for a media type.
func (d *API) RegisterConsumer(mediaType string, handler runtime.Consumer) {
if d.consumers == nil {
d.consumers = make(map[string]runtime.Consumer, 10)
d.consumers = make(map[string]runtime.Consumer, smallPreallocatedSlots)
}
d.consumers[strings.ToLower(mediaType)] = handler
}
@ -123,7 +129,7 @@ func (d *API) RegisterConsumer(mediaType string, handler runtime.Consumer) {
// RegisterProducer registers a producer for a media type
func (d *API) RegisterProducer(mediaType string, handler runtime.Producer) {
if d.producers == nil {
d.producers = make(map[string]runtime.Producer, 10)
d.producers = make(map[string]runtime.Producer, smallPreallocatedSlots)
}
d.producers[strings.ToLower(mediaType)] = handler
}
@ -131,7 +137,7 @@ func (d *API) RegisterProducer(mediaType string, handler runtime.Producer) {
// RegisterOperation registers an operation handler for an operation name
func (d *API) RegisterOperation(method, path string, handler runtime.OperationHandler) {
if d.operations == nil {
d.operations = make(map[string]map[string]runtime.OperationHandler, 30)
d.operations = make(map[string]map[string]runtime.OperationHandler, mediumPreallocatedSlots)
}
um := strings.ToUpper(method)
if b, ok := d.operations[um]; !ok || b == nil {

View file

@ -20,9 +20,8 @@ import (
"strings"
"github.com/go-openapi/errors"
"github.com/go-openapi/swag"
"github.com/go-openapi/runtime"
"github.com/go-openapi/swag/stringutils"
)
type validation struct {
@ -30,7 +29,7 @@ type validation struct {
result []error
request *http.Request
route *MatchedRoute
bound map[string]interface{}
bound map[string]any
}
// ContentType validates the content type of a request
@ -42,14 +41,14 @@ func validateContentType(allowed []string, actual string) error {
if err != nil {
return errors.InvalidContentType(actual, allowed)
}
if swag.ContainsStringsCI(allowed, mt) {
if stringutils.ContainsStringsCI(allowed, mt) {
return nil
}
if swag.ContainsStringsCI(allowed, "*/*") {
if stringutils.ContainsStringsCI(allowed, "*/*") {
return nil
}
parts := strings.Split(actual, "/")
if len(parts) == 2 && swag.ContainsStringsCI(allowed, parts[0]+"/*") {
if len(parts) == 2 && stringutils.ContainsStringsCI(allowed, parts[0]+"/*") {
return nil
}
return errors.InvalidContentType(actual, allowed)
@ -60,7 +59,7 @@ func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *
context: ctx,
request: request,
route: route,
bound: make(map[string]interface{}),
bound: make(map[string]any),
}
validate.debugLogf("validating request %s %s", request.Method, request.URL.EscapedPath())
@ -83,7 +82,7 @@ func (v *validation) parameters() {
v.debugLogf("validating request parameters for %s %s", v.request.Method, v.request.URL.EscapedPath())
if result := v.route.Binder.Bind(v.request, v.route.Params, v.route.Consumer, v.bound); result != nil {
if result.Error() == "validation failure list" {
for _, e := range result.(*errors.Validation).Value.([]interface{}) {
for _, e := range result.(*errors.Validation).Value.([]any) {
v.result = append(v.result, e.(error))
}
return
@ -111,7 +110,7 @@ func (v *validation) contentType() {
if ct != "" && v.route.Consumer == nil {
cons, ok := v.route.Consumers[ct]
if !ok {
v.result = append(v.result, errors.New(500, "no consumer registered for %s", ct))
v.result = append(v.result, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct))
} else {
v.route.Consumer = cons
}