diff options
author | 2025-03-09 17:47:56 +0100 | |
---|---|---|
committer | 2025-03-10 01:59:49 +0100 | |
commit | 3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch) | |
tree | f61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/go-openapi/runtime/middleware | |
parent | [chore] update URLs to forked source (diff) | |
download | gotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz |
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/go-openapi/runtime/middleware')
23 files changed, 0 insertions, 4420 deletions
diff --git a/vendor/github.com/go-openapi/runtime/middleware/context.go b/vendor/github.com/go-openapi/runtime/middleware/context.go deleted file mode 100644 index 44cecf118..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/context.go +++ /dev/null @@ -1,722 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - stdContext "context" - "fmt" - "net/http" - "net/url" - "path" - "strings" - "sync" - - "github.com/go-openapi/analysis" - "github.com/go-openapi/errors" - "github.com/go-openapi/loads" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/logger" - "github.com/go-openapi/runtime/middleware/untyped" - "github.com/go-openapi/runtime/security" -) - -// Debug when true turns on verbose logging -var Debug = logger.DebugEnabled() - -// Logger is the standard libray logger used for printing debug messages -var Logger logger.Logger = logger.StandardLogger{} - -func debugLogfFunc(lg logger.Logger) func(string, ...any) { - if logger.DebugEnabled() { - if lg == nil { - return Logger.Debugf - } - - return lg.Debugf - } - - // muted logger - return func(_ string, _ ...any) {} -} - -// A Builder can create middlewares -type Builder func(http.Handler) http.Handler - -// PassthroughBuilder returns the handler, aka the builder identity function -func PassthroughBuilder(handler http.Handler) http.Handler { return handler } - -// RequestBinder is an interface for types to implement -// when they want to be able to bind from a request -type RequestBinder interface { - BindRequest(*http.Request, *MatchedRoute) error -} - -// Responder is an interface for types to implement -// when they want to be considered for writing HTTP responses -type Responder interface { - WriteResponse(http.ResponseWriter, runtime.Producer) -} - -// ResponderFunc wraps a func as a Responder interface -type ResponderFunc func(http.ResponseWriter, runtime.Producer) - -// WriteResponse writes to the response -func (fn ResponderFunc) WriteResponse(rw http.ResponseWriter, pr runtime.Producer) { - fn(rw, pr) -} - -// Context is a type safe wrapper around an untyped request context -// used throughout to store request context with the standard context attached -// to the http.Request -type Context struct { - spec *loads.Document - analyzer *analysis.Spec - api RoutableAPI - router Router - debugLogf func(string, ...any) // a logging function to debug context and all components using it -} - -type routableUntypedAPI struct { - api *untyped.API - hlock *sync.Mutex - handlers map[string]map[string]http.Handler - defaultConsumes string - defaultProduces string -} - -func newRoutableUntypedAPI(spec *loads.Document, api *untyped.API, context *Context) *routableUntypedAPI { - var handlers map[string]map[string]http.Handler - if spec == nil || api == nil { - return nil - } - analyzer := analysis.New(spec.Spec()) - for method, hls := range analyzer.Operations() { - um := strings.ToUpper(method) - for path, op := range hls { - schemes := analyzer.SecurityRequirementsFor(op) - - if oh, ok := api.OperationHandlerFor(method, path); ok { - if handlers == nil { - handlers = make(map[string]map[string]http.Handler) - } - if b, ok := handlers[um]; !ok || b == nil { - handlers[um] = make(map[string]http.Handler) - } - - var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // lookup route info in the context - route, rCtx, _ := context.RouteInfo(r) - if rCtx != nil { - r = rCtx - } - - // bind and validate the request using reflection - var bound interface{} - var validation error - bound, r, validation = context.BindAndValidate(r, route) - if validation != nil { - context.Respond(w, r, route.Produces, route, validation) - return - } - - // actually handle the request - result, err := oh.Handle(bound) - if err != nil { - // respond with failure - context.Respond(w, r, route.Produces, route, err) - return - } - - // respond with success - context.Respond(w, r, route.Produces, route, result) - }) - - if len(schemes) > 0 { - handler = newSecureAPI(context, handler) - } - handlers[um][path] = handler - } - } - } - - return &routableUntypedAPI{ - api: api, - hlock: new(sync.Mutex), - handlers: handlers, - defaultProduces: api.DefaultProduces, - defaultConsumes: api.DefaultConsumes, - } -} - -func (r *routableUntypedAPI) HandlerFor(method, path string) (http.Handler, bool) { - r.hlock.Lock() - paths, ok := r.handlers[strings.ToUpper(method)] - if !ok { - r.hlock.Unlock() - return nil, false - } - handler, ok := paths[path] - r.hlock.Unlock() - return handler, ok -} -func (r *routableUntypedAPI) ServeErrorFor(_ string) func(http.ResponseWriter, *http.Request, error) { - return r.api.ServeError -} -func (r *routableUntypedAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { - return r.api.ConsumersFor(mediaTypes) -} -func (r *routableUntypedAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer { - return r.api.ProducersFor(mediaTypes) -} -func (r *routableUntypedAPI) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { - return r.api.AuthenticatorsFor(schemes) -} -func (r *routableUntypedAPI) Authorizer() runtime.Authorizer { - return r.api.Authorizer() -} -func (r *routableUntypedAPI) Formats() strfmt.Registry { - return r.api.Formats() -} - -func (r *routableUntypedAPI) DefaultProduces() string { - return r.defaultProduces -} - -func (r *routableUntypedAPI) DefaultConsumes() string { - return r.defaultConsumes -} - -// NewRoutableContext creates a new context for a routable API. -// -// If a nil Router is provided, the DefaultRouter (denco-based) will be used. -func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Router) *Context { - var an *analysis.Spec - if spec != nil { - an = analysis.New(spec.Spec()) - } - - return NewRoutableContextWithAnalyzedSpec(spec, an, routableAPI, routes) -} - -// NewRoutableContextWithAnalyzedSpec is like NewRoutableContext but takes as input an already analysed spec. -// -// 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")) - } - - return &Context{ - spec: spec, - api: routableAPI, - analyzer: an, - router: routes, - debugLogf: debugLogfFunc(nil), - } -} - -// NewContext creates a new context wrapper. -// -// If a nil Router is provided, the DefaultRouter (denco-based) will be used. -func NewContext(spec *loads.Document, api *untyped.API, routes Router) *Context { - var an *analysis.Spec - if spec != nil { - an = analysis.New(spec.Spec()) - } - ctx := &Context{ - spec: spec, - analyzer: an, - router: routes, - debugLogf: debugLogfFunc(nil), - } - ctx.api = newRoutableUntypedAPI(spec, api, ctx) - - return ctx -} - -// Serve serves the specified spec with the specified api registrations as a http.Handler -func Serve(spec *loads.Document, api *untyped.API) http.Handler { - return ServeWithBuilder(spec, api, PassthroughBuilder) -} - -// ServeWithBuilder serves the specified spec with the specified api registrations as a http.Handler that is decorated -// by the Builder -func ServeWithBuilder(spec *loads.Document, api *untyped.API, builder Builder) http.Handler { - context := NewContext(spec, api, nil) - return context.APIHandler(builder) -} - -type contextKey int8 - -const ( - _ contextKey = iota - ctxContentType - ctxResponseFormat - ctxMatchedRoute - ctxBoundParams - ctxSecurityPrincipal - ctxSecurityScopes -) - -// MatchedRouteFrom request context value. -func MatchedRouteFrom(req *http.Request) *MatchedRoute { - mr := req.Context().Value(ctxMatchedRoute) - if mr == nil { - return nil - } - if res, ok := mr.(*MatchedRoute); ok { - return res - } - return nil -} - -// SecurityPrincipalFrom request context value. -func SecurityPrincipalFrom(req *http.Request) interface{} { - return req.Context().Value(ctxSecurityPrincipal) -} - -// SecurityScopesFrom request context value. -func SecurityScopesFrom(req *http.Request) []string { - rs := req.Context().Value(ctxSecurityScopes) - if res, ok := rs.([]string); ok { - return res - } - return nil -} - -type contentTypeValue struct { - MediaType string - Charset string -} - -// BasePath returns the base path for this API -func (c *Context) BasePath() string { - return c.spec.BasePath() -} - -// SetLogger allows for injecting a logger to catch debug entries. -// -// The logger is enabled in DEBUG mode only. -func (c *Context) SetLogger(lg logger.Logger) { - c.debugLogf = debugLogfFunc(lg) -} - -// RequiredProduces returns the accepted content types for responses -func (c *Context) RequiredProduces() []string { - return c.analyzer.RequiredProduces() -} - -// BindValidRequest binds a params object to a request but only when the request is valid -// if the request is not valid an error will be returned -func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, binder RequestBinder) error { - var res []error - var requestContentType string - - // check and validate content type, select consumer - if runtime.HasBody(request) { - ct, _, err := runtime.ContentType(request.Header) - if err != nil { - res = append(res, err) - } else { - c.debugLogf("validating content type for %q against [%s]", ct, strings.Join(route.Consumes, ", ")) - if err := validateContentType(route.Consumes, ct); err != nil { - res = append(res, err) - } - if len(res) == 0 { - cons, ok := route.Consumers[ct] - if !ok { - res = append(res, errors.New(500, "no consumer registered for %s", ct)) - } else { - route.Consumer = cons - requestContentType = ct - } - } - } - } - - // check and validate the response format - if len(res) == 0 { - // if the route does not provide Produces and a default contentType could not be identified - // based on a body, typical for GET and DELETE requests, then default contentType to. - if len(route.Produces) == 0 && requestContentType == "" { - requestContentType = "*/*" - } - - if str := NegotiateContentType(request, route.Produces, requestContentType); str == "" { - res = append(res, errors.InvalidResponseFormat(request.Header.Get(runtime.HeaderAccept), route.Produces)) - } - } - - // now bind the request with the provided binder - // it's assumed the binder will also validate the request and return an error if the - // request is invalid - if binder != nil && len(res) == 0 { - if err := binder.BindRequest(request, route); err != nil { - return err - } - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -// ContentType gets the parsed value of a content type -// Returns the media type, its charset and a shallow copy of the request -// when its context doesn't contain the content type value, otherwise it returns -// the same request -// Returns the error that runtime.ContentType may retunrs. -func (c *Context) ContentType(request *http.Request) (string, string, *http.Request, error) { - var rCtx = request.Context() - - if v, ok := rCtx.Value(ctxContentType).(*contentTypeValue); ok { - return v.MediaType, v.Charset, request, nil - } - - mt, cs, err := runtime.ContentType(request.Header) - if err != nil { - return "", "", nil, err - } - rCtx = stdContext.WithValue(rCtx, ctxContentType, &contentTypeValue{mt, cs}) - return mt, cs, request.WithContext(rCtx), nil -} - -// LookupRoute looks a route up and returns true when it is found -func (c *Context) LookupRoute(request *http.Request) (*MatchedRoute, bool) { - if route, ok := c.router.Lookup(request.Method, request.URL.EscapedPath()); ok { - return route, ok - } - return nil, false -} - -// RouteInfo tries to match a route for this request -// Returns the matched route, a shallow copy of the request if its context -// contains the matched router, otherwise the same request, and a bool to -// indicate if it the request matches one of the routes, if it doesn't -// then it returns false and nil for the other two return values -func (c *Context) RouteInfo(request *http.Request) (*MatchedRoute, *http.Request, bool) { - var rCtx = request.Context() - - if v, ok := rCtx.Value(ctxMatchedRoute).(*MatchedRoute); ok { - return v, request, ok - } - - if route, ok := c.LookupRoute(request); ok { - rCtx = stdContext.WithValue(rCtx, ctxMatchedRoute, route) - return route, request.WithContext(rCtx), ok - } - - return nil, nil, false -} - -// ResponseFormat negotiates the response content type -// Returns the response format and a shallow copy of the request if its context -// doesn't contain the response format, otherwise the same request -func (c *Context) ResponseFormat(r *http.Request, offers []string) (string, *http.Request) { - var rCtx = r.Context() - - if v, ok := rCtx.Value(ctxResponseFormat).(string); ok { - c.debugLogf("[%s %s] found response format %q in context", r.Method, r.URL.Path, v) - return v, r - } - - format := NegotiateContentType(r, offers, "") - if format != "" { - c.debugLogf("[%s %s] set response format %q in context", r.Method, r.URL.Path, format) - r = r.WithContext(stdContext.WithValue(rCtx, ctxResponseFormat, format)) - } - c.debugLogf("[%s %s] negotiated response format %q", r.Method, r.URL.Path, format) - return format, r -} - -// AllowedMethods gets the allowed methods for the path of this request -func (c *Context) AllowedMethods(request *http.Request) []string { - return c.router.OtherMethods(request.Method, request.URL.EscapedPath()) -} - -// ResetAuth removes the current principal from the request context -func (c *Context) ResetAuth(request *http.Request) *http.Request { - rctx := request.Context() - rctx = stdContext.WithValue(rctx, ctxSecurityPrincipal, nil) - rctx = stdContext.WithValue(rctx, ctxSecurityScopes, nil) - return request.WithContext(rctx) -} - -// Authorize authorizes the request -// Returns the principal object and a shallow copy of the request when its -// context doesn't contain the principal, otherwise the same request or an error -// (the last) if one of the authenticators returns one or an Unauthenticated error -func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interface{}, *http.Request, error) { - if route == nil || !route.HasAuth() { - return nil, nil, nil - } - - var rCtx = request.Context() - if v := rCtx.Value(ctxSecurityPrincipal); v != nil { - return v, request, nil - } - - applies, usr, err := route.Authenticators.Authenticate(request, route) - if !applies || err != nil || !route.Authenticators.AllowsAnonymous() && usr == nil { - if err != nil { - return nil, nil, err - } - return nil, nil, errors.Unauthenticated("invalid credentials") - } - if route.Authorizer != nil { - if err := route.Authorizer.Authorize(request, usr); err != nil { - if _, ok := err.(errors.Error); ok { - return nil, nil, err - } - - return nil, nil, errors.New(http.StatusForbidden, err.Error()) - } - } - - rCtx = request.Context() - - rCtx = stdContext.WithValue(rCtx, ctxSecurityPrincipal, usr) - rCtx = stdContext.WithValue(rCtx, ctxSecurityScopes, route.Authenticator.AllScopes()) - return usr, request.WithContext(rCtx), nil -} - -// BindAndValidate binds and validates the request -// Returns the validation map and a shallow copy of the request when its context -// doesn't contain the validation, otherwise it returns the same request or an -// CompositeValidationError error -func (c *Context) BindAndValidate(request *http.Request, matched *MatchedRoute) (interface{}, *http.Request, error) { - var rCtx = request.Context() - - if v, ok := rCtx.Value(ctxBoundParams).(*validation); ok { - c.debugLogf("got cached validation (valid: %t)", len(v.result) == 0) - if len(v.result) > 0 { - return v.bound, request, errors.CompositeValidationError(v.result...) - } - return v.bound, request, nil - } - result := validateRequest(c, request, matched) - rCtx = stdContext.WithValue(rCtx, ctxBoundParams, result) - request = request.WithContext(rCtx) - if len(result.result) > 0 { - return result.bound, request, errors.CompositeValidationError(result.result...) - } - c.debugLogf("no validation errors found") - return result.bound, request, nil -} - -// NotFound the default not found responder for when no route has been matched yet -func (c *Context) NotFound(rw http.ResponseWriter, r *http.Request) { - c.Respond(rw, r, []string{c.api.DefaultProduces()}, nil, errors.NotFound("not found")) -} - -// Respond renders the response after doing some content negotiation -func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []string, route *MatchedRoute, data interface{}) { - c.debugLogf("responding to %s %s with produces: %v", r.Method, r.URL.Path, produces) - offers := []string{} - for _, mt := range produces { - if mt != c.api.DefaultProduces() { - offers = append(offers, mt) - } - } - // the default producer is last so more specific producers take precedence - offers = append(offers, c.api.DefaultProduces()) - c.debugLogf("offers: %v", offers) - - var format string - format, r = c.ResponseFormat(r, offers) - rw.Header().Set(runtime.HeaderContentType, format) - - if resp, ok := data.(Responder); ok { - producers := route.Producers - // producers contains keys with normalized format, if a format has MIME type parameter such as `text/plain; charset=utf-8` - // then you must provide `text/plain` to get the correct producer. HOWEVER, format here is not normalized. - prod, ok := producers[normalizeOffer(format)] - if !ok { - prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()})) - pr, ok := prods[c.api.DefaultProduces()] - if !ok { - panic(errors.New(http.StatusInternalServerError, cantFindProducer(format))) - } - prod = pr - } - resp.WriteResponse(rw, prod) - return - } - - if err, ok := data.(error); ok { - if format == "" { - rw.Header().Set(runtime.HeaderContentType, runtime.JSONMime) - } - - if realm := security.FailedBasicAuth(r); realm != "" { - rw.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", realm)) - } - - if route == nil || route.Operation == nil { - c.api.ServeErrorFor("")(rw, r, err) - return - } - c.api.ServeErrorFor(route.Operation.ID)(rw, r, err) - return - } - - if route == nil || route.Operation == nil { - rw.WriteHeader(http.StatusOK) - if r.Method == http.MethodHead { - return - } - producers := c.api.ProducersFor(normalizeOffers(offers)) - prod, ok := producers[format] - if !ok { - panic(errors.New(http.StatusInternalServerError, cantFindProducer(format))) - } - if err := prod.Produce(rw, data); err != nil { - panic(err) // let the recovery middleware deal with this - } - return - } - - if _, code, ok := route.Operation.SuccessResponse(); ok { - rw.WriteHeader(code) - if code == http.StatusNoContent || r.Method == http.MethodHead { - return - } - - producers := route.Producers - prod, ok := producers[format] - if !ok { - if !ok { - prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()})) - pr, ok := prods[c.api.DefaultProduces()] - if !ok { - panic(errors.New(http.StatusInternalServerError, cantFindProducer(format))) - } - prod = pr - } - } - if err := prod.Produce(rw, data); err != nil { - panic(err) // let the recovery middleware deal with this - } - return - } - - c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response")) -} - -// APIHandlerSwaggerUI returns a handler to serve the API. -// -// This handler includes a swagger spec, router and the contract defined in the swagger spec. -// -// A spec UI (SwaggerUI) is served at {API base path}/docs and the spec document at /swagger.json -// (these can be modified with uiOptions). -func (c *Context) APIHandlerSwaggerUI(builder Builder, opts ...UIOption) http.Handler { - b := builder - if b == nil { - b = PassthroughBuilder - } - - specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts) - var swaggerUIOpts SwaggerUIOpts - fromCommonToAnyOptions(uiOpts, &swaggerUIOpts) - - return Spec(specPath, c.spec.Raw(), SwaggerUI(swaggerUIOpts, c.RoutesHandler(b)), specOpts...) -} - -// APIHandlerRapiDoc returns a handler to serve the API. -// -// This handler includes a swagger spec, router and the contract defined in the swagger spec. -// -// A spec UI (RapiDoc) is served at {API base path}/docs and the spec document at /swagger.json -// (these can be modified with uiOptions). -func (c *Context) APIHandlerRapiDoc(builder Builder, opts ...UIOption) http.Handler { - b := builder - if b == nil { - b = PassthroughBuilder - } - - specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts) - var rapidocUIOpts RapiDocOpts - fromCommonToAnyOptions(uiOpts, &rapidocUIOpts) - - return Spec(specPath, c.spec.Raw(), RapiDoc(rapidocUIOpts, c.RoutesHandler(b)), specOpts...) -} - -// APIHandler returns a handler to serve the API. -// -// This handler includes a swagger spec, router and the contract defined in the swagger spec. -// -// A spec UI (Redoc) is served at {API base path}/docs and the spec document at /swagger.json -// (these can be modified with uiOptions). -func (c *Context) APIHandler(builder Builder, opts ...UIOption) http.Handler { - b := builder - if b == nil { - b = PassthroughBuilder - } - - specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts) - var redocOpts RedocOpts - fromCommonToAnyOptions(uiOpts, &redocOpts) - - return Spec(specPath, c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)), specOpts...) -} - -func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []SpecOption) { - var title string - sp := c.spec.Spec() - if sp != nil && sp.Info != nil && sp.Info.Title != "" { - title = sp.Info.Title - } - - // default options (may be overridden) - optsForContext := []UIOption{ - WithUIBasePath(c.BasePath()), - WithUITitle(title), - } - optsForContext = append(optsForContext, opts...) - uiOpts := uiOptionsWithDefaults(optsForContext) - - // If spec URL is provided, there is a non-default path to serve the spec. - // This makes sure that the UI middleware is aligned with the Spec middleware. - u, _ := url.Parse(uiOpts.SpecURL) - var specPath string - if u != nil { - specPath = u.Path - } - - pth, doc := path.Split(specPath) - if pth == "." { - pth = "" - } - - 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 -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE b/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE deleted file mode 100644 index e65039ad8..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2014 Naoya Inada <naoina@kuune.org> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/README.md b/vendor/github.com/go-openapi/runtime/middleware/denco/README.md deleted file mode 100644 index 30109e17d..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/README.md +++ /dev/null @@ -1,180 +0,0 @@ -# Denco [](https://travis-ci.org/naoina/denco) - -The fast and flexible HTTP request router for [Go](http://golang.org). - -Denco is based on Double-Array implementation of [Kocha-urlrouter](https://github.com/naoina/kocha-urlrouter). -However, Denco is optimized and some features added. - -## Features - -* Fast (See [go-http-routing-benchmark](https://github.com/naoina/go-http-routing-benchmark)) -* [URL patterns](#url-patterns) (`/foo/:bar` and `/foo/*wildcard`) -* Small (but enough) URL router API -* HTTP request multiplexer like `http.ServeMux` - -## Installation - - go get -u github.com/go-openapi/runtime/middleware/denco - -## Using as HTTP request multiplexer - -```go -package main - -import ( - "fmt" - "log" - "net/http" - - "github.com/go-openapi/runtime/middleware/denco" -) - -func Index(w http.ResponseWriter, r *http.Request, params denco.Params) { - fmt.Fprintf(w, "Welcome to Denco!\n") -} - -func User(w http.ResponseWriter, r *http.Request, params denco.Params) { - fmt.Fprintf(w, "Hello %s!\n", params.Get("name")) -} - -func main() { - mux := denco.NewMux() - handler, err := mux.Build([]denco.Handler{ - mux.GET("/", Index), - mux.GET("/user/:name", User), - mux.POST("/user/:name", User), - }) - if err != nil { - panic(err) - } - log.Fatal(http.ListenAndServe(":8080", handler)) -} -``` - -## Using as URL router - -```go -package main - -import ( - "fmt" - - "github.com/go-openapi/runtime/middleware/denco" -) - -type route struct { - name string -} - -func main() { - router := denco.New() - router.Build([]denco.Record{ - {"/", &route{"root"}}, - {"/user/:id", &route{"user"}}, - {"/user/:name/:id", &route{"username"}}, - {"/static/*filepath", &route{"static"}}, - }) - - data, params, found := router.Lookup("/") - // print `&main.route{name:"root"}, denco.Params(nil), true`. - fmt.Printf("%#v, %#v, %#v\n", data, params, found) - - data, params, found = router.Lookup("/user/hoge") - // print `&main.route{name:"user"}, denco.Params{denco.Param{Name:"id", Value:"hoge"}}, true`. - fmt.Printf("%#v, %#v, %#v\n", data, params, found) - - data, params, found = router.Lookup("/user/hoge/7") - // print `&main.route{name:"username"}, denco.Params{denco.Param{Name:"name", Value:"hoge"}, denco.Param{Name:"id", Value:"7"}}, true`. - fmt.Printf("%#v, %#v, %#v\n", data, params, found) - - data, params, found = router.Lookup("/static/path/to/file") - // print `&main.route{name:"static"}, denco.Params{denco.Param{Name:"filepath", Value:"path/to/file"}}, true`. - fmt.Printf("%#v, %#v, %#v\n", data, params, found) -} -``` - -See [Godoc](http://godoc.org/github.com/go-openapi/runtime/middleware/denco) for more details. - -## Getting the value of path parameter - -You can get the value of path parameter by 2 ways. - -1. Using [`denco.Params.Get`](http://godoc.org/github.com/go-openapi/runtime/middleware/denco#Params.Get) method -2. Find by loop - -```go -package main - -import ( - "fmt" - - "github.com/go-openapi/runtime/middleware/denco" -) - -func main() { - router := denco.New() - if err := router.Build([]denco.Record{ - {"/user/:name/:id", "route1"}, - }); err != nil { - panic(err) - } - - // 1. Using denco.Params.Get method. - _, params, _ := router.Lookup("/user/alice/1") - name := params.Get("name") - if name != "" { - fmt.Printf("Hello %s.\n", name) // prints "Hello alice.". - } - - // 2. Find by loop. - for _, param := range params { - if param.Name == "name" { - fmt.Printf("Hello %s.\n", name) // prints "Hello alice.". - } - } -} -``` - -## URL patterns - -Denco's route matching strategy is "most nearly matching". - -When routes `/:name` and `/alice` have been built, URI `/alice` matches the route `/alice`, not `/:name`. -Because URI `/alice` is more match with the route `/alice` than `/:name`. - -For more example, when routes below have been built: - -``` -/user/alice -/user/:name -/user/:name/:id -/user/alice/:id -/user/:id/bob -``` - -Routes matching are: - -``` -/user/alice => "/user/alice" (no match with "/user/:name") -/user/bob => "/user/:name" -/user/naoina/1 => "/user/:name/1" -/user/alice/1 => "/user/alice/:id" (no match with "/user/:name/:id") -/user/1/bob => "/user/:id/bob" (no match with "/user/:name/:id") -/user/alice/bob => "/user/alice/:id" (no match with "/user/:name/:id" and "/user/:id/bob") -``` - -## Limitation - -Denco has some limitations below. - -* Number of param records (such as `/:name`) must be less than 2^22 -* Number of elements of internal slice must be less than 2^22 - -## Benchmarks - - cd $GOPATH/github.com/go-openapi/runtime/middleware/denco - go test -bench . -benchmem - -## License - -Denco is licensed under the MIT License. diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go deleted file mode 100644 index 4377f77a4..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go +++ /dev/null @@ -1,467 +0,0 @@ -// Package denco provides fast URL router. -package denco - -import ( - "errors" - "fmt" - "sort" - "strings" -) - -const ( - // ParamCharacter is a special character for path parameter. - ParamCharacter = ':' - - // WildcardCharacter is a special character for wildcard path parameter. - WildcardCharacter = '*' - - // TerminationCharacter is a special character for end of path. - TerminationCharacter = '#' - - // SeparatorCharacter separates path segments. - SeparatorCharacter = '/' - - // PathParamCharacter indicates a RESTCONF path param - PathParamCharacter = '=' - - // MaxSize is max size of records and internal slice. - MaxSize = (1 << 22) - 1 -) - -// Router represents a URL router. -type Router struct { - param *doubleArray - // SizeHint expects the maximum number of path parameters in records to Build. - // SizeHint will be used to determine the capacity of the memory to allocate. - // By default, SizeHint will be determined from given records to Build. - SizeHint int - - static map[string]interface{} -} - -// New returns a new Router. -func New() *Router { - return &Router{ - SizeHint: -1, - static: make(map[string]interface{}), - param: newDoubleArray(), - } -} - -// Lookup returns data and path parameters that associated with path. -// params is a slice of the Param that arranged in the order in which parameters appeared. -// e.g. when built routing path is "/path/to/:id/:name" and given path is "/path/to/1/alice". params order is [{"id": "1"}, {"name": "alice"}], not [{"name": "alice"}, {"id": "1"}]. -func (rt *Router) Lookup(path string) (data interface{}, params Params, found bool) { - if data, found = rt.static[path]; found { - return data, nil, true - } - if len(rt.param.node) == 1 { - return nil, nil, false - } - nd, params, found := rt.param.lookup(path, make([]Param, 0, rt.SizeHint), 1) - if !found { - return nil, nil, false - } - for i := 0; i < len(params); i++ { - params[i].Name = nd.paramNames[i] - } - return nd.data, params, true -} - -// Build builds URL router from records. -func (rt *Router) Build(records []Record) error { - statics, params := makeRecords(records) - if len(params) > MaxSize { - return errors.New("denco: too many records") - } - if rt.SizeHint < 0 { - rt.SizeHint = 0 - for _, p := range params { - size := 0 - for _, k := range p.Key { - if k == ParamCharacter || k == WildcardCharacter { - size++ - } - } - if size > rt.SizeHint { - rt.SizeHint = size - } - } - } - for _, r := range statics { - rt.static[r.Key] = r.Value - } - if err := rt.param.build(params, 1, 0, make(map[int]struct{})); err != nil { - return err - } - return nil -} - -// Param represents name and value of path parameter. -type Param struct { - Name string - Value string -} - -// Params represents the name and value of path parameters. -type Params []Param - -// Get gets the first value associated with the given name. -// If there are no values associated with the key, Get returns "". -func (ps Params) Get(name string) string { - for _, p := range ps { - if p.Name == name { - return p.Value - } - } - return "" -} - -type doubleArray struct { - bc []baseCheck - node []*node -} - -func newDoubleArray() *doubleArray { - return &doubleArray{ - bc: []baseCheck{0}, - node: []*node{nil}, // A start index is adjusting to 1 because 0 will be used as a mark of non-existent node. - } -} - -// baseCheck contains BASE, CHECK and Extra flags. -// From the top, 22bits of BASE, 2bits of Extra flags and 8bits of CHECK. -// -// BASE (22bit) | Extra flags (2bit) | CHECK (8bit) -// -// |----------------------|--|--------| -// 32 10 8 0 -type baseCheck uint32 - -func (bc baseCheck) Base() int { - return int(bc >> 10) -} - -func (bc *baseCheck) SetBase(base int) { - *bc |= baseCheck(base) << 10 -} - -func (bc baseCheck) Check() byte { - return byte(bc) -} - -func (bc *baseCheck) SetCheck(check byte) { - *bc |= baseCheck(check) -} - -func (bc baseCheck) IsEmpty() bool { - return bc&0xfffffcff == 0 -} - -func (bc baseCheck) IsSingleParam() bool { - return bc¶mTypeSingle == paramTypeSingle -} - -func (bc baseCheck) IsWildcardParam() bool { - return bc¶mTypeWildcard == paramTypeWildcard -} - -func (bc baseCheck) IsAnyParam() bool { - return bc¶mTypeAny != 0 -} - -func (bc *baseCheck) SetSingleParam() { - *bc |= (1 << 8) -} - -func (bc *baseCheck) SetWildcardParam() { - *bc |= (1 << 9) -} - -const ( - paramTypeSingle = 0x0100 - paramTypeWildcard = 0x0200 - paramTypeAny = 0x0300 -) - -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++ { - if da.bc[idx].IsAnyParam() { - indices = append(indices, (uint64(i)<<32)|(uint64(idx)&0xffffffff)) - } - c := path[i] - if idx = nextIndex(da.bc[idx].Base(), c); idx >= len(da.bc) || da.bc[idx].Check() != c { - goto BACKTRACKING - } - } - if next := nextIndex(da.bc[idx].Base(), TerminationCharacter); next < len(da.bc) && da.bc[next].Check() == TerminationCharacter { - return da.node[da.bc[next].Base()], params, true - } - -BACKTRACKING: - for j := len(indices) - 1; j >= 0; j-- { - i, idx := int(indices[j]>>32), int(indices[j]&0xffffffff) - if da.bc[idx].IsSingleParam() { - nextIdx := nextIndex(da.bc[idx].Base(), ParamCharacter) - if nextIdx >= len(da.bc) { - break - } - - next := NextSeparator(path, i) - nextParams := params - nextParams = append(nextParams, Param{Value: path[i:next]}) - if nd, nextNextParams, found := da.lookup(path[next:], nextParams, nextIdx); found { - return nd, nextNextParams, true - } - } - - if da.bc[idx].IsWildcardParam() { - nextIdx := nextIndex(da.bc[idx].Base(), WildcardCharacter) - nextParams := params - nextParams = append(nextParams, Param{Value: path[i:]}) - return da.node[da.bc[nextIdx].Base()], nextParams, true - } - } - return nil, nil, false -} - -// build builds double-array from records. -func (da *doubleArray) build(srcs []*record, idx, depth int, usedBase map[int]struct{}) error { - sort.Stable(recordSlice(srcs)) - base, siblings, leaf, err := da.arrange(srcs, idx, depth, usedBase) - if err != nil { - return err - } - if leaf != nil { - nd, err := makeNode(leaf) - if err != nil { - return err - } - da.bc[idx].SetBase(len(da.node)) - da.node = append(da.node, nd) - } - for _, sib := range siblings { - da.setCheck(nextIndex(base, sib.c), sib.c) - } - for _, sib := range siblings { - records := srcs[sib.start:sib.end] - switch sib.c { - case ParamCharacter: - for _, r := range records { - next := NextSeparator(r.Key, depth+1) - name := r.Key[depth+1 : next] - r.paramNames = append(r.paramNames, name) - r.Key = r.Key[next:] - } - da.bc[idx].SetSingleParam() - if err := da.build(records, nextIndex(base, sib.c), 0, usedBase); err != nil { - return err - } - case WildcardCharacter: - r := records[0] - name := r.Key[depth+1 : len(r.Key)-1] - r.paramNames = append(r.paramNames, name) - r.Key = "" - da.bc[idx].SetWildcardParam() - if err := da.build(records, nextIndex(base, sib.c), 0, usedBase); err != nil { - return err - } - default: - if err := da.build(records, nextIndex(base, sib.c), depth+1, usedBase); err != nil { - return err - } - } - } - return nil -} - -// setBase sets BASE. -func (da *doubleArray) setBase(i, base int) { - da.bc[i].SetBase(base) -} - -// setCheck sets CHECK. -func (da *doubleArray) setCheck(i int, check byte) { - da.bc[i].SetCheck(check) -} - -// findEmptyIndex returns an index of unused BASE/CHECK node. -func (da *doubleArray) findEmptyIndex(start int) int { - i := start - for ; i < len(da.bc); i++ { - if da.bc[i].IsEmpty() { - break - } - } - return i -} - -// findBase returns good BASE. -func (da *doubleArray) findBase(siblings []sibling, start int, usedBase map[int]struct{}) (base int) { - for idx, firstChar := start+1, siblings[0].c; ; idx = da.findEmptyIndex(idx + 1) { - base = nextIndex(idx, firstChar) - if _, used := usedBase[base]; used { - continue - } - i := 0 - for ; i < len(siblings); i++ { - next := nextIndex(base, siblings[i].c) - if len(da.bc) <= next { - da.bc = append(da.bc, make([]baseCheck, next-len(da.bc)+1)...) - } - if !da.bc[next].IsEmpty() { - break - } - } - if i == len(siblings) { - break - } - } - usedBase[base] = struct{}{} - return base -} - -func (da *doubleArray) arrange(records []*record, idx, depth int, usedBase map[int]struct{}) (base int, siblings []sibling, leaf *record, err error) { - siblings, leaf, err = makeSiblings(records, depth) - if err != nil { - return -1, nil, nil, err - } - if len(siblings) < 1 { - return -1, nil, leaf, nil - } - base = da.findBase(siblings, idx, usedBase) - if base > MaxSize { - return -1, nil, nil, errors.New("denco: too many elements of internal slice") - } - da.setBase(idx, base) - return base, siblings, leaf, err -} - -// node represents a node of Double-Array. -type node struct { - data interface{} - - // Names of path parameters. - paramNames []string -} - -// makeNode returns a new node from record. -func makeNode(r *record) (*node, error) { - dups := make(map[string]bool) - for _, name := range r.paramNames { - if dups[name] { - return nil, fmt.Errorf("denco: path parameter `%v' is duplicated in the key `%v'", name, r.Key) - } - dups[name] = true - } - return &node{data: r.Value, paramNames: r.paramNames}, nil -} - -// sibling represents an intermediate data of build for Double-Array. -type sibling struct { - // An index of start of duplicated characters. - start int - - // An index of end of duplicated characters. - end int - - // A character of sibling. - c byte -} - -// nextIndex returns a next index of array of BASE/CHECK. -func nextIndex(base int, c byte) int { - return base ^ int(c) -} - -// makeSiblings returns slice of sibling. -func makeSiblings(records []*record, depth int) (sib []sibling, leaf *record, err error) { - var ( - pc byte - n int - ) - for i, r := range records { - if len(r.Key) <= depth { - leaf = r - continue - } - c := r.Key[depth] - switch { - case pc < c: - sib = append(sib, sibling{start: i, c: c}) - case pc == c: - continue - default: - return nil, nil, errors.New("denco: BUG: routing table hasn't been sorted") - } - if n > 0 { - sib[n-1].end = i - } - pc = c - n++ - } - if n == 0 { - return nil, leaf, nil - } - sib[n-1].end = len(records) - return sib, leaf, nil -} - -// Record represents a record data for router construction. -type Record struct { - // Key for router construction. - Key string - - // Result value for Key. - Value interface{} -} - -// NewRecord returns a new Record. -func NewRecord(key string, value interface{}) Record { - return Record{ - Key: key, - Value: value, - } -} - -// record represents a record that use to build the Double-Array. -type record struct { - Record - paramNames []string -} - -// makeRecords returns the records that use to build Double-Arrays. -func makeRecords(srcs []Record) (statics, params []*record) { - termChar := string(TerminationCharacter) - paramPrefix := string(SeparatorCharacter) + string(ParamCharacter) - wildcardPrefix := string(SeparatorCharacter) + string(WildcardCharacter) - restconfPrefix := string(PathParamCharacter) + string(ParamCharacter) - for _, r := range srcs { - if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) || strings.Contains(r.Key, restconfPrefix) { - r.Key += termChar - params = append(params, &record{Record: r}) - } else { - statics = append(statics, &record{Record: r}) - } - } - return statics, params -} - -// recordSlice represents a slice of Record for sort and implements the sort.Interface. -type recordSlice []*record - -// Len implements the sort.Interface.Len. -func (rs recordSlice) Len() int { - return len(rs) -} - -// Less implements the sort.Interface.Less. -func (rs recordSlice) Less(i, j int) bool { - return rs[i].Key < rs[j].Key -} - -// Swap implements the sort.Interface.Swap. -func (rs recordSlice) Swap(i, j int) { - rs[i], rs[j] = rs[j], rs[i] -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/server.go b/vendor/github.com/go-openapi/runtime/middleware/denco/server.go deleted file mode 100644 index 0886713c1..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/server.go +++ /dev/null @@ -1,106 +0,0 @@ -package denco - -import ( - "net/http" -) - -// Mux represents a multiplexer for HTTP request. -type Mux struct{} - -// NewMux returns a new Mux. -func NewMux() *Mux { - return &Mux{} -} - -// GET is shorthand of Mux.Handler("GET", path, handler). -func (m *Mux) GET(path string, handler HandlerFunc) Handler { - return m.Handler("GET", path, handler) -} - -// POST is shorthand of Mux.Handler("POST", path, handler). -func (m *Mux) POST(path string, handler HandlerFunc) Handler { - return m.Handler("POST", path, handler) -} - -// PUT is shorthand of Mux.Handler("PUT", path, handler). -func (m *Mux) PUT(path string, handler HandlerFunc) Handler { - return m.Handler("PUT", path, handler) -} - -// HEAD is shorthand of Mux.Handler("HEAD", path, handler). -func (m *Mux) HEAD(path string, handler HandlerFunc) Handler { - return m.Handler("HEAD", path, handler) -} - -// Handler returns a handler for HTTP method. -func (m *Mux) Handler(method, path string, handler HandlerFunc) Handler { - return Handler{ - Method: method, - Path: path, - Func: handler, - } -} - -// Build builds a http.Handler. -func (m *Mux) Build(handlers []Handler) (http.Handler, error) { - recordMap := make(map[string][]Record) - for _, h := range handlers { - recordMap[h.Method] = append(recordMap[h.Method], NewRecord(h.Path, h.Func)) - } - mux := newServeMux() - for m, records := range recordMap { - router := New() - if err := router.Build(records); err != nil { - return nil, err - } - mux.routers[m] = router - } - return mux, nil -} - -// Handler represents a handler of HTTP request. -type Handler struct { - // Method is an HTTP method. - Method string - - // Path is a routing path for handler. - Path string - - // Func is a function of handler of HTTP request. - Func HandlerFunc -} - -// The HandlerFunc type is aliased to type of handler function. -type HandlerFunc func(w http.ResponseWriter, r *http.Request, params Params) - -type serveMux struct { - routers map[string]*Router -} - -func newServeMux() *serveMux { - return &serveMux{ - routers: make(map[string]*Router), - } -} - -// ServeHTTP implements http.Handler interface. -func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { - handler, params := mux.handler(r.Method, r.URL.Path) - handler(w, r, params) -} - -func (mux *serveMux) handler(method, path string) (HandlerFunc, []Param) { - if router, found := mux.routers[method]; found { - if handler, params, found := router.Lookup(path); found { - return handler.(HandlerFunc), params - } - } - return NotFound, nil -} - -// NotFound replies to the request with an HTTP 404 not found error. -// NotFound is called when unknown HTTP method or a handler not found. -// If you want to use the your own NotFound handler, please overwrite this variable. -var NotFound = func(w http.ResponseWriter, r *http.Request, _ Params) { - http.NotFound(w, r) -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/util.go b/vendor/github.com/go-openapi/runtime/middleware/denco/util.go deleted file mode 100644 index edc1f6ab8..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/util.go +++ /dev/null @@ -1,12 +0,0 @@ -package denco - -// NextSeparator returns an index of next separator in path. -func NextSeparator(path string, start int) int { - for start < len(path) { - if c := path[start]; c == '/' || c == TerminationCharacter { - break - } - start++ - } - return start -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/doc.go b/vendor/github.com/go-openapi/runtime/middleware/doc.go deleted file mode 100644 index 836a98850..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/doc.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package middleware provides the library with helper functions for serving swagger APIs. - -Pseudo middleware handler - - import ( - "net/http" - - "github.com/go-openapi/errors" - ) - - func newCompleteMiddleware(ctx *Context) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - // use context to lookup routes - if matched, ok := ctx.RouteInfo(r); ok { - - if matched.NeedsAuth() { - if _, err := ctx.Authorize(r, matched); err != nil { - ctx.Respond(rw, r, matched.Produces, matched, err) - return - } - } - - bound, validation := ctx.BindAndValidate(r, matched) - if validation != nil { - ctx.Respond(rw, r, matched.Produces, matched, validation) - return - } - - result, err := matched.Handler.Handle(bound) - if err != nil { - ctx.Respond(rw, r, matched.Produces, matched, err) - return - } - - ctx.Respond(rw, r, matched.Produces, matched, result) - return - } - - // Not found, check if it exists in the other methods first - if others := ctx.AllowedMethods(r); len(others) > 0 { - ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others)) - return - } - ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path)) - }) - } -*/ -package middleware diff --git a/vendor/github.com/go-openapi/runtime/middleware/header/header.go b/vendor/github.com/go-openapi/runtime/middleware/header/header.go deleted file mode 100644 index df073c87d..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/header/header.go +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd. - -// this file was taken from the github.com/golang/gddo repository - -// Package header provides functions for parsing HTTP headers. -package header - -import ( - "net/http" - "strings" - "time" -) - -// Octet types from RFC 2616. -var octetTypes [256]octetType - -type octetType byte - -const ( - isToken octetType = 1 << iota - isSpace -) - -func init() { - // OCTET = <any 8-bit sequence of data> - // CHAR = <any US-ASCII character (octets 0 - 127)> - // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> - // CR = <US-ASCII CR, carriage return (13)> - // LF = <US-ASCII LF, linefeed (10)> - // SP = <US-ASCII SP, space (32)> - // HT = <US-ASCII HT, horizontal-tab (9)> - // <"> = <US-ASCII double-quote mark (34)> - // CRLF = CR LF - // LWS = [CRLF] 1*( SP | HT ) - // TEXT = <any OCTET except CTLs, but including LWS> - // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> - // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT - // token = 1*<any CHAR except CTLs or separators> - // qdtext = <any TEXT except <">> - - for c := 0; c < 256; c++ { - var t octetType - isCtl := c <= 31 || c == 127 - isChar := 0 <= c && c <= 127 - isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) - if strings.ContainsRune(" \t\r\n", rune(c)) { - t |= isSpace - } - if isChar && !isCtl && !isSeparator { - t |= isToken - } - octetTypes[c] = t - } -} - -// Copy returns a shallow copy of the header. -func Copy(header http.Header) http.Header { - h := make(http.Header) - for k, vs := range header { - h[k] = vs - } - return h -} - -var timeLayouts = []string{"Mon, 02 Jan 2006 15:04:05 GMT", time.RFC850, time.ANSIC} - -// ParseTime parses the header as time. The zero value is returned if the -// header is not present or there is an error parsing the -// header. -func ParseTime(header http.Header, key string) time.Time { - if s := header.Get(key); s != "" { - for _, layout := range timeLayouts { - if t, err := time.Parse(layout, s); err == nil { - return t.UTC() - } - } - } - return time.Time{} -} - -// ParseList parses a comma separated list of values. Commas are ignored in -// quoted strings. Quoted values are not unescaped or unquoted. Whitespace is -// trimmed. -func ParseList(header http.Header, key string) []string { - var result []string - for _, s := range header[http.CanonicalHeaderKey(key)] { - begin := 0 - end := 0 - escape := false - quote := false - for i := 0; i < len(s); i++ { - b := s[i] - switch { - case escape: - escape = false - end = i + 1 - case quote: - switch b { - case '\\': - escape = true - case '"': - quote = false - } - end = i + 1 - case b == '"': - quote = true - end = i + 1 - case octetTypes[b]&isSpace != 0: - if begin == end { - begin = i + 1 - end = begin - } - case b == ',': - if begin < end { - result = append(result, s[begin:end]) - } - begin = i + 1 - end = begin - default: - end = i + 1 - } - } - if begin < end { - result = append(result, s[begin:end]) - } - } - return result -} - -// ParseValueAndParams parses a comma separated list of values with optional -// semicolon separated name-value pairs. Content-Type and Content-Disposition -// headers are in this format. -func ParseValueAndParams(header http.Header, key string) (string, map[string]string) { - return parseValueAndParams(header.Get(key)) -} - -func parseValueAndParams(s string) (value string, params map[string]string) { - params = make(map[string]string) - value, s = expectTokenSlash(s) - if value == "" { - return - } - value = strings.ToLower(value) - s = skipSpace(s) - for strings.HasPrefix(s, ";") { - var pkey string - pkey, s = expectToken(skipSpace(s[1:])) - if pkey == "" { - return - } - if !strings.HasPrefix(s, "=") { - return - } - var pvalue string - pvalue, s = expectTokenOrQuoted(s[1:]) - if pvalue == "" { - return - } - pkey = strings.ToLower(pkey) - params[pkey] = pvalue - s = skipSpace(s) - } - return -} - -// AcceptSpec ... -type AcceptSpec struct { - Value string - Q float64 -} - -// ParseAccept2 ... -func ParseAccept2(header http.Header, key string) (specs []AcceptSpec) { - for _, en := range ParseList(header, key) { - v, p := parseValueAndParams(en) - var spec AcceptSpec - spec.Value = v - spec.Q = 1.0 - if p != nil { - if q, ok := p["q"]; ok { - spec.Q, _ = expectQuality(q) - } - } - if spec.Q < 0.0 { - continue - } - specs = append(specs, spec) - } - - return -} - -// ParseAccept parses Accept* headers. -func ParseAccept(header http.Header, key string) []AcceptSpec { - var specs []AcceptSpec -loop: - for _, s := range header[key] { - for { - var spec AcceptSpec - spec.Value, s = expectTokenSlash(s) - if spec.Value == "" { - continue loop - } - spec.Q = 1.0 - s = skipSpace(s) - if strings.HasPrefix(s, ";") { - s = skipSpace(s[1:]) - for !strings.HasPrefix(s, "q=") && s != "" && !strings.HasPrefix(s, ",") { - s = skipSpace(s[1:]) - } - if strings.HasPrefix(s, "q=") { - spec.Q, s = expectQuality(s[2:]) - if spec.Q < 0.0 { - continue loop - } - } - } - - specs = append(specs, spec) - s = skipSpace(s) - if !strings.HasPrefix(s, ",") { - continue loop - } - s = skipSpace(s[1:]) - } - } - - return specs -} - -func skipSpace(s string) (rest string) { - i := 0 - for ; i < len(s); i++ { - if octetTypes[s[i]]&isSpace == 0 { - break - } - } - return s[i:] -} - -func expectToken(s string) (token, rest string) { - i := 0 - for ; i < len(s); i++ { - if octetTypes[s[i]]&isToken == 0 { - break - } - } - return s[:i], s[i:] -} - -func expectTokenSlash(s string) (token, rest string) { - i := 0 - for ; i < len(s); i++ { - b := s[i] - if (octetTypes[b]&isToken == 0) && b != '/' { - break - } - } - return s[:i], s[i:] -} - -func expectQuality(s string) (q float64, rest string) { - switch { - case len(s) == 0: - return -1, "" - case s[0] == '0': - // q is already 0 - s = s[1:] - case s[0] == '1': - s = s[1:] - q = 1 - case s[0] == '.': - // q is already 0 - default: - return -1, "" - } - if !strings.HasPrefix(s, ".") { - return q, s - } - s = s[1:] - i := 0 - n := 0 - d := 1 - for ; i < len(s); i++ { - b := s[i] - if b < '0' || b > '9' { - break - } - n = n*10 + int(b) - '0' - d *= 10 - } - return q + float64(n)/float64(d), s[i:] -} - -func expectTokenOrQuoted(s string) (value string, rest string) { - if !strings.HasPrefix(s, "\"") { - return expectToken(s) - } - s = s[1:] - for i := 0; i < len(s); i++ { - switch s[i] { - case '"': - return s[:i], s[i+1:] - case '\\': - p := make([]byte, len(s)-1) - j := copy(p, s[:i]) - escape := true - for i++; i < len(s); i++ { - b := s[i] - switch { - case escape: - escape = false - p[j] = b - j++ - case b == '\\': - escape = true - case b == '"': - return string(p[:j]), s[i+1:] - default: - p[j] = b - j++ - } - } - return "", "" - } - } - return "", "" -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/negotiate.go b/vendor/github.com/go-openapi/runtime/middleware/negotiate.go deleted file mode 100644 index a9b6f27d3..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/negotiate.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd. - -// this file was taken from the github.com/golang/gddo repository - -package middleware - -import ( - "net/http" - "strings" - - "github.com/go-openapi/runtime/middleware/header" -) - -// NegotiateContentEncoding returns the best offered content encoding for the -// request's Accept-Encoding header. If two offers match with equal weight and -// then the offer earlier in the list is preferred. If no offers are -// acceptable, then "" is returned. -func NegotiateContentEncoding(r *http.Request, offers []string) string { - bestOffer := "identity" - bestQ := -1.0 - specs := header.ParseAccept(r.Header, "Accept-Encoding") - for _, offer := range offers { - for _, spec := range specs { - if spec.Q > bestQ && - (spec.Value == "*" || spec.Value == offer) { - bestQ = spec.Q - bestOffer = offer - } - } - } - if bestQ == 0 { - bestOffer = "" - } - return bestOffer -} - -// NegotiateContentType returns the best offered content type for the request's -// Accept header. If two offers match with equal weight, then the more specific -// offer is preferred. For example, text/* trumps */*. If two offers match -// with equal weight and specificity, then the offer earlier in the list is -// preferred. If no offers match, then defaultOffer is returned. -func NegotiateContentType(r *http.Request, offers []string, defaultOffer string) string { - bestOffer := defaultOffer - bestQ := -1.0 - bestWild := 3 - specs := header.ParseAccept(r.Header, "Accept") - for _, rawOffer := range offers { - offer := normalizeOffer(rawOffer) - // No Accept header: just return the first offer. - if len(specs) == 0 { - return rawOffer - } - for _, spec := range specs { - switch { - case spec.Q == 0.0: - // ignore - case spec.Q < bestQ: - // better match found - case spec.Value == "*/*": - if spec.Q > bestQ || bestWild > 2 { - bestQ = spec.Q - bestWild = 2 - bestOffer = rawOffer - } - case strings.HasSuffix(spec.Value, "/*"): - if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) && - (spec.Q > bestQ || bestWild > 1) { - bestQ = spec.Q - bestWild = 1 - bestOffer = rawOffer - } - default: - if spec.Value == offer && - (spec.Q > bestQ || bestWild > 0) { - bestQ = spec.Q - bestWild = 0 - bestOffer = rawOffer - } - } - } - } - return bestOffer -} - -func normalizeOffers(orig []string) (norm []string) { - for _, o := range orig { - norm = append(norm, normalizeOffer(o)) - } - return -} - -func normalizeOffer(orig string) string { - return strings.SplitN(orig, ";", 2)[0] -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go b/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go deleted file mode 100644 index bc6942a0f..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - "net/http" - - "github.com/go-openapi/runtime" -) - -type errorResp struct { - code int - response interface{} - headers http.Header -} - -func (e *errorResp) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - for k, v := range e.headers { - for _, val := range v { - rw.Header().Add(k, val) - } - } - if e.code > 0 { - rw.WriteHeader(e.code) - } else { - rw.WriteHeader(http.StatusInternalServerError) - } - if err := producer.Produce(rw, e.response); err != nil { - Logger.Printf("failed to write error response: %v", err) - } -} - -// NotImplemented the error response when the response is not implemented -func NotImplemented(message string) Responder { - return Error(http.StatusNotImplemented, message) -} - -// Error creates a generic responder for returning errors, the data will be serialized -// with the matching producer for the request -func Error(code int, data interface{}, headers ...http.Header) Responder { - var hdr http.Header - for _, h := range headers { - for k, v := range h { - if hdr == nil { - hdr = make(http.Header) - } - hdr[k] = v - } - } - return &errorResp{ - code: code, - response: data, - headers: hdr, - } -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/operation.go b/vendor/github.com/go-openapi/runtime/middleware/operation.go deleted file mode 100644 index 1175a63cf..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/operation.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import "net/http" - -// NewOperationExecutor creates a context aware middleware that handles the operations after routing -func NewOperationExecutor(ctx *Context) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - // use context to lookup routes - route, rCtx, _ := ctx.RouteInfo(r) - if rCtx != nil { - r = rCtx - } - - route.Handler.ServeHTTP(rw, r) - }) -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/parameter.go b/vendor/github.com/go-openapi/runtime/middleware/parameter.go deleted file mode 100644 index 9c3353a95..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/parameter.go +++ /dev/null @@ -1,491 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - "encoding" - "encoding/base64" - "fmt" - "io" - "net/http" - "reflect" - "strconv" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" - - "github.com/go-openapi/runtime" -) - -const defaultMaxMemory = 32 << 20 - -const ( - typeString = "string" - typeArray = "array" -) - -var textUnmarshalType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem() - -func newUntypedParamBinder(param spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *untypedParamBinder { - binder := new(untypedParamBinder) - binder.Name = param.Name - binder.parameter = ¶m - binder.formats = formats - if param.In != "body" { - binder.validator = validate.NewParamValidator(¶m, formats) - } else { - binder.validator = validate.NewSchemaValidator(param.Schema, spec, param.Name, formats) - } - - return binder -} - -type untypedParamBinder struct { - parameter *spec.Parameter - formats strfmt.Registry - Name string - validator validate.EntityValidator -} - -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 { - case "query": - data, custom, hasKey, err := p.readValue(runtime.Values(request.URL.Query()), target) - if err != nil { - return err - } - if custom { - return nil - } - - return p.bindValue(data, hasKey, target) - - case "header": - data, custom, hasKey, err := p.readValue(runtime.Values(request.Header), target) - if err != nil { - return err - } - if custom { - return nil - } - return p.bindValue(data, hasKey, target) - - case "path": - data, custom, hasKey, err := p.readValue(routeParams, target) - if err != nil { - return err - } - if custom { - return nil - } - return p.bindValue(data, hasKey, target) - - case "formData": - var err error - var mt string - - mt, _, e := runtime.ContentType(request.Header) - if e != nil { - // because of the interface conversion go thinks the error is not nil - // so we first check for nil and then set the err var if it's not nil - err = e - } - - if err != nil { - return errors.InvalidContentType("", []string{"multipart/form-data", "application/x-www-form-urlencoded"}) - } - - if mt != "multipart/form-data" && mt != "application/x-www-form-urlencoded" { - return errors.InvalidContentType(mt, []string{"multipart/form-data", "application/x-www-form-urlencoded"}) - } - - if mt == "multipart/form-data" { - if err = request.ParseMultipartForm(defaultMaxMemory); err != nil { - return errors.NewParseError(p.Name, p.parameter.In, "", err) - } - } - - if err = request.ParseForm(); err != nil { - return errors.NewParseError(p.Name, p.parameter.In, "", err) - } - - if p.parameter.Type == "file" { - file, header, ffErr := request.FormFile(p.parameter.Name) - if ffErr != nil { - if p.parameter.Required { - return errors.NewParseError(p.Name, p.parameter.In, "", ffErr) - } - - return nil - } - - target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header})) - return nil - } - - if request.MultipartForm != nil { - data, custom, hasKey, rvErr := p.readValue(runtime.Values(request.MultipartForm.Value), target) - if rvErr != nil { - return rvErr - } - if custom { - return nil - } - return p.bindValue(data, hasKey, target) - } - data, custom, hasKey, err := p.readValue(runtime.Values(request.PostForm), target) - if err != nil { - return err - } - if custom { - return nil - } - return p.bindValue(data, hasKey, target) - - case "body": - newValue := reflect.New(target.Type()) - if !runtime.HasBody(request) { - if p.parameter.Default != nil { - target.Set(reflect.ValueOf(p.parameter.Default)) - } - - return nil - } - if err := consumer.Consume(request.Body, newValue.Interface()); err != nil { - if err == io.EOF && p.parameter.Default != nil { - target.Set(reflect.ValueOf(p.parameter.Default)) - return nil - } - tpe := p.parameter.Type - if p.parameter.Format != "" { - tpe = p.parameter.Format - } - return errors.InvalidType(p.Name, p.parameter.In, tpe, nil) - } - target.Set(reflect.Indirect(newValue)) - return nil - default: - return errors.New(500, fmt.Sprintf("invalid parameter location %q", p.parameter.In)) - } -} - -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) - } - var d string - if len(data) > 0 { - d = data[len(data)-1] - } - return p.setFieldValue(target, p.parameter.Default, d, hasKey) -} - -func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue interface{}, data string, hasKey bool) error { //nolint:gocyclo - tpe := p.parameter.Type - if p.parameter.Format != "" { - tpe = p.parameter.Format - } - - if (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) && p.parameter.Required && p.parameter.Default == nil { - return errors.Required(p.Name, p.parameter.In, data) - } - - ok, err := p.tryUnmarshaler(target, defaultValue, data) - if err != nil { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if ok { - return nil - } - - defVal := reflect.Zero(target.Type()) - if defaultValue != nil { - defVal = reflect.ValueOf(defaultValue) - } - - if tpe == "byte" { - if data == "" { - if target.CanSet() { - target.SetBytes(defVal.Bytes()) - } - return nil - } - - b, err := base64.StdEncoding.DecodeString(data) - if err != nil { - b, err = base64.URLEncoding.DecodeString(data) - if err != nil { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - } - if target.CanSet() { - target.SetBytes(b) - } - return nil - } - - switch target.Kind() { //nolint:exhaustive // we want to check only types that map from a swagger parameter - case reflect.Bool: - if data == "" { - if target.CanSet() { - target.SetBool(defVal.Bool()) - } - return nil - } - b, err := swag.ConvertBool(data) - if err != nil { - return err - } - if target.CanSet() { - target.SetBool(b) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if data == "" { - if target.CanSet() { - rd := defVal.Convert(reflect.TypeOf(int64(0))) - target.SetInt(rd.Int()) - } - return nil - } - i, err := strconv.ParseInt(data, 10, 64) - if err != nil { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if target.OverflowInt(i) { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if target.CanSet() { - target.SetInt(i) - } - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if data == "" { - if target.CanSet() { - rd := defVal.Convert(reflect.TypeOf(uint64(0))) - target.SetUint(rd.Uint()) - } - return nil - } - u, err := strconv.ParseUint(data, 10, 64) - if err != nil { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if target.OverflowUint(u) { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if target.CanSet() { - target.SetUint(u) - } - - case reflect.Float32, reflect.Float64: - if data == "" { - if target.CanSet() { - rd := defVal.Convert(reflect.TypeOf(float64(0))) - target.SetFloat(rd.Float()) - } - return nil - } - f, err := strconv.ParseFloat(data, 64) - if err != nil { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if target.OverflowFloat(f) { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - if target.CanSet() { - target.SetFloat(f) - } - - case reflect.String: - value := data - if value == "" { - value = defVal.String() - } - // validate string - if target.CanSet() { - target.SetString(value) - } - - case reflect.Ptr: - if data == "" && defVal.Kind() == reflect.Ptr { - if target.CanSet() { - target.Set(defVal) - } - return nil - } - newVal := reflect.New(target.Type().Elem()) - if err := p.setFieldValue(reflect.Indirect(newVal), defVal, data, hasKey); err != nil { - return err - } - if target.CanSet() { - target.Set(newVal) - } - - default: - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - return nil -} - -func (p *untypedParamBinder) tryUnmarshaler(target reflect.Value, defaultValue interface{}, data string) (bool, error) { - if !target.CanSet() { - 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 defaultValue != nil && len(data) == 0 { - target.Set(reflect.ValueOf(defaultValue)) - return true, nil - } - value := reflect.New(target.Type()) - if err := value.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(data)); err != nil { - return true, err - } - target.Set(reflect.Indirect(value)) - return true, nil - } - return false, nil -} - -func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target reflect.Value) ([]string, bool, error) { - ok, err := p.tryUnmarshaler(target, p.parameter.Default, data) - if err != nil { - return nil, true, err - } - if ok { - return nil, true, nil - } - - return swag.SplitByFormat(data, p.parameter.CollectionFormat), false, nil -} - -func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error { - sz := len(data) - if (!hasKey || (!p.parameter.AllowEmptyValue && (sz == 0 || (sz == 1 && data[0] == "")))) && p.parameter.Required && defaultValue == nil { - return errors.Required(p.Name, p.parameter.In, data) - } - - defVal := reflect.Zero(target.Type()) - if defaultValue != nil { - defVal = reflect.ValueOf(defaultValue) - } - - if !target.CanSet() { - return nil - } - if sz == 0 { - target.Set(defVal) - return nil - } - - value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz) - - for i := 0; i < sz; i++ { - if err := p.setFieldValue(value.Index(i), nil, data[i], hasKey); err != nil { - return err - } - } - - target.Set(value) - - return nil -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go b/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go deleted file mode 100644 index ef75e7441..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go +++ /dev/null @@ -1,80 +0,0 @@ -package middleware - -import ( - "bytes" - "fmt" - "html/template" - "net/http" - "path" -) - -// RapiDocOpts configures the RapiDoc middlewares -type RapiDocOpts struct { - // BasePath for the UI, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string - - // RapiDocURL points to the js asset that generates the rapidoc site. - // - // Defaults to https://unpkg.com/rapidoc/dist/rapidoc-min.js - RapiDocURL string -} - -func (r *RapiDocOpts) EnsureDefaults() { - common := toCommonUIOptions(r) - common.EnsureDefaults() - fromCommonToAnyOptions(common, r) - - // rapidoc-specifics - if r.RapiDocURL == "" { - r.RapiDocURL = rapidocLatest - } - if r.Template == "" { - r.Template = rapidocTemplate - } -} - -// RapiDoc creates a middleware to serve a documentation site for a swagger spec. -// -// This allows for altering the spec before starting the http listener. -func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler { - opts.EnsureDefaults() - - pth := path.Join(opts.BasePath, opts.Path) - tmpl := template.Must(template.New("rapidoc").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - rapidocLatest = "https://unpkg.com/rapidoc/dist/rapidoc-min.js" - rapidocTemplate = `<!doctype html> -<html> -<head> - <title>{{ .Title }}</title> - <meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 characters --> - <script type="module" src="{{ .RapiDocURL }}"></script> -</head> -<body> - <rapi-doc spec-url="{{ .SpecURL }}"></rapi-doc> -</body> -</html> -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/redoc.go b/vendor/github.com/go-openapi/runtime/middleware/redoc.go deleted file mode 100644 index b96b01e7f..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/redoc.go +++ /dev/null @@ -1,94 +0,0 @@ -package middleware - -import ( - "bytes" - "fmt" - "html/template" - "net/http" - "path" -) - -// RedocOpts configures the Redoc middlewares -type RedocOpts struct { - // BasePath for the UI, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string - - // RedocURL points to the js that generates the redoc site. - // - // Defaults to: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js - RedocURL string -} - -// EnsureDefaults in case some options are missing -func (r *RedocOpts) EnsureDefaults() { - common := toCommonUIOptions(r) - common.EnsureDefaults() - fromCommonToAnyOptions(common, r) - - // redoc-specifics - if r.RedocURL == "" { - r.RedocURL = redocLatest - } - if r.Template == "" { - r.Template = redocTemplate - } -} - -// Redoc creates a middleware to serve a documentation site for a swagger spec. -// -// This allows for altering the spec before starting the http listener. -func Redoc(opts RedocOpts, next http.Handler) http.Handler { - opts.EnsureDefaults() - - pth := path.Join(opts.BasePath, opts.Path) - tmpl := template.Must(template.New("redoc").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - redocLatest = "https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js" - redocTemplate = `<!DOCTYPE html> -<html> - <head> - <title>{{ .Title }}</title> - <!-- needed for adaptive design --> - <meta charset="utf-8"/> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet"> - - <!-- - ReDoc doesn't change outer page styles - --> - <style> - body { - margin: 0; - padding: 0; - } - </style> - </head> - <body> - <redoc spec-url='{{ .SpecURL }}'></redoc> - <script src="{{ .RedocURL }}"> </script> - </body> -</html> -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/request.go b/vendor/github.com/go-openapi/runtime/middleware/request.go deleted file mode 100644 index 82e143665..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/request.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - "net/http" - "reflect" - - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/logger" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" -) - -// UntypedRequestBinder binds and validates the data from a http request -type UntypedRequestBinder struct { - Spec *spec.Swagger - Parameters map[string]spec.Parameter - Formats strfmt.Registry - paramBinders map[string]*untypedParamBinder - debugLogf func(string, ...any) // a logging function to debug context and all components using it -} - -// NewUntypedRequestBinder creates a new binder for reading a request. -func NewUntypedRequestBinder(parameters map[string]spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *UntypedRequestBinder { - binders := make(map[string]*untypedParamBinder) - for fieldName, param := range parameters { - binders[fieldName] = newUntypedParamBinder(param, spec, formats) - } - return &UntypedRequestBinder{ - Parameters: parameters, - paramBinders: binders, - Spec: spec, - Formats: formats, - debugLogf: debugLogfFunc(nil), - } -} - -// Bind perform the databinding and validation -func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, data interface{}) error { - val := reflect.Indirect(reflect.ValueOf(data)) - isMap := val.Kind() == reflect.Map - var result []error - o.debugLogf("binding %d parameters for %s %s", len(o.Parameters), request.Method, request.URL.EscapedPath()) - for fieldName, param := range o.Parameters { - binder := o.paramBinders[fieldName] - o.debugLogf("binding parameter %s for %s %s", fieldName, request.Method, request.URL.EscapedPath()) - var target reflect.Value - if !isMap { - binder.Name = fieldName - target = val.FieldByName(fieldName) - } - - if isMap { - tpe := binder.Type() - if tpe == nil { - if param.Schema.Type.Contains(typeArray) { - tpe = reflect.TypeOf([]interface{}{}) - } else { - tpe = reflect.TypeOf(map[string]interface{}{}) - } - } - target = reflect.Indirect(reflect.New(tpe)) - } - - if !target.IsValid() { - result = append(result, errors.New(500, "parameter name %q is an unknown field", binder.Name)) - continue - } - - if err := binder.Bind(request, routeParams, consumer, target); err != nil { - result = append(result, err) - continue - } - - if binder.validator != nil { - rr := binder.validator.Validate(target.Interface()) - if rr != nil && rr.HasErrors() { - result = append(result, rr.AsError()) - } - } - - if isMap { - val.SetMapIndex(reflect.ValueOf(param.Name), target) - } - } - - if len(result) > 0 { - return errors.CompositeValidationError(result...) - } - - return nil -} - -// SetLogger allows for injecting a logger to catch debug entries. -// -// The logger is enabled in DEBUG mode only. -func (o *UntypedRequestBinder) SetLogger(lg logger.Logger) { - o.debugLogf = debugLogfFunc(lg) -} - -func (o *UntypedRequestBinder) setDebugLogf(fn func(string, ...any)) { - o.debugLogf = fn -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/router.go b/vendor/github.com/go-openapi/runtime/middleware/router.go deleted file mode 100644 index 3a6aee90e..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/router.go +++ /dev/null @@ -1,531 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - "fmt" - "net/http" - "net/url" - fpath "path" - "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/spec" - "github.com/go-openapi/strfmt" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/middleware/denco" -) - -// RouteParam is a object to capture route params in a framework agnostic way. -// implementations of the muxer should use these route params to communicate with the -// swagger framework -type RouteParam struct { - Name string - Value string -} - -// RouteParams the collection of route params -type RouteParams []RouteParam - -// Get gets the value for the route param for the specified key -func (r RouteParams) Get(name string) string { - vv, _, _ := r.GetOK(name) - if len(vv) > 0 { - return vv[len(vv)-1] - } - return "" -} - -// GetOK gets the value but also returns booleans to indicate if a key or value -// is present. This aids in validation and satisfies an interface in use there -// -// The returned values are: data, has key, has value -func (r RouteParams) GetOK(name string) ([]string, bool, bool) { - for _, p := range r { - if p.Name == name { - return []string{p.Value}, true, p.Value != "" - } - } - return nil, false, false -} - -// NewRouter creates a new context-aware router middleware -func NewRouter(ctx *Context, next http.Handler) http.Handler { - if ctx.router == nil { - ctx.router = DefaultRouter(ctx.spec, ctx.api, WithDefaultRouterLoggerFunc(ctx.debugLogf)) - } - - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - if _, rCtx, ok := ctx.RouteInfo(r); ok { - next.ServeHTTP(rw, rCtx) - return - } - - // Not found, check if it exists in the other methods first - if others := ctx.AllowedMethods(r); len(others) > 0 { - ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others)) - return - } - - ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.EscapedPath())) - }) -} - -// RoutableAPI represents an interface for things that can serve -// as a provider of implementations for the swagger router -type RoutableAPI interface { - HandlerFor(string, string) (http.Handler, bool) - ServeErrorFor(string) func(http.ResponseWriter, *http.Request, error) - ConsumersFor([]string) map[string]runtime.Consumer - ProducersFor([]string) map[string]runtime.Producer - AuthenticatorsFor(map[string]spec.SecurityScheme) map[string]runtime.Authenticator - Authorizer() runtime.Authorizer - Formats() strfmt.Registry - DefaultProduces() string - DefaultConsumes() string -} - -// Router represents a swagger-aware router -type Router interface { - Lookup(method, path string) (*MatchedRoute, bool) - OtherMethods(method, path string) []string -} - -type defaultRouteBuilder struct { - spec *loads.Document - analyzer *analysis.Spec - api RoutableAPI - records map[string][]denco.Record - debugLogf func(string, ...any) // a logging function to debug context and all components using it -} - -type defaultRouter struct { - spec *loads.Document - routers map[string]*denco.Router - debugLogf func(string, ...any) // a logging function to debug context and all components using it -} - -func newDefaultRouteBuilder(spec *loads.Document, api RoutableAPI, opts ...DefaultRouterOpt) *defaultRouteBuilder { - var o defaultRouterOpts - for _, apply := range opts { - apply(&o) - } - if o.debugLogf == nil { - o.debugLogf = debugLogfFunc(nil) // defaults to standard logger - } - - return &defaultRouteBuilder{ - spec: spec, - analyzer: analysis.New(spec.Spec()), - api: api, - records: make(map[string][]denco.Record), - debugLogf: o.debugLogf, - } -} - -// DefaultRouterOpt allows to inject optional behavior to the default router. -type DefaultRouterOpt func(*defaultRouterOpts) - -type defaultRouterOpts struct { - debugLogf func(string, ...any) -} - -// WithDefaultRouterLogger sets the debug logger for the default router. -// -// This is enabled only in DEBUG mode. -func WithDefaultRouterLogger(lg logger.Logger) DefaultRouterOpt { - return func(o *defaultRouterOpts) { - o.debugLogf = debugLogfFunc(lg) - } -} - -// WithDefaultRouterLoggerFunc sets a logging debug method for the default router. -func WithDefaultRouterLoggerFunc(fn func(string, ...any)) DefaultRouterOpt { - return func(o *defaultRouterOpts) { - o.debugLogf = fn - } -} - -// DefaultRouter creates a default implementation of the router -func DefaultRouter(spec *loads.Document, api RoutableAPI, opts ...DefaultRouterOpt) Router { - builder := newDefaultRouteBuilder(spec, api, opts...) - if spec != nil { - for method, paths := range builder.analyzer.Operations() { - for path, operation := range paths { - fp := fpath.Join(spec.BasePath(), path) - builder.debugLogf("adding route %s %s %q", method, fp, operation.ID) - builder.AddRoute(method, fp, operation) - } - } - } - return builder.Build() -} - -// RouteAuthenticator is an authenticator that can compose several authenticators together. -// It also knows when it contains an authenticator that allows for anonymous pass through. -// Contains a group of 1 or more authenticators that have a logical AND relationship -type RouteAuthenticator struct { - Authenticator map[string]runtime.Authenticator - Schemes []string - Scopes map[string][]string - allScopes []string - commonScopes []string - allowAnonymous bool -} - -func (ra *RouteAuthenticator) AllowsAnonymous() bool { - return ra.allowAnonymous -} - -// AllScopes returns a list of unique scopes that is the combination -// of all the scopes in the requirements -func (ra *RouteAuthenticator) AllScopes() []string { - return ra.allScopes -} - -// CommonScopes returns a list of unique scopes that are common in all the -// scopes in the requirements -func (ra *RouteAuthenticator) CommonScopes() []string { - return ra.commonScopes -} - -// Authenticate Authenticator interface implementation -func (ra *RouteAuthenticator) Authenticate(req *http.Request, route *MatchedRoute) (bool, interface{}, error) { - if ra.allowAnonymous { - route.Authenticator = ra - return true, nil, nil - } - // iterate in proper order - var lastResult interface{} - for _, scheme := range ra.Schemes { - if authenticator, ok := ra.Authenticator[scheme]; ok { - applies, princ, err := authenticator.Authenticate(&security.ScopedAuthRequest{ - Request: req, - RequiredScopes: ra.Scopes[scheme], - }) - if !applies { - return false, nil, nil - } - if err != nil { - route.Authenticator = ra - return true, nil, err - } - lastResult = princ - } - } - route.Authenticator = ra - return true, lastResult, nil -} - -func stringSliceUnion(slices ...[]string) []string { - unique := make(map[string]struct{}) - var result []string - for _, slice := range slices { - for _, entry := range slice { - if _, ok := unique[entry]; ok { - continue - } - unique[entry] = struct{}{} - result = append(result, entry) - } - } - return result -} - -func stringSliceIntersection(slices ...[]string) []string { - unique := make(map[string]int) - var intersection []string - - total := len(slices) - var emptyCnt int - for _, slice := range slices { - if len(slice) == 0 { - emptyCnt++ - continue - } - - for _, entry := range slice { - unique[entry]++ - if unique[entry] == total-emptyCnt { // this entry appeared in all the non-empty slices - intersection = append(intersection, entry) - } - } - } - - return intersection -} - -// RouteAuthenticators represents a group of authenticators that represent a logical OR -type RouteAuthenticators []RouteAuthenticator - -// AllowsAnonymous returns true when there is an authenticator that means optional auth -func (ras RouteAuthenticators) AllowsAnonymous() bool { - for _, ra := range ras { - if ra.AllowsAnonymous() { - return true - } - } - return false -} - -// Authenticate method implemention so this collection can be used as authenticator -func (ras RouteAuthenticators) Authenticate(req *http.Request, route *MatchedRoute) (bool, interface{}, error) { - var lastError error - var allowsAnon bool - var anonAuth RouteAuthenticator - - for _, ra := range ras { - if ra.AllowsAnonymous() { - anonAuth = ra - allowsAnon = true - continue - } - applies, usr, err := ra.Authenticate(req, route) - if !applies || err != nil || usr == nil { - if err != nil { - lastError = err - } - continue - } - return applies, usr, nil - } - - if allowsAnon && lastError == nil { - route.Authenticator = &anonAuth - return true, nil, lastError - } - return lastError != nil, nil, lastError -} - -type routeEntry struct { - PathPattern string - BasePath string - Operation *spec.Operation - Consumes []string - Consumers map[string]runtime.Consumer - Produces []string - Producers map[string]runtime.Producer - Parameters map[string]spec.Parameter - Handler http.Handler - Formats strfmt.Registry - Binder *UntypedRequestBinder - Authenticators RouteAuthenticators - Authorizer runtime.Authorizer -} - -// MatchedRoute represents the route that was matched in this request -type MatchedRoute struct { - routeEntry - Params RouteParams - Consumer runtime.Consumer - Producer runtime.Producer - Authenticator *RouteAuthenticator -} - -// HasAuth returns true when the route has a security requirement defined -func (m *MatchedRoute) HasAuth() bool { - return len(m.Authenticators) > 0 -} - -// NeedsAuth returns true when the request still -// needs to perform authentication -func (m *MatchedRoute) NeedsAuth() bool { - return m.HasAuth() && m.Authenticator == nil -} - -func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) { - mth := strings.ToUpper(method) - d.debugLogf("looking up route for %s %s", method, path) - if Debug { - if len(d.routers) == 0 { - d.debugLogf("there are no known routers") - } - for meth := range d.routers { - d.debugLogf("got a router for %s", meth) - } - } - if router, ok := d.routers[mth]; ok { - if m, rp, ok := router.Lookup(fpath.Clean(path)); ok && m != nil { - if entry, ok := m.(*routeEntry); ok { - d.debugLogf("found a route for %s %s with %d parameters", method, path, len(entry.Parameters)) - var params RouteParams - for _, p := range rp { - v, err := url.PathUnescape(p.Value) - if err != nil { - d.debugLogf("failed to escape %q: %v", p.Value, err) - v = p.Value - } - // 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] != '/' { - // extract fragment parameters - ep := strings.Split(entry.PathPattern[xpos:], "/")[0] - pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil) - for i, pname := range pnames { - params = append(params, RouteParam{Name: pname, Value: pvalues[i]}) - } - } else { - // use the parameter directly - params = append(params, RouteParam{Name: p.Name, Value: v}) - } - } - return &MatchedRoute{routeEntry: *entry, Params: params}, true - } - } else { - d.debugLogf("couldn't find a route by path for %s %s", method, path) - } - } else { - d.debugLogf("couldn't find a route by method for %s %s", method, path) - } - return nil, false -} - -func (d *defaultRouter) OtherMethods(method, path string) []string { - mn := strings.ToUpper(method) - var methods []string - for k, v := range d.routers { - if k != mn { - if _, _, ok := v.Lookup(fpath.Clean(path)); ok { - methods = append(methods, k) - continue - } - } - } - return methods -} - -func (d *defaultRouter) SetLogger(lg logger.Logger) { - d.debugLogf = debugLogfFunc(lg) -} - -// convert swagger parameters per path segment into a denco parameter as multiple parameters per segment are not supported in denco -var pathConverter = regexp.MustCompile(`{(.+?)}([^/]*)`) - -func decodeCompositParams(name string, value string, pattern string, names []string, values []string) ([]string, []string) { - pleft := strings.Index(pattern, "{") - names = append(names, name) - if pleft < 0 { - if strings.HasSuffix(value, pattern) { - values = append(values, value[:len(value)-len(pattern)]) - } else { - values = append(values, "") - } - } else { - toskip := pattern[:pleft] - pright := strings.Index(pattern, "}") - vright := strings.Index(value, toskip) - if vright >= 0 { - values = append(values, value[:vright]) - } else { - values = append(values, "") - value = "" - } - return decodeCompositParams(pattern[pleft+1:pright], value[vright+len(toskip):], pattern[pright+1:], names, values) - } - return names, values -} - -func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Operation) { - mn := strings.ToUpper(method) - - bp := fpath.Clean(d.spec.BasePath()) - if len(bp) > 0 && bp[len(bp)-1] == '/' { - bp = bp[:len(bp)-1] - } - - d.debugLogf("operation: %#v", *operation) - if handler, ok := d.api.HandlerFor(method, strings.TrimPrefix(path, bp)); ok { - consumes := d.analyzer.ConsumesFor(operation) - produces := d.analyzer.ProducesFor(operation) - 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) { - consumes = append(consumes, defConsumes) - } - - if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) { - produces = append(produces, defProduces) - } - - requestBinder := NewUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()) - requestBinder.setDebugLogf(d.debugLogf) - record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{ - BasePath: bp, - PathPattern: path, - Operation: operation, - Handler: handler, - Consumes: consumes, - Produces: produces, - Consumers: d.api.ConsumersFor(normalizeOffers(consumes)), - Producers: d.api.ProducersFor(normalizeOffers(produces)), - Parameters: parameters, - Formats: d.api.Formats(), - Binder: requestBinder, - Authenticators: d.buildAuthenticators(operation), - Authorizer: d.api.Authorizer(), - }) - d.records[mn] = append(d.records[mn], record) - } -} - -func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) RouteAuthenticators { - requirements := d.analyzer.SecurityRequirementsFor(operation) - auths := make([]RouteAuthenticator, 0, len(requirements)) - for _, reqs := range requirements { - schemes := make([]string, 0, len(reqs)) - scopes := make(map[string][]string, len(reqs)) - scopeSlices := make([][]string, 0, len(reqs)) - for _, req := range reqs { - schemes = append(schemes, req.Name) - scopes[req.Name] = req.Scopes - scopeSlices = append(scopeSlices, req.Scopes) - } - - definitions := d.analyzer.SecurityDefinitionsForRequirements(reqs) - authenticators := d.api.AuthenticatorsFor(definitions) - auths = append(auths, RouteAuthenticator{ - Authenticator: authenticators, - Schemes: schemes, - Scopes: scopes, - allScopes: stringSliceUnion(scopeSlices...), - commonScopes: stringSliceIntersection(scopeSlices...), - allowAnonymous: len(reqs) == 1 && reqs[0].Name == "", - }) - } - 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, - } -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/security.go b/vendor/github.com/go-openapi/runtime/middleware/security.go deleted file mode 100644 index 2b061caef..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/security.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import "net/http" - -func newSecureAPI(ctx *Context, next http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - route, rCtx, _ := ctx.RouteInfo(r) - if rCtx != nil { - r = rCtx - } - if route != nil && !route.NeedsAuth() { - next.ServeHTTP(rw, r) - return - } - - _, rCtx, err := ctx.Authorize(r, route) - if err != nil { - ctx.Respond(rw, r, route.Produces, route, err) - return - } - r = rCtx - - next.ServeHTTP(rw, r) - }) -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/spec.go b/vendor/github.com/go-openapi/runtime/middleware/spec.go deleted file mode 100644 index 87e17e342..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/spec.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - "net/http" - "path" -) - -const ( - contentTypeHeader = "Content-Type" - applicationJSON = "application/json" -) - -// SpecOption can be applied to the Spec serving middleware -type SpecOption func(*specOptions) - -var defaultSpecOptions = specOptions{ - Path: "", - Document: "swagger.json", -} - -type specOptions struct { - Path string - Document string -} - -func specOptionsWithDefaults(opts []SpecOption) specOptions { - o := defaultSpecOptions - for _, apply := range opts { - apply(&o) - } - - return o -} - -// Spec creates a middleware to serve a swagger spec as a JSON document. -// -// This allows for altering the spec before starting the http listener. -// -// The basePath argument indicates the path of the spec document (defaults to "/"). -// Additional SpecOption can be used to change the name of the document (defaults to "swagger.json"). -func Spec(basePath string, b []byte, next http.Handler, opts ...SpecOption) http.Handler { - if basePath == "" { - basePath = "/" - } - o := specOptionsWithDefaults(opts) - pth := path.Join(basePath, o.Path, o.Document) - - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - if path.Clean(r.URL.Path) == pth { - rw.Header().Set(contentTypeHeader, applicationJSON) - rw.WriteHeader(http.StatusOK) - _, _ = rw.Write(b) - - return - } - - if next != nil { - next.ServeHTTP(rw, r) - - return - } - - rw.Header().Set(contentTypeHeader, applicationJSON) - rw.WriteHeader(http.StatusNotFound) - }) -} - -// WithSpecPath sets the path to be joined to the base path of the Spec middleware. -// -// This is empty by default. -func WithSpecPath(pth string) SpecOption { - return func(o *specOptions) { - o.Path = pth - } -} - -// WithSpecDocument sets the name of the JSON document served as a spec. -// -// By default, this is "swagger.json" -func WithSpecDocument(doc string) SpecOption { - return func(o *specOptions) { - if doc == "" { - return - } - - o.Document = doc - } -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go b/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go deleted file mode 100644 index ec3c10cba..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go +++ /dev/null @@ -1,175 +0,0 @@ -package middleware - -import ( - "bytes" - "fmt" - "html/template" - "net/http" - "path" -) - -// SwaggerUIOpts configures the SwaggerUI middleware -type SwaggerUIOpts struct { - // BasePath for the API, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string - - // OAuthCallbackURL the url called after OAuth2 login - OAuthCallbackURL string - - // The three components needed to embed swagger-ui - - // SwaggerURL points to the js that generates the SwaggerUI site. - // - // Defaults to: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js - SwaggerURL string - - SwaggerPresetURL string - SwaggerStylesURL string - - Favicon32 string - Favicon16 string -} - -// EnsureDefaults in case some options are missing -func (r *SwaggerUIOpts) EnsureDefaults() { - r.ensureDefaults() - - if r.Template == "" { - r.Template = swaggeruiTemplate - } -} - -func (r *SwaggerUIOpts) EnsureDefaultsOauth2() { - r.ensureDefaults() - - if r.Template == "" { - r.Template = swaggerOAuthTemplate - } -} - -func (r *SwaggerUIOpts) ensureDefaults() { - common := toCommonUIOptions(r) - common.EnsureDefaults() - fromCommonToAnyOptions(common, r) - - // swaggerui-specifics - if r.OAuthCallbackURL == "" { - r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback") - } - if r.SwaggerURL == "" { - r.SwaggerURL = swaggerLatest - } - if r.SwaggerPresetURL == "" { - r.SwaggerPresetURL = swaggerPresetLatest - } - if r.SwaggerStylesURL == "" { - r.SwaggerStylesURL = swaggerStylesLatest - } - if r.Favicon16 == "" { - r.Favicon16 = swaggerFavicon16Latest - } - if r.Favicon32 == "" { - r.Favicon32 = swaggerFavicon32Latest - } -} - -// SwaggerUI creates a middleware to serve a documentation site for a swagger spec. -// -// This allows for altering the spec before starting the http listener. -func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler { - opts.EnsureDefaults() - - pth := path.Join(opts.BasePath, opts.Path) - tmpl := template.Must(template.New("swaggerui").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - swaggerLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" - swaggerPresetLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js" - swaggerStylesLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui.css" - swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png" - swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png" - swaggeruiTemplate = ` -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="UTF-8"> - <title>{{ .Title }}</title> - - <link rel="stylesheet" type="text/css" href="{{ .SwaggerStylesURL }}" > - <link rel="icon" type="image/png" href="{{ .Favicon32 }}" sizes="32x32" /> - <link rel="icon" type="image/png" href="{{ .Favicon16 }}" sizes="16x16" /> - <style> - html - { - box-sizing: border-box; - overflow: -moz-scrollbars-vertical; - overflow-y: scroll; - } - - *, - *:before, - *:after - { - box-sizing: inherit; - } - - body - { - margin:0; - background: #fafafa; - } - </style> - </head> - - <body> - <div id="swagger-ui"></div> - - <script src="{{ .SwaggerURL }}"> </script> - <script src="{{ .SwaggerPresetURL }}"> </script> - <script> - window.onload = function() { - // Begin Swagger UI call region - const ui = SwaggerUIBundle({ - url: '{{ .SpecURL }}', - dom_id: '#swagger-ui', - deepLinking: true, - presets: [ - SwaggerUIBundle.presets.apis, - SwaggerUIStandalonePreset - ], - plugins: [ - SwaggerUIBundle.plugins.DownloadUrl - ], - layout: "StandaloneLayout", - oauth2RedirectUrl: '{{ .OAuthCallbackURL }}' - }) - // End Swagger UI call region - - window.ui = ui - } - </script> - </body> -</html> -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go b/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go deleted file mode 100644 index e81212f71..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go +++ /dev/null @@ -1,105 +0,0 @@ -package middleware - -import ( - "bytes" - "fmt" - "net/http" - "text/template" -) - -func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler { - opts.EnsureDefaultsOauth2() - - pth := opts.OAuthCallbackURL - tmpl := template.Must(template.New("swaggeroauth").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - swaggerOAuthTemplate = ` -<!DOCTYPE html> -<html lang="en"> -<head> - <title>{{ .Title }}</title> -</head> -<body> -<script> - 'use strict'; - function run () { - var oauth2 = window.opener.swaggerUIRedirectOauth2; - var sentState = oauth2.state; - var redirectUrl = oauth2.redirectUrl; - var isValid, qp, arr; - - if (/code|token|error/.test(window.location.hash)) { - qp = window.location.hash.substring(1).replace('?', '&'); - } else { - qp = location.search.substring(1); - } - - arr = qp.split("&"); - arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';}); - qp = qp ? JSON.parse('{' + arr.join() + '}', - function (key, value) { - return key === "" ? value : decodeURIComponent(value); - } - ) : {}; - - isValid = qp.state === sentState; - - if (( - oauth2.auth.schema.get("flow") === "accessCode" || - oauth2.auth.schema.get("flow") === "authorizationCode" || - oauth2.auth.schema.get("flow") === "authorization_code" - ) && !oauth2.auth.code) { - if (!isValid) { - oauth2.errCb({ - authId: oauth2.auth.name, - source: "auth", - level: "warning", - message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server." - }); - } - - if (qp.code) { - delete oauth2.state; - oauth2.auth.code = qp.code; - oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); - } else { - let oauthErrorMsg; - if (qp.error) { - oauthErrorMsg = "["+qp.error+"]: " + - (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + - (qp.error_uri ? "More info: "+qp.error_uri : ""); - } - - oauth2.errCb({ - authId: oauth2.auth.name, - source: "auth", - level: "error", - message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server." - }); - } - } else { - oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl}); - } - window.close(); - } - - if (document.readyState !== 'loading') { - run(); - } else { - document.addEventListener('DOMContentLoaded', function () { - run(); - }); - } -</script> -</body> -</html> -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/ui_options.go b/vendor/github.com/go-openapi/runtime/middleware/ui_options.go deleted file mode 100644 index b86efa008..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/ui_options.go +++ /dev/null @@ -1,173 +0,0 @@ -package middleware - -import ( - "bytes" - "encoding/gob" - "fmt" - "net/http" - "path" - "strings" -) - -const ( - // constants that are common to all UI-serving middlewares - defaultDocsPath = "docs" - defaultDocsURL = "/swagger.json" - defaultDocsTitle = "API Documentation" -) - -// uiOptions defines common options for UI serving middlewares. -type uiOptions struct { - // BasePath for the UI, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string -} - -// toCommonUIOptions converts any UI option type to retain the common options. -// -// This uses gob encoding/decoding to convert common fields from one struct to another. -func toCommonUIOptions(opts interface{}) uiOptions { - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - dec := gob.NewDecoder(&buf) - var o uiOptions - err := enc.Encode(opts) - if err != nil { - panic(err) - } - - err = dec.Decode(&o) - if err != nil { - panic(err) - } - - return o -} - -func fromCommonToAnyOptions[T any](source uiOptions, target *T) { - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - dec := gob.NewDecoder(&buf) - err := enc.Encode(source) - if err != nil { - panic(err) - } - - err = dec.Decode(target) - if err != nil { - panic(err) - } -} - -// UIOption can be applied to UI serving middleware, such as Context.APIHandler or -// Context.APIHandlerSwaggerUI to alter the defaut behavior. -type UIOption func(*uiOptions) - -func uiOptionsWithDefaults(opts []UIOption) uiOptions { - var o uiOptions - for _, apply := range opts { - apply(&o) - } - - return o -} - -// WithUIBasePath sets the base path from where to serve the UI assets. -// -// By default, Context middleware sets this value to the API base path. -func WithUIBasePath(base string) UIOption { - return func(o *uiOptions) { - if !strings.HasPrefix(base, "/") { - base = "/" + base - } - o.BasePath = base - } -} - -// WithUIPath sets the path from where to serve the UI assets (i.e. /{basepath}/{path}. -func WithUIPath(pth string) UIOption { - return func(o *uiOptions) { - o.Path = pth - } -} - -// WithUISpecURL sets the path from where to serve swagger spec document. -// -// This may be specified as a full URL or a path. -// -// By default, this is "/swagger.json" -func WithUISpecURL(specURL string) UIOption { - return func(o *uiOptions) { - o.SpecURL = specURL - } -} - -// WithUITitle sets the title of the UI. -// -// By default, Context middleware sets this value to the title found in the API spec. -func WithUITitle(title string) UIOption { - return func(o *uiOptions) { - o.Title = title - } -} - -// WithTemplate allows to set a custom template for the UI. -// -// UI middleware will panic if the template does not parse or execute properly. -func WithTemplate(tpl string) UIOption { - return func(o *uiOptions) { - o.Template = tpl - } -} - -// EnsureDefaults in case some options are missing -func (r *uiOptions) EnsureDefaults() { - if r.BasePath == "" { - r.BasePath = "/" - } - if r.Path == "" { - r.Path = defaultDocsPath - } - if r.SpecURL == "" { - r.SpecURL = defaultDocsURL - } - if r.Title == "" { - r.Title = defaultDocsTitle - } -} - -// serveUI creates a middleware that serves a templated asset as text/html. -func serveUI(pth string, assets []byte, next http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - if path.Clean(r.URL.Path) == pth { - rw.Header().Set(contentTypeHeader, "text/html; charset=utf-8") - rw.WriteHeader(http.StatusOK) - _, _ = rw.Write(assets) - - return - } - - if next != nil { - next.ServeHTTP(rw, r) - - return - } - - rw.Header().Set(contentTypeHeader, "text/plain") - rw.WriteHeader(http.StatusNotFound) - _, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth))) - }) -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go b/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go deleted file mode 100644 index 7b7269bd1..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package untyped - -import ( - "fmt" - "net/http" - "sort" - "strings" - - "github.com/go-openapi/analysis" - "github.com/go-openapi/errors" - "github.com/go-openapi/loads" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - - "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() -} - -// API represents an untyped mux for a swagger spec -type API struct { - spec *loads.Document - analyzer *analysis.Spec - DefaultProduces string - DefaultConsumes string - consumers map[string]runtime.Consumer - producers map[string]runtime.Producer - authenticators map[string]runtime.Authenticator - authorizer runtime.Authorizer - operations map[string]map[string]runtime.OperationHandler - ServeError func(http.ResponseWriter, *http.Request, error) - Models map[string]func() interface{} - formats strfmt.Registry -} - -// WithJSONDefaults loads the json defaults for this api -func (d *API) WithJSONDefaults() *API { - d.DefaultConsumes = runtime.JSONMime - d.DefaultProduces = runtime.JSONMime - d.consumers[runtime.JSONMime] = runtime.JSONConsumer() - d.producers[runtime.JSONMime] = runtime.JSONProducer() - return d -} - -// WithoutJSONDefaults clears the json defaults for this api -func (d *API) WithoutJSONDefaults() *API { - d.DefaultConsumes = "" - d.DefaultProduces = "" - delete(d.consumers, runtime.JSONMime) - delete(d.producers, runtime.JSONMime) - return d -} - -// Formats returns the registered string formats -func (d *API) Formats() strfmt.Registry { - if d.formats == nil { - d.formats = strfmt.NewFormats() - } - return d.formats -} - -// RegisterFormat registers a custom format validator -func (d *API) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) { - if d.formats == nil { - d.formats = strfmt.NewFormats() - } - d.formats.Add(name, format, validator) -} - -// RegisterAuth registers an auth handler in this api -func (d *API) RegisterAuth(scheme string, handler runtime.Authenticator) { - if d.authenticators == nil { - d.authenticators = make(map[string]runtime.Authenticator) - } - d.authenticators[scheme] = handler -} - -// RegisterAuthorizer registers an authorizer handler in this api -func (d *API) RegisterAuthorizer(handler runtime.Authorizer) { - d.authorizer = handler -} - -// 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[strings.ToLower(mediaType)] = handler -} - -// 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[strings.ToLower(mediaType)] = handler -} - -// 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) - } - um := strings.ToUpper(method) - if b, ok := d.operations[um]; !ok || b == nil { - d.operations[um] = make(map[string]runtime.OperationHandler) - } - d.operations[um][path] = handler -} - -// OperationHandlerFor returns the operation handler for the specified id if it can be found -func (d *API) OperationHandlerFor(method, path string) (runtime.OperationHandler, bool) { - if d.operations == nil { - return nil, false - } - if pi, ok := d.operations[strings.ToUpper(method)]; ok { - h, ok := pi[path] - return h, ok - } - return nil, false -} - -// ConsumersFor gets the consumers for the specified media types -func (d *API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { - result := make(map[string]runtime.Consumer) - for _, mt := range mediaTypes { - if consumer, ok := d.consumers[mt]; ok { - result[mt] = consumer - } - } - return result -} - -// ProducersFor gets the producers for the specified media types -func (d *API) ProducersFor(mediaTypes []string) map[string]runtime.Producer { - result := make(map[string]runtime.Producer) - for _, mt := range mediaTypes { - if producer, ok := d.producers[mt]; ok { - result[mt] = producer - } - } - return result -} - -// AuthenticatorsFor gets the authenticators for the specified security schemes -func (d *API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { - result := make(map[string]runtime.Authenticator) - for k := range schemes { - if a, ok := d.authenticators[k]; ok { - result[k] = a - } - } - return result -} - -// Authorizer returns the registered authorizer -func (d *API) Authorizer() runtime.Authorizer { - return d.authorizer -} - -// Validate validates this API for any missing items -func (d *API) Validate() error { - return d.validate() -} - -// validateWith validates the registrations in this API against the provided spec analyzer -func (d *API) validate() error { - consumes := make([]string, 0, len(d.consumers)) - for k := range d.consumers { - consumes = append(consumes, k) - } - - produces := make([]string, 0, len(d.producers)) - for k := range d.producers { - produces = append(produces, k) - } - - authenticators := make([]string, 0, len(d.authenticators)) - for k := range d.authenticators { - authenticators = append(authenticators, k) - } - - operations := make([]string, 0, len(d.operations)) - for m, v := range d.operations { - for p := range v { - operations = append(operations, fmt.Sprintf("%s %s", strings.ToUpper(m), p)) - } - } - - secDefinitions := d.spec.Spec().SecurityDefinitions - definedAuths := make([]string, 0, len(secDefinitions)) - for k := range secDefinitions { - definedAuths = append(definedAuths, k) - } - - if err := d.verify("consumes", consumes, d.analyzer.RequiredConsumes()); err != nil { - return err - } - if err := d.verify("produces", produces, d.analyzer.RequiredProduces()); err != nil { - return err - } - if err := d.verify("operation", operations, d.analyzer.OperationMethodPaths()); err != nil { - return err - } - - requiredAuths := d.analyzer.RequiredSecuritySchemes() - if err := d.verify("auth scheme", authenticators, requiredAuths); err != nil { - return err - } - if err := d.verify("security definitions", definedAuths, requiredAuths); err != nil { - return err - } - return nil -} - -func (d *API) verify(name string, registrations []string, expectations []string) error { - sort.Strings(registrations) - sort.Strings(expectations) - - expected := map[string]struct{}{} - seen := map[string]struct{}{} - - for _, v := range expectations { - expected[v] = struct{}{} - } - - var unspecified []string - for _, v := range registrations { - seen[v] = struct{}{} - if _, ok := expected[v]; !ok { - unspecified = append(unspecified, v) - } - } - - for k := range seen { - delete(expected, k) - } - - unregistered := make([]string, 0, len(expected)) - for k := range expected { - unregistered = append(unregistered, k) - } - sort.Strings(unspecified) - sort.Strings(unregistered) - - if len(unregistered) > 0 || len(unspecified) > 0 { - return &errors.APIVerificationFailed{ - Section: name, - MissingSpecification: unspecified, - MissingRegistration: unregistered, - } - } - - return nil -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/validation.go b/vendor/github.com/go-openapi/runtime/middleware/validation.go deleted file mode 100644 index 0a5356c60..000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/validation.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package middleware - -import ( - "mime" - "net/http" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - - "github.com/go-openapi/runtime" -) - -type validation struct { - context *Context - result []error - request *http.Request - route *MatchedRoute - bound map[string]interface{} -} - -// ContentType validates the content type of a request -func validateContentType(allowed []string, actual string) error { - if len(allowed) == 0 { - return nil - } - mt, _, err := mime.ParseMediaType(actual) - if err != nil { - return errors.InvalidContentType(actual, allowed) - } - if swag.ContainsStringsCI(allowed, mt) { - return nil - } - if swag.ContainsStringsCI(allowed, "*/*") { - return nil - } - parts := strings.Split(actual, "/") - if len(parts) == 2 && swag.ContainsStringsCI(allowed, parts[0]+"/*") { - return nil - } - return errors.InvalidContentType(actual, allowed) -} - -func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *validation { - validate := &validation{ - context: ctx, - request: request, - route: route, - bound: make(map[string]interface{}), - } - validate.debugLogf("validating request %s %s", request.Method, request.URL.EscapedPath()) - - validate.contentType() - if len(validate.result) == 0 { - validate.responseFormat() - } - if len(validate.result) == 0 { - validate.parameters() - } - - return validate -} - -func (v *validation) debugLogf(format string, args ...any) { - v.context.debugLogf(format, args...) -} - -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{}) { - v.result = append(v.result, e.(error)) - } - return - } - v.result = append(v.result, result) - } -} - -func (v *validation) contentType() { - if len(v.result) == 0 && runtime.HasBody(v.request) { - v.debugLogf("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath()) - ct, _, req, err := v.context.ContentType(v.request) - if err != nil { - v.result = append(v.result, err) - } else { - v.request = req - } - - if len(v.result) == 0 { - v.debugLogf("validating content type for %q against [%s]", ct, strings.Join(v.route.Consumes, ", ")) - if err := validateContentType(v.route.Consumes, ct); err != nil { - v.result = append(v.result, err) - } - } - 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)) - } else { - v.route.Consumer = cons - } - } - } -} - -func (v *validation) responseFormat() { - // if the route provides values for Produces and no format could be identify then return an error. - // if the route does not specify values for Produces then treat request as valid since the API designer - // choose not to specify the format for responses. - if str, rCtx := v.context.ResponseFormat(v.request, v.route.Produces); str == "" && len(v.route.Produces) > 0 { - v.request = rCtx - v.result = append(v.result, errors.InvalidResponseFormat(v.request.Header.Get(runtime.HeaderAccept), v.route.Produces)) - } -} |