mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
update vendor/ dir to latest w/o heroku, moby
had to lock a lot of things in place
This commit is contained in:
5
vendor/github.com/go-openapi/runtime/.travis.yml
generated
vendored
5
vendor/github.com/go-openapi/runtime/.travis.yml
generated
vendored
@@ -1,6 +1,6 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.7.1
|
||||
- 1.8.x
|
||||
install:
|
||||
- go get -u github.com/axw/gocov/gocov
|
||||
- go get -u gopkg.in/matm/v1/gocov-html
|
||||
@@ -8,7 +8,6 @@ install:
|
||||
- go get -u github.com/stretchr/testify/assert
|
||||
- go get -u golang.org/x/net/context
|
||||
- go get -u gopkg.in/yaml.v2
|
||||
- go get -u github.com/gorilla/context
|
||||
- go get -u github.com/go-openapi/analysis
|
||||
- go get -u github.com/go-openapi/errors
|
||||
- go get -u github.com/go-openapi/loads
|
||||
@@ -21,4 +20,4 @@ after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
notifications:
|
||||
slack:
|
||||
secure: EmObnQuM9Mw8J9vpFaKKHqSMN4Wsr/A9+v7ewAD5cEhA0T1P4m7MbJMiJOhxUhj/X+BFh2DamW+P2lT8mybj5wg8wnkQ2BteKA8Tawi6f9PRw2NRheO8tAi8o/npLnlmet0kc93mn+oLuqHw36w4+j5mkOl2FghkfGiUVhwrhkCP7KXQN+3TU87e+/HzQumlJ3nsE+6terVxkH3PmaUTsS5ONaODZfuxFpfb7RsoEl3skHf6d+tr+1nViLxxly7558Nc33C+W1mr0qiEvMLZ+kJ/CpGWBJ6CUJM3jm6hNe2eMuIPwEK2hxZob8c7n22VPap4K6a0bBRoydoDXaba+2sD7Ym6ivDO/DVyL44VeBBLyIiIBylDGQdZH+6SoWm90Qe/i7tnY/T5Ao5igT8f3cfQY1c3EsTfqmlDfrhmACBmwSlgkdVBLTprHL63JMY24LWmh4jhxsmMRZhCL4dze8su1w6pLN/pD1pGHtKYCEVbdTmaM3PblNRFf12XB7qosmQsgUndH4Vq3bTbU0s1pKjeDhRyLvFzvR0TBbo0pDLEoF1A/i5GVFWa7yLZNUDudQERRh7qv/xBl2excIaQ1sV4DSVm7bAE9l6Kp+yeHQJW2uN6Y3X8wu9gB9nv9l5HBze7wh8KE6PyWAOLYYqZg9/sAtsv/2GcQqXcKFF1zcA=
|
||||
secure: EmObnQuM9Mw8J9vpFaKKHqSMN4Wsr/A9+v7ewAD5cEhA0T1P4m7MbJMiJOhxUhj/X+BFh2DamW+P2lT8mybj5wg8wnkQ2BteKA8Tawi6f9PRw2NRheO8tAi8o/npLnlmet0kc93mn+oLuqHw36w4+j5mkOl2FghkfGiUVhwrhkCP7KXQN+3TU87e+/HzQumlJ3nsE+6terVxkH3PmaUTsS5ONaODZfuxFpfb7RsoEl3skHf6d+tr+1nViLxxly7558Nc33C+W1mr0qiEvMLZ+kJ/CpGWBJ6CUJM3jm6hNe2eMuIPwEK2hxZob8c7n22VPap4K6a0bBRoydoDXaba+2sD7Ym6ivDO/DVyL44VeBBLyIiIBylDGQdZH+6SoWm90Qe/i7tnY/T5Ao5igT8f3cfQY1c3EsTfqmlDfrhmACBmwSlgkdVBLTprHL63JMY24LWmh4jhxsmMRZhCL4dze8su1w6pLN/pD1pGHtKYCEVbdTmaM3PblNRFf12XB7qosmQsgUndH4Vq3bTbU0s1pKjeDhRyLvFzvR0TBbo0pDLEoF1A/i5GVFWa7yLZNUDudQERRh7qv/xBl2excIaQ1sV4DSVm7bAE9l6Kp+yeHQJW2uN6Y3X8wu9gB9nv9l5HBze7wh8KE6PyWAOLYYqZg9/sAtsv/2GcQqXcKFF1zcA=
|
||||
|
||||
12
vendor/github.com/go-openapi/runtime/middleware/body_test.go
generated
vendored
12
vendor/github.com/go-openapi/runtime/middleware/body_test.go
generated
vendored
@@ -38,9 +38,9 @@ func TestBindRequest_BodyValidation(t *testing.T) {
|
||||
if assert.NoError(t, err) {
|
||||
req.Header.Set("Content-Type", runtime.JSONMime)
|
||||
|
||||
ri, ok := ctx.RouteInfo(req)
|
||||
ri, rCtx, ok := ctx.RouteInfo(req)
|
||||
if assert.True(t, ok) {
|
||||
|
||||
req = rCtx
|
||||
err := ctx.BindValidRequest(req, ri, rbn(func(r *http.Request, rr *MatchedRoute) error {
|
||||
defer r.Body.Close()
|
||||
var data interface{}
|
||||
@@ -65,9 +65,9 @@ func TestBindRequest_DeleteNoBody(t *testing.T) {
|
||||
if assert.NoError(t, err) {
|
||||
req.Header.Set("Accept", "*/*")
|
||||
|
||||
ri, ok := ctx.RouteInfo(req)
|
||||
ri, rCtx, ok := ctx.RouteInfo(req)
|
||||
if assert.True(t, ok) {
|
||||
|
||||
req = rCtx
|
||||
err := ctx.BindValidRequest(req, ri, rbn(func(r *http.Request, rr *MatchedRoute) error {
|
||||
return nil
|
||||
}))
|
||||
@@ -83,9 +83,9 @@ func TestBindRequest_DeleteNoBody(t *testing.T) {
|
||||
req.Header.Set("Content-Type", runtime.JSONMime)
|
||||
req.ContentLength = 1
|
||||
|
||||
ri, ok := ctx.RouteInfo(req)
|
||||
ri, rCtx, ok := ctx.RouteInfo(req)
|
||||
if assert.True(t, ok) {
|
||||
|
||||
req = rCtx
|
||||
err := ctx.BindValidRequest(req, ri, rbn(func(r *http.Request, rr *MatchedRoute) error {
|
||||
defer r.Body.Close()
|
||||
var data interface{}
|
||||
|
||||
135
vendor/github.com/go-openapi/runtime/middleware/context.go
generated
vendored
135
vendor/github.com/go-openapi/runtime/middleware/context.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
stdContext "context"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -29,7 +30,6 @@ import (
|
||||
"github.com/go-openapi/runtime/security"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/gorilla/context"
|
||||
)
|
||||
|
||||
// Debug when true turns on verbose logging
|
||||
@@ -68,7 +68,8 @@ func (fn ResponderFunc) WriteResponse(rw http.ResponseWriter, pr runtime.Produce
|
||||
}
|
||||
|
||||
// Context is a type safe wrapper around an untyped request context
|
||||
// used throughout to store request context with the gorilla context module
|
||||
// used throughout to store request context with the standard context attached
|
||||
// to the http.Request
|
||||
type Context struct {
|
||||
spec *loads.Document
|
||||
analyzer *analysis.Spec
|
||||
@@ -106,10 +107,15 @@ func newRoutableUntypedAPI(spec *loads.Document, api *untyped.API, context *Cont
|
||||
|
||||
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// lookup route info in the context
|
||||
route, _ := context.RouteInfo(r)
|
||||
route, rCtx, _ := context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
|
||||
// bind and validate the request using reflection
|
||||
bound, validation := context.BindAndValidate(r, route)
|
||||
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
|
||||
@@ -292,19 +298,23 @@ func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, b
|
||||
}
|
||||
|
||||
// ContentType gets the parsed value of a content type
|
||||
func (c *Context) ContentType(request *http.Request) (string, string, error) {
|
||||
if v, ok := context.GetOk(request, ctxContentType); ok {
|
||||
if val, ok := v.(*contentTypeValue); ok {
|
||||
return val.MediaType, val.Charset, nil
|
||||
}
|
||||
// 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 "", "", err
|
||||
return "", "", nil, err
|
||||
}
|
||||
context.Set(request, ctxContentType, &contentTypeValue{mt, cs})
|
||||
return mt, cs, nil
|
||||
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
|
||||
@@ -316,34 +326,43 @@ func (c *Context) LookupRoute(request *http.Request) (*MatchedRoute, bool) {
|
||||
}
|
||||
|
||||
// RouteInfo tries to match a route for this request
|
||||
func (c *Context) RouteInfo(request *http.Request) (*MatchedRoute, bool) {
|
||||
if v, ok := context.GetOk(request, ctxMatchedRoute); ok {
|
||||
if val, ok := v.(*MatchedRoute); ok {
|
||||
return val, ok
|
||||
}
|
||||
// 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 {
|
||||
context.Set(request, ctxMatchedRoute, route)
|
||||
return route, ok
|
||||
rCtx = stdContext.WithValue(rCtx, ctxMatchedRoute, route)
|
||||
return route, request.WithContext(rCtx), ok
|
||||
}
|
||||
|
||||
return nil, false
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
// ResponseFormat negotiates the response content type
|
||||
func (c *Context) ResponseFormat(r *http.Request, offers []string) string {
|
||||
if v, ok := context.GetOk(r, ctxResponseFormat); ok {
|
||||
if val, ok := v.(string); ok {
|
||||
return val
|
||||
}
|
||||
// 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 {
|
||||
debugLog("[%s %s] found response format %q in context", r.Method, r.URL.Path, v)
|
||||
return v, r
|
||||
}
|
||||
|
||||
format := NegotiateContentType(r, offers, "")
|
||||
if format != "" {
|
||||
context.Set(r, ctxResponseFormat, format)
|
||||
debugLog("[%s %s] set response format %q in context", r.Method, r.URL.Path, format)
|
||||
r = r.WithContext(stdContext.WithValue(rCtx, ctxResponseFormat, format))
|
||||
}
|
||||
return format
|
||||
debugLog("[%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
|
||||
@@ -352,12 +371,17 @@ func (c *Context) AllowedMethods(request *http.Request) []string {
|
||||
}
|
||||
|
||||
// Authorize authorizes the request
|
||||
func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interface{}, error) {
|
||||
// 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 || len(route.Authenticators) == 0 {
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
if v, ok := context.GetOk(request, ctxSecurityPrincipal); ok {
|
||||
return v, nil
|
||||
|
||||
var rCtx = request.Context()
|
||||
if v := rCtx.Value(ctxSecurityPrincipal); v != nil {
|
||||
return v, request, nil
|
||||
}
|
||||
|
||||
var lastError error
|
||||
@@ -372,38 +396,40 @@ func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interfa
|
||||
}
|
||||
continue
|
||||
}
|
||||
context.Set(request, ctxSecurityPrincipal, usr)
|
||||
context.Set(request, ctxSecurityScopes, route.Scopes[scheme])
|
||||
return usr, nil
|
||||
rCtx = stdContext.WithValue(rCtx, ctxSecurityPrincipal, usr)
|
||||
rCtx = stdContext.WithValue(rCtx, ctxSecurityScopes, route.Scopes[scheme])
|
||||
return usr, request.WithContext(rCtx), nil
|
||||
}
|
||||
|
||||
if lastError != nil {
|
||||
return nil, lastError
|
||||
return nil, nil, lastError
|
||||
}
|
||||
|
||||
return nil, errors.Unauthenticated("invalid credentials")
|
||||
return nil, nil, errors.Unauthenticated("invalid credentials")
|
||||
}
|
||||
|
||||
// BindAndValidate binds and validates the request
|
||||
func (c *Context) BindAndValidate(request *http.Request, matched *MatchedRoute) (interface{}, error) {
|
||||
if v, ok := context.GetOk(request, ctxBoundParams); ok {
|
||||
if val, ok := v.(*validation); ok {
|
||||
debugLog("got cached validation (valid: %t)", len(val.result) == 0)
|
||||
if len(val.result) > 0 {
|
||||
return val.bound, errors.CompositeValidationError(val.result...)
|
||||
}
|
||||
return val.bound, nil
|
||||
// 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 {
|
||||
debugLog("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)
|
||||
if result != nil {
|
||||
context.Set(request, ctxBoundParams, result)
|
||||
}
|
||||
rCtx = stdContext.WithValue(rCtx, ctxBoundParams, result)
|
||||
request = request.WithContext(rCtx)
|
||||
if len(result.result) > 0 {
|
||||
return result.bound, errors.CompositeValidationError(result.result...)
|
||||
return result.bound, request, errors.CompositeValidationError(result.result...)
|
||||
}
|
||||
debugLog("no validation errors found")
|
||||
return result.bound, nil
|
||||
return result.bound, request, nil
|
||||
}
|
||||
|
||||
// NotFound the default not found responder for when no route has been matched yet
|
||||
@@ -413,6 +439,7 @@ func (c *Context) NotFound(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 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{}) {
|
||||
debugLog("responding to %s %s with produces: %v", r.Method, r.URL.Path, produces)
|
||||
offers := []string{}
|
||||
for _, mt := range produces {
|
||||
if mt != c.api.DefaultProduces() {
|
||||
@@ -421,15 +448,17 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
}
|
||||
// the default producer is last so more specific producers take precedence
|
||||
offers = append(offers, c.api.DefaultProduces())
|
||||
debugLog("offers: %v", offers)
|
||||
|
||||
format := c.ResponseFormat(r, 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
|
||||
prod, ok := producers[format]
|
||||
if !ok {
|
||||
prods := c.api.ProducersFor([]string{c.api.DefaultProduces()})
|
||||
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
|
||||
pr, ok := prods[c.api.DefaultProduces()]
|
||||
if !ok {
|
||||
panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
|
||||
@@ -457,7 +486,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
if r.Method == "HEAD" {
|
||||
return
|
||||
}
|
||||
producers := c.api.ProducersFor(offers)
|
||||
producers := c.api.ProducersFor(normalizeOffers(offers))
|
||||
prod, ok := producers[format]
|
||||
if !ok {
|
||||
panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
|
||||
@@ -478,7 +507,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
prod, ok := producers[format]
|
||||
if !ok {
|
||||
if !ok {
|
||||
prods := c.api.ProducersFor([]string{c.api.DefaultProduces()})
|
||||
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
|
||||
pr, ok := prods[c.api.DefaultProduces()]
|
||||
if !ok {
|
||||
panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
|
||||
|
||||
155
vendor/github.com/go-openapi/runtime/middleware/context_test.go
generated
vendored
155
vendor/github.com/go-openapi/runtime/middleware/context_test.go
generated
vendored
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/internal/testing/petstore"
|
||||
"github.com/go-openapi/runtime/middleware/untyped"
|
||||
"github.com/gorilla/context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -94,42 +93,49 @@ func TestContextAuthorize(t *testing.T) {
|
||||
|
||||
request, _ := runtime.JSONRequest("GET", "/api/pets", nil)
|
||||
|
||||
v, ok := context.GetOk(request, ctxSecurityPrincipal)
|
||||
assert.False(t, ok)
|
||||
assert.Nil(t, v)
|
||||
|
||||
ri, ok := ctx.RouteInfo(request)
|
||||
ri, reqWithCtx, ok := ctx.RouteInfo(request)
|
||||
assert.True(t, ok)
|
||||
p, err := ctx.Authorize(request, ri)
|
||||
assert.NotNil(t, reqWithCtx)
|
||||
|
||||
request = reqWithCtx
|
||||
|
||||
p, reqWithCtx, err := ctx.Authorize(request, ri)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, p)
|
||||
assert.Nil(t, reqWithCtx)
|
||||
|
||||
v, ok = context.GetOk(request, ctxSecurityPrincipal)
|
||||
assert.False(t, ok)
|
||||
v := request.Context().Value(ctxSecurityPrincipal)
|
||||
assert.Nil(t, v)
|
||||
|
||||
request.SetBasicAuth("wrong", "wrong")
|
||||
p, err = ctx.Authorize(request, ri)
|
||||
p, reqWithCtx, err = ctx.Authorize(request, ri)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, p)
|
||||
assert.Nil(t, reqWithCtx)
|
||||
|
||||
v, ok = context.GetOk(request, ctxSecurityPrincipal)
|
||||
assert.False(t, ok)
|
||||
v = request.Context().Value(ctxSecurityPrincipal)
|
||||
assert.Nil(t, v)
|
||||
|
||||
request.SetBasicAuth("admin", "admin")
|
||||
p, err = ctx.Authorize(request, ri)
|
||||
p, reqWithCtx, err = ctx.Authorize(request, ri)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "admin", p)
|
||||
assert.NotNil(t, reqWithCtx)
|
||||
|
||||
v, ok = context.GetOk(request, ctxSecurityPrincipal)
|
||||
// Assign the new returned request to follow with the test
|
||||
request = reqWithCtx
|
||||
|
||||
v, ok = request.Context().Value(ctxSecurityPrincipal).(string)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "admin", v)
|
||||
|
||||
// Once the request context contains the principal the authentication
|
||||
// isn't rechecked
|
||||
request.SetBasicAuth("doesn't matter", "doesn't")
|
||||
pp, rr := ctx.Authorize(request, ri)
|
||||
pp, reqCtx, rr := ctx.Authorize(request, ri)
|
||||
assert.Equal(t, p, pp)
|
||||
assert.Equal(t, err, rr)
|
||||
assert.Equal(t, request, reqCtx)
|
||||
}
|
||||
|
||||
func TestContextNegotiateContentType(t *testing.T) {
|
||||
@@ -141,17 +147,13 @@ func TestContextNegotiateContentType(t *testing.T) {
|
||||
// request.Header.Add("Accept", "*/*")
|
||||
request.Header.Add("content-type", "text/html")
|
||||
|
||||
v, ok := context.GetOk(request, ctxBoundParams)
|
||||
assert.False(t, ok)
|
||||
v := request.Context().Value(ctxBoundParams)
|
||||
assert.Nil(t, v)
|
||||
|
||||
ri, _ := ctx.RouteInfo(request)
|
||||
ri, request, _ := ctx.RouteInfo(request)
|
||||
|
||||
res := NegotiateContentType(request, ri.Produces, "")
|
||||
assert.Equal(t, "", res)
|
||||
|
||||
res2 := NegotiateContentType(request, ri.Produces, "text/plain")
|
||||
assert.Equal(t, "text/plain", res2)
|
||||
res := NegotiateContentType(request, ri.Produces, "text/plain")
|
||||
assert.Equal(t, ri.Produces[0], res)
|
||||
}
|
||||
|
||||
func TestContextBindAndValidate(t *testing.T) {
|
||||
@@ -164,22 +166,22 @@ func TestContextBindAndValidate(t *testing.T) {
|
||||
request.Header.Add("content-type", "text/html")
|
||||
request.ContentLength = 1
|
||||
|
||||
v, ok := context.GetOk(request, ctxBoundParams)
|
||||
assert.False(t, ok)
|
||||
v := request.Context().Value(ctxBoundParams)
|
||||
assert.Nil(t, v)
|
||||
|
||||
ri, _ := ctx.RouteInfo(request)
|
||||
data, result := ctx.BindAndValidate(request, ri) // this requires a much more thorough test
|
||||
ri, request, _ := ctx.RouteInfo(request)
|
||||
data, request, result := ctx.BindAndValidate(request, ri) // this requires a much more thorough test
|
||||
assert.NotNil(t, data)
|
||||
assert.NotNil(t, result)
|
||||
|
||||
v, ok = context.GetOk(request, ctxBoundParams)
|
||||
v, ok := request.Context().Value(ctxBoundParams).(*validation)
|
||||
assert.True(t, ok)
|
||||
assert.NotNil(t, v)
|
||||
|
||||
dd, rr := ctx.BindAndValidate(request, ri)
|
||||
dd, rCtx, rr := ctx.BindAndValidate(request, ri)
|
||||
assert.Equal(t, data, dd)
|
||||
assert.Equal(t, result, rr)
|
||||
assert.Equal(t, rCtx, request)
|
||||
}
|
||||
|
||||
func TestContextRender(t *testing.T) {
|
||||
@@ -191,9 +193,9 @@ func TestContextRender(t *testing.T) {
|
||||
ctx := NewContext(spec, api, nil)
|
||||
ctx.router = DefaultRouter(spec, ctx.api)
|
||||
|
||||
request, _ := http.NewRequest("GET", "pets", nil)
|
||||
request, _ := http.NewRequest("GET", "/api/pets", nil)
|
||||
request.Header.Set(runtime.HeaderAccept, ct)
|
||||
ri, _ := ctx.RouteInfo(request)
|
||||
ri, request, _ := ctx.RouteInfo(request)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
ctx.Respond(recorder, request, []string{ct}, ri, map[string]interface{}{"name": "hello"})
|
||||
@@ -207,13 +209,15 @@ func TestContextRender(t *testing.T) {
|
||||
// recorder = httptest.NewRecorder()
|
||||
// assert.Panics(t, func() { ctx.Respond(recorder, request, []string{ct}, ri, map[int]interface{}{1: "hello"}) })
|
||||
|
||||
// Panic when route is nil and there is not a producer for the requested response format
|
||||
recorder = httptest.NewRecorder()
|
||||
request, _ = http.NewRequest("GET", "pets", nil)
|
||||
assert.Panics(t, func() { ctx.Respond(recorder, request, []string{}, ri, map[string]interface{}{"name": "hello"}) })
|
||||
request, _ = http.NewRequest("GET", "/api/pets", nil)
|
||||
request.Header.Set(runtime.HeaderAccept, "text/xml")
|
||||
assert.Panics(t, func() { ctx.Respond(recorder, request, []string{}, nil, map[string]interface{}{"name": "hello"}) })
|
||||
|
||||
request, _ = http.NewRequest("GET", "/pets", nil)
|
||||
request, _ = http.NewRequest("GET", "/api/pets", nil)
|
||||
request.Header.Set(runtime.HeaderAccept, ct)
|
||||
ri, _ = ctx.RouteInfo(request)
|
||||
ri, request, _ = ctx.RouteInfo(request)
|
||||
|
||||
recorder = httptest.NewRecorder()
|
||||
ctx.Respond(recorder, request, []string{ct}, ri, map[string]interface{}{"name": "hello"})
|
||||
@@ -233,7 +237,7 @@ func TestContextRender(t *testing.T) {
|
||||
|
||||
recorder = httptest.NewRecorder()
|
||||
request, _ = http.NewRequest("DELETE", "/api/pets/1", nil)
|
||||
ri, _ = ctx.RouteInfo(request)
|
||||
ri, request, _ = ctx.RouteInfo(request)
|
||||
ctx.Respond(recorder, request, ri.Produces, ri, nil)
|
||||
assert.Equal(t, 204, recorder.Code)
|
||||
}
|
||||
@@ -248,21 +252,21 @@ func TestContextValidResponseFormat(t *testing.T) {
|
||||
request.Header.Set(runtime.HeaderAccept, ct)
|
||||
|
||||
// check there's nothing there
|
||||
cached, ok := context.GetOk(request, ctxResponseFormat)
|
||||
cached, ok := request.Context().Value(ctxResponseFormat).(string)
|
||||
assert.False(t, ok)
|
||||
assert.Empty(t, cached)
|
||||
|
||||
// trigger the parse
|
||||
mt := ctx.ResponseFormat(request, []string{ct})
|
||||
mt, request := ctx.ResponseFormat(request, []string{ct})
|
||||
assert.Equal(t, ct, mt)
|
||||
|
||||
// check it was cached
|
||||
cached, ok = context.GetOk(request, ctxResponseFormat)
|
||||
cached, ok = request.Context().Value(ctxResponseFormat).(string)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, ct, cached)
|
||||
|
||||
// check if the cast works and fetch from cache too
|
||||
mt = ctx.ResponseFormat(request, []string{ct})
|
||||
mt, request = ctx.ResponseFormat(request, []string{ct})
|
||||
assert.Equal(t, ct, mt)
|
||||
}
|
||||
|
||||
@@ -277,22 +281,23 @@ func TestContextInvalidResponseFormat(t *testing.T) {
|
||||
request.Header.Set(runtime.HeaderAccept, ct)
|
||||
|
||||
// check there's nothing there
|
||||
cached, ok := context.GetOk(request, ctxResponseFormat)
|
||||
cached, ok := request.Context().Value(ctxResponseFormat).(string)
|
||||
assert.False(t, ok)
|
||||
assert.Empty(t, cached)
|
||||
|
||||
// trigger the parse
|
||||
mt := ctx.ResponseFormat(request, []string{other})
|
||||
mt, request := ctx.ResponseFormat(request, []string{other})
|
||||
assert.Empty(t, mt)
|
||||
|
||||
// check it was cached
|
||||
cached, ok = context.GetOk(request, ctxResponseFormat)
|
||||
cached, ok = request.Context().Value(ctxResponseFormat).(string)
|
||||
assert.False(t, ok)
|
||||
assert.Empty(t, cached)
|
||||
|
||||
// check if the cast works and fetch from cache too
|
||||
mt = ctx.ResponseFormat(request, []string{other})
|
||||
mt, rCtx := ctx.ResponseFormat(request, []string{other})
|
||||
assert.Empty(t, mt)
|
||||
assert.Equal(t, request, rCtx)
|
||||
}
|
||||
|
||||
func TestContextValidRoute(t *testing.T) {
|
||||
@@ -303,20 +308,25 @@ func TestContextValidRoute(t *testing.T) {
|
||||
request, _ := http.NewRequest("GET", "/api/pets", nil)
|
||||
|
||||
// check there's nothing there
|
||||
_, ok := context.GetOk(request, ctxMatchedRoute)
|
||||
assert.False(t, ok)
|
||||
cached := request.Context().Value(ctxMatchedRoute)
|
||||
assert.Nil(t, cached)
|
||||
|
||||
matched, ok := ctx.RouteInfo(request)
|
||||
matched, rCtx, ok := ctx.RouteInfo(request)
|
||||
assert.True(t, ok)
|
||||
assert.NotNil(t, matched)
|
||||
assert.NotNil(t, rCtx)
|
||||
assert.NotEqual(t, request, rCtx)
|
||||
|
||||
request = rCtx
|
||||
|
||||
// check it was cached
|
||||
_, ok = context.GetOk(request, ctxMatchedRoute)
|
||||
_, ok = request.Context().Value(ctxMatchedRoute).(*MatchedRoute)
|
||||
assert.True(t, ok)
|
||||
|
||||
matched, ok = ctx.RouteInfo(request)
|
||||
matched, rCtx, ok = ctx.RouteInfo(request)
|
||||
assert.True(t, ok)
|
||||
assert.NotNil(t, matched)
|
||||
assert.Equal(t, request, rCtx)
|
||||
}
|
||||
|
||||
func TestContextInvalidRoute(t *testing.T) {
|
||||
@@ -327,20 +337,22 @@ func TestContextInvalidRoute(t *testing.T) {
|
||||
request, _ := http.NewRequest("DELETE", "pets", nil)
|
||||
|
||||
// check there's nothing there
|
||||
_, ok := context.GetOk(request, ctxMatchedRoute)
|
||||
assert.False(t, ok)
|
||||
cached := request.Context().Value(ctxMatchedRoute)
|
||||
assert.Nil(t, cached)
|
||||
|
||||
matched, ok := ctx.RouteInfo(request)
|
||||
matched, rCtx, ok := ctx.RouteInfo(request)
|
||||
assert.False(t, ok)
|
||||
assert.Nil(t, matched)
|
||||
assert.Nil(t, rCtx)
|
||||
|
||||
// check it was cached
|
||||
_, ok = context.GetOk(request, ctxMatchedRoute)
|
||||
assert.False(t, ok)
|
||||
// check it was not cached
|
||||
cached = request.Context().Value(ctxMatchedRoute)
|
||||
assert.Nil(t, cached)
|
||||
|
||||
matched, ok = ctx.RouteInfo(request)
|
||||
matched, rCtx, ok = ctx.RouteInfo(request)
|
||||
assert.False(t, ok)
|
||||
assert.Nil(t, matched)
|
||||
assert.Nil(t, rCtx)
|
||||
}
|
||||
|
||||
func TestContextValidContentType(t *testing.T) {
|
||||
@@ -351,22 +363,27 @@ func TestContextValidContentType(t *testing.T) {
|
||||
request.Header.Set(runtime.HeaderContentType, ct)
|
||||
|
||||
// check there's nothing there
|
||||
_, ok := context.GetOk(request, ctxContentType)
|
||||
assert.False(t, ok)
|
||||
cached := request.Context().Value(ctxContentType)
|
||||
assert.Nil(t, cached)
|
||||
|
||||
// trigger the parse
|
||||
mt, _, err := ctx.ContentType(request)
|
||||
mt, _, rCtx, err := ctx.ContentType(request)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, ct, mt)
|
||||
assert.NotNil(t, rCtx)
|
||||
assert.NotEqual(t, request, rCtx)
|
||||
|
||||
request = rCtx
|
||||
|
||||
// check it was cached
|
||||
_, ok = context.GetOk(request, ctxContentType)
|
||||
assert.True(t, ok)
|
||||
cached = request.Context().Value(ctxContentType)
|
||||
assert.NotNil(t, cached)
|
||||
|
||||
// check if the cast works and fetch from cache too
|
||||
mt, _, err = ctx.ContentType(request)
|
||||
mt, _, rCtx, err = ctx.ContentType(request)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, ct, mt)
|
||||
assert.Equal(t, request, rCtx)
|
||||
}
|
||||
|
||||
func TestContextInvalidContentType(t *testing.T) {
|
||||
@@ -377,19 +394,21 @@ func TestContextInvalidContentType(t *testing.T) {
|
||||
request.Header.Set(runtime.HeaderContentType, ct)
|
||||
|
||||
// check there's nothing there
|
||||
_, ok := context.GetOk(request, ctxContentType)
|
||||
assert.False(t, ok)
|
||||
cached := request.Context().Value(ctxContentType)
|
||||
assert.Nil(t, cached)
|
||||
|
||||
// trigger the parse
|
||||
mt, _, err := ctx.ContentType(request)
|
||||
mt, _, rCtx, err := ctx.ContentType(request)
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, mt)
|
||||
assert.Nil(t, rCtx)
|
||||
|
||||
// check it was not cached
|
||||
_, ok = context.GetOk(request, ctxContentType)
|
||||
assert.False(t, ok)
|
||||
cached = request.Context().Value(ctxContentType)
|
||||
assert.Nil(t, cached)
|
||||
|
||||
// check if the failure continues
|
||||
_, _, err = ctx.ContentType(request)
|
||||
_, _, rCtx, err = ctx.ContentType(request)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, rCtx)
|
||||
}
|
||||
|
||||
3
vendor/github.com/go-openapi/runtime/middleware/doc.go
generated
vendored
3
vendor/github.com/go-openapi/runtime/middleware/doc.go
generated
vendored
@@ -20,13 +20,10 @@ Pseudo middleware handler
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/gorilla/context"
|
||||
)
|
||||
|
||||
func newCompleteMiddleware(ctx *Context) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
defer context.Clear(r)
|
||||
|
||||
// use context to lookup routes
|
||||
if matched, ok := ctx.RouteInfo(r); ok {
|
||||
|
||||
|
||||
43
vendor/github.com/go-openapi/runtime/middleware/header/header.go
generated
vendored
43
vendor/github.com/go-openapi/runtime/middleware/header/header.go
generated
vendored
@@ -134,9 +134,12 @@ func ParseList(header http.Header, key string) []string {
|
||||
// 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) (value string, params map[string]string) {
|
||||
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)
|
||||
s := header.Get(key)
|
||||
value, s = expectTokenSlash(s)
|
||||
if value == "" {
|
||||
return
|
||||
@@ -169,6 +172,26 @@ type AcceptSpec struct {
|
||||
Q float64
|
||||
}
|
||||
|
||||
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) (specs []AcceptSpec) {
|
||||
loop:
|
||||
@@ -183,12 +206,14 @@ loop:
|
||||
s = skipSpace(s)
|
||||
if strings.HasPrefix(s, ";") {
|
||||
s = skipSpace(s[1:])
|
||||
if !strings.HasPrefix(s, "q=") {
|
||||
continue loop
|
||||
for !strings.HasPrefix(s, "q=") && s != "" && !strings.HasPrefix(s, ",") {
|
||||
s = skipSpace(s[1:])
|
||||
}
|
||||
spec.Q, s = expectQuality(s[2:])
|
||||
if spec.Q < 0.0 {
|
||||
continue loop
|
||||
if strings.HasPrefix(s, "q=") {
|
||||
spec.Q, s = expectQuality(s[2:])
|
||||
if spec.Q < 0.0 {
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
}
|
||||
specs = append(specs, spec)
|
||||
@@ -282,14 +307,14 @@ func expectTokenOrQuoted(s string) (value string, rest string) {
|
||||
case escape:
|
||||
escape = false
|
||||
p[j] = b
|
||||
j += 1
|
||||
j++
|
||||
case b == '\\':
|
||||
escape = true
|
||||
case b == '"':
|
||||
return string(p[:j]), s[i+1:]
|
||||
default:
|
||||
p[j] = b
|
||||
j += 1
|
||||
j++
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
|
||||
13
vendor/github.com/go-openapi/runtime/middleware/negotiate.go
generated
vendored
13
vendor/github.com/go-openapi/runtime/middleware/negotiate.go
generated
vendored
@@ -48,7 +48,11 @@ func NegotiateContentType(r *http.Request, offers []string, defaultOffer string)
|
||||
bestQ := -1.0
|
||||
bestWild := 3
|
||||
specs := header.ParseAccept(r.Header, "Accept")
|
||||
for _, offer := range offers {
|
||||
for _, offer := range normalizeOffers(offers) {
|
||||
// No Accept header: just return the first offer.
|
||||
if len(specs) == 0 {
|
||||
return offer
|
||||
}
|
||||
for _, spec := range specs {
|
||||
switch {
|
||||
case spec.Q == 0.0:
|
||||
@@ -80,3 +84,10 @@ func NegotiateContentType(r *http.Request, offers []string, defaultOffer string)
|
||||
}
|
||||
return bestOffer
|
||||
}
|
||||
|
||||
func normalizeOffers(orig []string) (norm []string) {
|
||||
for _, o := range orig {
|
||||
norm = append(norm, strings.SplitN(o, ";", 2)[0])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
11
vendor/github.com/go-openapi/runtime/middleware/negotiate_test.go
generated
vendored
11
vendor/github.com/go-openapi/runtime/middleware/negotiate_test.go
generated
vendored
@@ -50,6 +50,7 @@ var negotiateContentTypeTests = []struct {
|
||||
{"text/html;q=0.5, image/png", []string{"text/html"}, "", "text/html"},
|
||||
{"text/html;q=0.5, image/png", []string{"image/png", "text/html"}, "", "image/png"},
|
||||
{"text/html;q=0.5, image/png", []string{"text/html", "image/png"}, "", "image/png"},
|
||||
{"text/html;q=0.5, image/png", []string{"text/html", "image/png"}, "", "image/png"},
|
||||
{"image/png, image/*;q=0.5", []string{"image/jpg", "image/png"}, "", "image/png"},
|
||||
{"image/png, image/*;q=0.5", []string{"image/jpg"}, "", "image/jpg"},
|
||||
{"image/png, image/*;q=0.5", []string{"image/jpg", "image/gif"}, "", "image/jpg"},
|
||||
@@ -57,6 +58,7 @@ var negotiateContentTypeTests = []struct {
|
||||
{"image/png, image/*", []string{"image/gif", "image/jpg"}, "", "image/gif"},
|
||||
{"image/png, image/*", []string{"image/gif", "image/png"}, "", "image/png"},
|
||||
{"image/png, image/*", []string{"image/png", "image/gif"}, "", "image/png"},
|
||||
{"application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.7,text/plain;version=0.0.4;q=0.3", []string{"text/plain"}, "", "text/plain"},
|
||||
}
|
||||
|
||||
func TestNegotiateContentType(t *testing.T) {
|
||||
@@ -68,3 +70,12 @@ func TestNegotiateContentType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNegotiateContentTypeNoAcceptHeader(t *testing.T) {
|
||||
r := &http.Request{Header: http.Header{}}
|
||||
offers := []string{"application/json", "text/xml"}
|
||||
actual := NegotiateContentType(r, offers, "")
|
||||
if actual != "application/json" {
|
||||
t.Errorf("NegotiateContentType(empty, %#v, empty)=%q, want %q", offers, actual, "application/json")
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/github.com/go-openapi/runtime/middleware/operation.go
generated
vendored
6
vendor/github.com/go-openapi/runtime/middleware/operation.go
generated
vendored
@@ -20,7 +20,11 @@ import "net/http"
|
||||
func NewOperationExecutor(ctx *Context) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
// use context to lookup routes
|
||||
route, _ := ctx.RouteInfo(r)
|
||||
route, rCtx, _ := ctx.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
|
||||
route.Handler.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
13
vendor/github.com/go-openapi/runtime/middleware/router.go
generated
vendored
13
vendor/github.com/go-openapi/runtime/middleware/router.go
generated
vendored
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/go-openapi/runtime/middleware/denco"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/gorilla/context"
|
||||
)
|
||||
|
||||
// RouteParam is a object to capture route params in a framework agnostic way.
|
||||
@@ -71,9 +70,8 @@ func NewRouter(ctx *Context, next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
defer context.Clear(r)
|
||||
if _, ok := ctx.RouteInfo(r); ok {
|
||||
next.ServeHTTP(rw, r)
|
||||
if _, rCtx, ok := ctx.RouteInfo(r); ok {
|
||||
next.ServeHTTP(rw, rCtx)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -184,7 +182,7 @@ func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
|
||||
debugLog("found a route for %s %s with %d parameters", method, path, len(entry.Parameters))
|
||||
var params RouteParams
|
||||
for _, p := range rp {
|
||||
v, err := url.QueryUnescape(p.Value)
|
||||
v, err := url.PathUnescape(p.Value)
|
||||
if err != nil {
|
||||
debugLog("failed to escape %q: %v", p.Value, err)
|
||||
v = p.Value
|
||||
@@ -226,6 +224,7 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
|
||||
bp = bp[:len(bp)-1]
|
||||
}
|
||||
|
||||
debugLog("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)
|
||||
@@ -244,8 +243,8 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
|
||||
Handler: handler,
|
||||
Consumes: consumes,
|
||||
Produces: produces,
|
||||
Consumers: d.api.ConsumersFor(consumes),
|
||||
Producers: d.api.ProducersFor(produces),
|
||||
Consumers: d.api.ConsumersFor(normalizeOffers(consumes)),
|
||||
Producers: d.api.ProducersFor(normalizeOffers(produces)),
|
||||
Parameters: parameters,
|
||||
Formats: d.api.Formats(),
|
||||
Binder: newUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()),
|
||||
|
||||
2
vendor/github.com/go-openapi/runtime/middleware/router_test.go
generated
vendored
2
vendor/github.com/go-openapi/runtime/middleware/router_test.go
generated
vendored
@@ -167,7 +167,7 @@ func TestRouter_EscapedPath(t *testing.T) {
|
||||
|
||||
mw.ServeHTTP(recorder, request)
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
ri, _ := context.RouteInfo(request)
|
||||
ri, _, _ := context.RouteInfo(request)
|
||||
if assert.NotNil(t, ri) {
|
||||
if assert.NotNil(t, ri.Params) {
|
||||
assert.Equal(t, "abc/def", ri.Params.Get("id"))
|
||||
|
||||
9
vendor/github.com/go-openapi/runtime/middleware/security.go
generated
vendored
9
vendor/github.com/go-openapi/runtime/middleware/security.go
generated
vendored
@@ -18,15 +18,20 @@ import "net/http"
|
||||
|
||||
func newSecureAPI(ctx *Context, next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
route, _ := ctx.RouteInfo(r)
|
||||
route, rCtx, _ := ctx.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
if route != nil && len(route.Authenticators) == 0 {
|
||||
next.ServeHTTP(rw, r)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := ctx.Authorize(r, route); err != nil {
|
||||
if _, rCtx, err := ctx.Authorize(r, route); err != nil {
|
||||
ctx.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
} else {
|
||||
r = rCtx
|
||||
}
|
||||
|
||||
next.ServeHTTP(rw, r)
|
||||
|
||||
22
vendor/github.com/go-openapi/runtime/middleware/validation.go
generated
vendored
22
vendor/github.com/go-openapi/runtime/middleware/validation.go
generated
vendored
@@ -28,12 +28,15 @@ import (
|
||||
func newValidation(ctx *Context, next http.Handler) http.Handler {
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
matched, _ := ctx.RouteInfo(r)
|
||||
matched, rCtx, _ := ctx.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
if matched == nil {
|
||||
ctx.NotFound(rw, r)
|
||||
return
|
||||
}
|
||||
_, result := ctx.BindAndValidate(r, matched)
|
||||
_, r, result := ctx.BindAndValidate(r, matched)
|
||||
|
||||
if result != nil {
|
||||
ctx.Respond(rw, r, matched.Produces, matched, result)
|
||||
@@ -75,6 +78,13 @@ func validateContentType(allowed []string, actual string) error {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -114,10 +124,13 @@ func (v *validation) parameters() {
|
||||
func (v *validation) contentType() {
|
||||
if len(v.result) == 0 && runtime.HasBody(v.request) {
|
||||
debugLog("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath())
|
||||
ct, _, err := v.context.ContentType(v.request)
|
||||
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 {
|
||||
if err := validateContentType(v.route.Consumes, ct); err != nil {
|
||||
v.result = append(v.result, err)
|
||||
@@ -135,7 +148,8 @@ func (v *validation) contentType() {
|
||||
}
|
||||
|
||||
func (v *validation) responseFormat() {
|
||||
if str := v.context.ResponseFormat(v.request, v.route.Produces); str == "" && runtime.HasBody(v.request) {
|
||||
if str, rCtx := v.context.ResponseFormat(v.request, v.route.Produces); str == "" && runtime.HasBody(v.request) {
|
||||
v.request = rCtx
|
||||
v.result = append(v.result, errors.InvalidResponseFormat(v.request.Header.Get(runtime.HeaderAccept), v.route.Produces))
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-openapi/runtime/middleware/validation_test.go
generated
vendored
2
vendor/github.com/go-openapi/runtime/middleware/validation_test.go
generated
vendored
@@ -114,6 +114,8 @@ func TestValidateContentType(t *testing.T) {
|
||||
{"text/html; charset=utf-8", []string{"application/json"}, errors.InvalidContentType("text/html; charset=utf-8", []string{"application/json"})},
|
||||
{"application(", []string{"application/json"}, errors.InvalidContentType("application(", []string{"application/json"})},
|
||||
{"application/json;char*", []string{"application/json"}, errors.InvalidContentType("application/json;char*", []string{"application/json"})},
|
||||
{"application/octet-stream", []string{"image/jpeg", "application/*"}, nil},
|
||||
{"image/png", []string{"*/*", "application/json"}, nil},
|
||||
}
|
||||
|
||||
for _, v := range data {
|
||||
|
||||
44
vendor/github.com/go-openapi/spec/expander.go
generated
vendored
44
vendor/github.com/go-openapi/spec/expander.go
generated
vendored
@@ -662,21 +662,27 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader) (*
|
||||
return &target, nil
|
||||
}
|
||||
parentRefs = append(parentRefs, target.Ref.String())
|
||||
target = *t
|
||||
if t != nil {
|
||||
target = *t
|
||||
}
|
||||
}
|
||||
|
||||
t, err := expandItems(target, parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
target = *t
|
||||
if t != nil {
|
||||
target = *t
|
||||
}
|
||||
|
||||
for i := range target.AllOf {
|
||||
t, err := expandSchema(target.AllOf[i], parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
target.AllOf[i] = *t
|
||||
if t != nil {
|
||||
target.AllOf[i] = *t
|
||||
}
|
||||
}
|
||||
for i := range target.AnyOf {
|
||||
t, err := expandSchema(target.AnyOf[i], parentRefs, resolver)
|
||||
@@ -690,35 +696,45 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader) (*
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
target.OneOf[i] = *t
|
||||
if t != nil {
|
||||
target.OneOf[i] = *t
|
||||
}
|
||||
}
|
||||
if target.Not != nil {
|
||||
t, err := expandSchema(*target.Not, parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
*target.Not = *t
|
||||
if t != nil {
|
||||
*target.Not = *t
|
||||
}
|
||||
}
|
||||
for k := range target.Properties {
|
||||
t, err := expandSchema(target.Properties[k], parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
target.Properties[k] = *t
|
||||
if t != nil {
|
||||
target.Properties[k] = *t
|
||||
}
|
||||
}
|
||||
if target.AdditionalProperties != nil && target.AdditionalProperties.Schema != nil {
|
||||
t, err := expandSchema(*target.AdditionalProperties.Schema, parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
*target.AdditionalProperties.Schema = *t
|
||||
if t != nil {
|
||||
*target.AdditionalProperties.Schema = *t
|
||||
}
|
||||
}
|
||||
for k := range target.PatternProperties {
|
||||
t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
target.PatternProperties[k] = *t
|
||||
if t != nil {
|
||||
target.PatternProperties[k] = *t
|
||||
}
|
||||
}
|
||||
for k := range target.Dependencies {
|
||||
if target.Dependencies[k].Schema != nil {
|
||||
@@ -726,7 +742,9 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader) (*
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
*target.Dependencies[k].Schema = *t
|
||||
if t != nil {
|
||||
*target.Dependencies[k].Schema = *t
|
||||
}
|
||||
}
|
||||
}
|
||||
if target.AdditionalItems != nil && target.AdditionalItems.Schema != nil {
|
||||
@@ -734,14 +752,18 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader) (*
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
*target.AdditionalItems.Schema = *t
|
||||
if t != nil {
|
||||
*target.AdditionalItems.Schema = *t
|
||||
}
|
||||
}
|
||||
for k := range target.Definitions {
|
||||
t, err := expandSchema(target.Definitions[k], parentRefs, resolver)
|
||||
if shouldStopOnError(err, resolver.options) {
|
||||
return &target, err
|
||||
}
|
||||
target.Definitions[k] = *t
|
||||
if t != nil {
|
||||
target.Definitions[k] = *t
|
||||
}
|
||||
}
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
10
vendor/github.com/go-openapi/spec/expander_test.go
generated
vendored
10
vendor/github.com/go-openapi/spec/expander_test.go
generated
vendored
@@ -214,6 +214,16 @@ func TestContinueOnErrorExpansion(t *testing.T) {
|
||||
err = ExpandSpec(testCase.Input, opts)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testCase.Input, testCase.Expected, "Should continue expanding spec when a definition can't be found.")
|
||||
|
||||
doc, err := jsonDoc("fixtures/expansion/missingItemRef.json")
|
||||
spec := new(Swagger)
|
||||
err = json.Unmarshal(doc, spec)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
err = ExpandSpec(spec, opts)
|
||||
assert.NoError(t, err)
|
||||
}, "Array of missing refs should not cause a panic, and continue to expand spec.")
|
||||
}
|
||||
|
||||
func TestIssue415(t *testing.T) {
|
||||
|
||||
31
vendor/github.com/go-openapi/spec/fixtures/expansion/missingItemRef.json
generated
vendored
Normal file
31
vendor/github.com/go-openapi/spec/fixtures/expansion/missingItemRef.json
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "2.1.0",
|
||||
"title": "Missing Item API"
|
||||
},
|
||||
"host": "item.com",
|
||||
"basePath": "/missing/ref",
|
||||
"schemes": [
|
||||
"http"
|
||||
],
|
||||
"paths": {
|
||||
"/employees": {
|
||||
"get": {
|
||||
"operationId": "LIST-Employees",
|
||||
"summary": "List Employee Types",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/employees-output"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
vendor/github.com/go-openapi/spec/ref.go
generated
vendored
10
vendor/github.com/go-openapi/spec/ref.go
generated
vendored
@@ -125,20 +125,12 @@ func MustCreateRef(refURI string) Ref {
|
||||
return Ref{Ref: jsonreference.MustCreateRef(refURI)}
|
||||
}
|
||||
|
||||
// // NewResolvedRef creates a resolved ref
|
||||
// func NewResolvedRef(refURI string, data interface{}) Ref {
|
||||
// return Ref{
|
||||
// Ref: jsonreference.MustCreateRef(refURI),
|
||||
// Resolved: data,
|
||||
// }
|
||||
// }
|
||||
|
||||
// MarshalJSON marshals this ref into a JSON object
|
||||
func (r Ref) MarshalJSON() ([]byte, error) {
|
||||
str := r.String()
|
||||
if str == "" {
|
||||
if r.IsRoot() {
|
||||
return []byte(`{"$ref":"#"}`), nil
|
||||
return []byte(`{"$ref":""}`), nil
|
||||
}
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
|
||||
53
vendor/github.com/go-openapi/validate/defaulter_test.go
generated
vendored
Normal file
53
vendor/github.com/go-openapi/validate/defaulter_test.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
package validate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
var defaulterFixturesPath = filepath.Join("fixtures", "defaulting")
|
||||
|
||||
func TestDefaulter(t *testing.T) {
|
||||
fname := filepath.Join(defaulterFixturesPath, "schema.json")
|
||||
b, err := ioutil.ReadFile(fname)
|
||||
assert.NoError(t, err)
|
||||
var schema spec.Schema
|
||||
assert.NoError(t, json.Unmarshal(b, &schema))
|
||||
|
||||
err = spec.ExpandSchema(&schema, nil, nil /*new(noopResCache)*/)
|
||||
assert.NoError(t, err, fname+" should expand cleanly")
|
||||
|
||||
validator := NewSchemaValidator(&schema, nil, "", strfmt.Default)
|
||||
x := map[string]interface{}{
|
||||
"nested": map[string]interface{}{},
|
||||
"all": map[string]interface{}{},
|
||||
"any": map[string]interface{}{},
|
||||
"one": map[string]interface{}{},
|
||||
}
|
||||
t.Logf("Before: %v", x)
|
||||
r := validator.Validate(x)
|
||||
assert.False(t, r.HasErrors(), fmt.Sprintf("unexpected validation error: %v", r.AsError()))
|
||||
|
||||
r.ApplyDefaults()
|
||||
t.Logf("After: %v", x)
|
||||
var expected interface{}
|
||||
err = json.Unmarshal([]byte(`{
|
||||
"int": 42,
|
||||
"str": "Hello",
|
||||
"obj": {"foo": "bar"},
|
||||
"nested": {"inner": 7},
|
||||
"all": {"foo": 42, "bar": 42},
|
||||
"any": {"foo": 42},
|
||||
"one": {"bar": 42}
|
||||
}`), &expected)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, x)
|
||||
}
|
||||
101
vendor/github.com/go-openapi/validate/fixtures/defaulting/schema.json
generated
vendored
Normal file
101
vendor/github.com/go-openapi/validate/fixtures/defaulting/schema.json
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"properties": {
|
||||
"int": {
|
||||
"type": "integer",
|
||||
"default": 42
|
||||
},
|
||||
"str": {
|
||||
"type": "string",
|
||||
"minLength": 4,
|
||||
"default": "Hello"
|
||||
},
|
||||
"obj": {
|
||||
"type": "object",
|
||||
"default": {"foo": "bar"}
|
||||
},
|
||||
"nested": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"inner": {
|
||||
"type": "integer",
|
||||
"default": 7
|
||||
}
|
||||
}
|
||||
},
|
||||
"all": {
|
||||
"allOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "integer",
|
||||
"default": 42
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer",
|
||||
"default": 42
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"any": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "integer",
|
||||
"default": 42
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer",
|
||||
"default": 42
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"one": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": ["foo"]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer",
|
||||
"default": 42
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"not": {
|
||||
"not": {
|
||||
"type": "object",
|
||||
"default": {
|
||||
"foo": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["int", "str", "nested", "all", "any", "one"]
|
||||
}
|
||||
32
vendor/github.com/go-openapi/validate/object_validator.go
generated
vendored
32
vendor/github.com/go-openapi/validate/object_validator.go
generated
vendored
@@ -64,14 +64,6 @@ func (o *objectValidator) Validate(data interface{}) *Result {
|
||||
}
|
||||
|
||||
res := new(Result)
|
||||
if len(o.Required) > 0 {
|
||||
for _, k := range o.Required {
|
||||
if _, ok := val[k]; !ok {
|
||||
res.AddErrors(errors.Required(o.Path+"."+k, o.In))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if o.AdditionalProperties != nil && !o.AdditionalProperties.Allows {
|
||||
for k := range val {
|
||||
@@ -102,6 +94,8 @@ func (o *objectValidator) Validate(data interface{}) *Result {
|
||||
}
|
||||
}
|
||||
|
||||
createdFromDefaults := map[string]bool{}
|
||||
|
||||
for pName, pSchema := range o.Properties {
|
||||
rName := pName
|
||||
if o.Path != "" {
|
||||
@@ -109,7 +103,24 @@ func (o *objectValidator) Validate(data interface{}) *Result {
|
||||
}
|
||||
|
||||
if v, ok := val[pName]; ok {
|
||||
res.Merge(NewSchemaValidator(&pSchema, o.Root, rName, o.KnownFormats).Validate(v))
|
||||
r := NewSchemaValidator(&pSchema, o.Root, rName, o.KnownFormats).Validate(v)
|
||||
res.Merge(r)
|
||||
} else if pSchema.Default != nil {
|
||||
createdFromDefaults[pName] = true
|
||||
pName := pName // shaddow
|
||||
def := pSchema.Default
|
||||
res.Defaulters = append(res.Defaulters, DefaulterFunc(func() {
|
||||
val[pName] = def
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
if len(o.Required) > 0 {
|
||||
for _, k := range o.Required {
|
||||
if _, ok := val[k]; !ok && !createdFromDefaults[k] {
|
||||
res.AddErrors(errors.Required(o.Path+"."+k, o.In))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,9 +151,6 @@ func (o *objectValidator) validatePatternProperty(key string, value interface{},
|
||||
|
||||
res := validator.Validate(value)
|
||||
result.Merge(res)
|
||||
if res.IsValid() {
|
||||
succeededOnce = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
vendor/github.com/go-openapi/validate/result.go
generated
vendored
18
vendor/github.com/go-openapi/validate/result.go
generated
vendored
@@ -25,10 +25,21 @@ var (
|
||||
Debug = os.Getenv("SWAGGER_DEBUG") != ""
|
||||
)
|
||||
|
||||
type Defaulter interface {
|
||||
Apply()
|
||||
}
|
||||
|
||||
type DefaulterFunc func()
|
||||
|
||||
func (f DefaulterFunc) Apply() {
|
||||
f()
|
||||
}
|
||||
|
||||
// Result represents a validation result
|
||||
type Result struct {
|
||||
Errors []error
|
||||
MatchCount int
|
||||
Defaulters []Defaulter
|
||||
}
|
||||
|
||||
// Merge merges this result with the other one, preserving match counts etc
|
||||
@@ -38,6 +49,7 @@ func (r *Result) Merge(other *Result) *Result {
|
||||
}
|
||||
r.AddErrors(other.Errors...)
|
||||
r.MatchCount += other.MatchCount
|
||||
r.Defaulters = append(r.Defaulters, other.Defaulters...)
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -69,3 +81,9 @@ func (r *Result) AsError() error {
|
||||
}
|
||||
return errors.CompositeValidationError(r.Errors...)
|
||||
}
|
||||
|
||||
func (r *Result) ApplyDefaults() {
|
||||
for _, d := range r.Defaulters {
|
||||
d.Apply()
|
||||
}
|
||||
}
|
||||
|
||||
3
vendor/github.com/go-openapi/validate/schema.go
generated
vendored
3
vendor/github.com/go-openapi/validate/schema.go
generated
vendored
@@ -148,7 +148,6 @@ func (s *SchemaValidator) commonValidator() valueValidator {
|
||||
return &basicCommonValidator{
|
||||
Path: s.Path,
|
||||
In: s.in,
|
||||
Default: s.Schema.Default,
|
||||
Enum: s.Schema.Enum,
|
||||
}
|
||||
}
|
||||
@@ -184,7 +183,6 @@ func (s *SchemaValidator) stringValidator() valueValidator {
|
||||
return &stringValidator{
|
||||
Path: s.Path,
|
||||
In: s.in,
|
||||
Default: s.Schema.Default,
|
||||
MaxLength: s.Schema.MaxLength,
|
||||
MinLength: s.Schema.MinLength,
|
||||
Pattern: s.Schema.Pattern,
|
||||
@@ -195,7 +193,6 @@ func (s *SchemaValidator) formatValidator() valueValidator {
|
||||
return &formatValidator{
|
||||
Path: s.Path,
|
||||
In: s.in,
|
||||
//Default: s.Schema.Default,
|
||||
Format: s.Schema.Format,
|
||||
KnownFormats: s.KnownFormats,
|
||||
}
|
||||
|
||||
12
vendor/github.com/go-openapi/validate/schema_props.go
generated
vendored
12
vendor/github.com/go-openapi/validate/schema_props.go
generated
vendored
@@ -89,6 +89,7 @@ func (s *schemaPropsValidator) Applies(source interface{}, kind reflect.Kind) bo
|
||||
|
||||
func (s *schemaPropsValidator) Validate(data interface{}) *Result {
|
||||
mainResult := new(Result)
|
||||
var firstSuccess *Result
|
||||
if len(s.anyOfValidators) > 0 {
|
||||
var bestFailures *Result
|
||||
succeededOnce := false
|
||||
@@ -97,6 +98,9 @@ func (s *schemaPropsValidator) Validate(data interface{}) *Result {
|
||||
if result.IsValid() {
|
||||
bestFailures = nil
|
||||
succeededOnce = true
|
||||
if firstSuccess == nil {
|
||||
firstSuccess = result
|
||||
}
|
||||
break
|
||||
}
|
||||
if bestFailures == nil || result.MatchCount > bestFailures.MatchCount {
|
||||
@@ -109,11 +113,14 @@ func (s *schemaPropsValidator) Validate(data interface{}) *Result {
|
||||
}
|
||||
if bestFailures != nil {
|
||||
mainResult.Merge(bestFailures)
|
||||
} else if firstSuccess != nil {
|
||||
mainResult.Merge(firstSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.oneOfValidators) > 0 {
|
||||
var bestFailures *Result
|
||||
var firstSuccess *Result
|
||||
validated := 0
|
||||
|
||||
for _, oneOfSchema := range s.oneOfValidators {
|
||||
@@ -121,6 +128,9 @@ func (s *schemaPropsValidator) Validate(data interface{}) *Result {
|
||||
if result.IsValid() {
|
||||
validated++
|
||||
bestFailures = nil
|
||||
if firstSuccess == nil {
|
||||
firstSuccess = result
|
||||
}
|
||||
continue
|
||||
}
|
||||
if validated == 0 && (bestFailures == nil || result.MatchCount > bestFailures.MatchCount) {
|
||||
@@ -133,6 +143,8 @@ func (s *schemaPropsValidator) Validate(data interface{}) *Result {
|
||||
if bestFailures != nil {
|
||||
mainResult.Merge(bestFailures)
|
||||
}
|
||||
} else if firstSuccess != nil {
|
||||
mainResult.Merge(firstSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user