diff options
author | techknowlogick <techknowlogick@gitea.io> | 2021-02-28 18:08:33 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-28 18:08:33 -0500 |
commit | 47f6a4ec3f058f69b65fb6501d6ac98994b8f8da (patch) | |
tree | 4d1421a4c836de9de4014117419c151035c17eec /vendor/github.com/go-openapi/spec | |
parent | 030646eea41e17e58e11e73b19339630b6d6148e (diff) | |
download | gitea-47f6a4ec3f058f69b65fb6501d6ac98994b8f8da.tar.gz gitea-47f6a4ec3f058f69b65fb6501d6ac98994b8f8da.zip |
go1.16 (#14783)
Diffstat (limited to 'vendor/github.com/go-openapi/spec')
-rw-r--r-- | vendor/github.com/go-openapi/spec/.golangci.yml | 3 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/README.md | 10 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/appveyor.yml | 8 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/debug.go | 12 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/errors.go | 1 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/expander.go | 91 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/go.mod | 6 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/go.sum | 19 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/normalizer.go | 264 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/normalizer_nonwindows.go | 43 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/normalizer_windows.go | 154 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/resolver.go | 29 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/schema_loader.go | 94 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/security_scheme.go | 4 | ||||
-rw-r--r-- | vendor/github.com/go-openapi/spec/unused.go | 174 |
15 files changed, 488 insertions, 424 deletions
diff --git a/vendor/github.com/go-openapi/spec/.golangci.yml b/vendor/github.com/go-openapi/spec/.golangci.yml index a5e3239799..835d55e742 100644 --- a/vendor/github.com/go-openapi/spec/.golangci.yml +++ b/vendor/github.com/go-openapi/spec/.golangci.yml @@ -37,3 +37,6 @@ linters: - godot - gofumpt - paralleltest + - tparallel + - thelper + - ifshort diff --git a/vendor/github.com/go-openapi/spec/README.md b/vendor/github.com/go-openapi/spec/README.md index 8d13b70242..18782c6daf 100644 --- a/vendor/github.com/go-openapi/spec/README.md +++ b/vendor/github.com/go-openapi/spec/README.md @@ -1,7 +1,11 @@ -# OAI object model [](https://travis-ci.org/go-openapi/spec) [](https://codecov.io/gh/go-openapi/spec) [](https://slackin.goswagger.io) +# OAI object model +[](https://travis-ci.org/go-openapi/spec) +<!-- [](https://ci.appveyor.com/project/casualjim/go-openapi/spec/branch/master) --> +[](https://codecov.io/gh/go-openapi/spec) +[](https://slackin.goswagger.io) [](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE) -[](http://godoc.org/github.com/go-openapi/spec) +[](https://pkg.go.dev/github.com/go-openapi/spec) [](https://goreportcard.com/report/github.com/go-openapi/spec) The object model for OpenAPI specification documents. @@ -11,7 +15,7 @@ The object model for OpenAPI specification documents. * What does this do? > 1. This package knows how to marshal and unmarshal Swagger API specifications into a golang object model -> 2. It knows how to resolve $ref and expand them to make a single root documment +> 2. It knows how to resolve $ref and expand them to make a single root document * How does it play with the rest of the go-openapi packages ? diff --git a/vendor/github.com/go-openapi/spec/appveyor.yml b/vendor/github.com/go-openapi/spec/appveyor.yml index e5d28bd1e4..0903593916 100644 --- a/vendor/github.com/go-openapi/spec/appveyor.yml +++ b/vendor/github.com/go-openapi/spec/appveyor.yml @@ -14,13 +14,11 @@ build: off environment: GOPATH: c:\gopath -stack: go 1.12 +stack: go 1.15 test_script: - - echo "test disabled for now" - #- go test -v -timeout 20m ./... -#artifacts: -# - path: '%GOPATH%\bin\*.exe' + - go test -v -timeout 20m ./... + deploy: off notifications: diff --git a/vendor/github.com/go-openapi/spec/debug.go b/vendor/github.com/go-openapi/spec/debug.go index 389c528ff6..fc889f6d0b 100644 --- a/vendor/github.com/go-openapi/spec/debug.go +++ b/vendor/github.com/go-openapi/spec/debug.go @@ -18,14 +18,16 @@ import ( "fmt" "log" "os" - "path/filepath" + "path" "runtime" ) +// Debug is true when the SWAGGER_DEBUG env var is not empty. +// +// It enables a more verbose logging of this package. +var Debug = os.Getenv("SWAGGER_DEBUG") != "" + var ( - // Debug is true when the SWAGGER_DEBUG env var is not empty. - // It enables a more verbose logging of this package. - Debug = os.Getenv("SWAGGER_DEBUG") != "" // specLogger is a debug logger for this package specLogger *log.Logger ) @@ -42,6 +44,6 @@ func debugLog(msg string, args ...interface{}) { // A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog() if Debug { _, file1, pos1, _ := runtime.Caller(1) - specLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...)) + specLogger.Printf("%s:%d: %s", path.Base(file1), pos1, fmt.Sprintf(msg, args...)) } } diff --git a/vendor/github.com/go-openapi/spec/errors.go b/vendor/github.com/go-openapi/spec/errors.go index 10a693a5da..6992c7ba73 100644 --- a/vendor/github.com/go-openapi/spec/errors.go +++ b/vendor/github.com/go-openapi/spec/errors.go @@ -2,6 +2,7 @@ package spec import "errors" +// Error codes var ( // ErrUnknownTypeForReference indicates that a resolved reference was found in an unsupported container type ErrUnknownTypeForReference = errors.New("unknown type for the resolved reference") diff --git a/vendor/github.com/go-openapi/spec/expander.go b/vendor/github.com/go-openapi/spec/expander.go index 8a80e2bb81..d4ea889d44 100644 --- a/vendor/github.com/go-openapi/spec/expander.go +++ b/vendor/github.com/go-openapi/spec/expander.go @@ -20,29 +20,46 @@ import ( ) // ExpandOptions provides options for the spec expander. +// +// RelativeBase is the path to the root document. This can be a remote URL or a path to a local file. +// +// If left empty, the root document is assumed to be located in the current working directory: +// all relative $ref's will be resolved from there. +// +// PathLoader injects a document loading method. By default, this resolves to the function provided by the SpecLoader package variable. +// type ExpandOptions struct { - RelativeBase string - SkipSchemas bool - ContinueOnError bool - PathLoader func(string) (json.RawMessage, error) `json:"-"` + RelativeBase string // the path to the root document to expand. This is a file, not a directory + SkipSchemas bool // do not expand schemas, just paths, parameters and responses + ContinueOnError bool // continue expanding even after and error is found + PathLoader func(string) (json.RawMessage, error) `json:"-"` // the document loading method that takes a path as input and yields a json document + AbsoluteCircularRef bool // circular $ref remaining after expansion remain absolute URLs +} - AbsoluteCircularRef bool +func optionsOrDefault(opts *ExpandOptions) *ExpandOptions { + if opts != nil { + clone := *opts // shallow clone to avoid internal changes to be propagated to the caller + if clone.RelativeBase != "" { + clone.RelativeBase = normalizeBase(clone.RelativeBase) + } + // if the relative base is empty, let the schema loader choose a pseudo root document + return &clone + } + return &ExpandOptions{} } // ExpandSpec expands the references in a swagger spec func ExpandSpec(spec *Swagger, options *ExpandOptions) error { + options = optionsOrDefault(options) resolver := defaultSchemaLoader(spec, options, nil, nil) - // getting the base path of the spec to adjust all subsequent reference resolutions - specBasePath := "" - if options != nil && options.RelativeBase != "" { - specBasePath, _ = absPath(options.RelativeBase) - } + specBasePath := options.RelativeBase - if options == nil || !options.SkipSchemas { + if !options.SkipSchemas { for key, definition := range spec.Definitions { parentRefs := make([]string, 0, 10) parentRefs = append(parentRefs, fmt.Sprintf("#/definitions/%s", key)) + def, err := expandSchema(definition, parentRefs, resolver, specBasePath) if resolver.shouldStopOnError(err) { return err @@ -94,8 +111,7 @@ func baseForRoot(root interface{}, cache ResolutionCache) string { } // cache the root document to resolve $ref's - base, _ := absPath(rootBase) - normalizedBase := normalizeAbsPath(base) + normalizedBase := normalizeBase(rootBase) cache.Set(normalizedBase, root) return normalizedBase @@ -135,15 +151,12 @@ func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *Expan cache = cacheOrDefault(cache) - var basePath string - if opts.RelativeBase != "" { - basePath, _ = absPath(opts.RelativeBase) - } + opts = optionsOrDefault(opts) resolver := defaultSchemaLoader(nil, opts, cache, nil) parentRefs := make([]string, 0, 10) - s, err := expandSchema(*schema, parentRefs, resolver, basePath) + s, err := expandSchema(*schema, parentRefs, resolver, opts.RelativeBase) if err != nil { return err } @@ -183,7 +196,7 @@ func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, bas func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { if target.Ref.String() == "" && target.Ref.IsRoot() { - newRef := normalizeFileRef(&target.Ref, basePath) + newRef := normalizeRef(&target.Ref, basePath) target.Ref = *newRef return &target, nil } @@ -315,7 +328,7 @@ func expandSchemaRef(target Schema, parentRefs []string, resolver *schemaLoader, // Ref also changes the resolution scope of children expandSchema // here the resolution scope is changed because a $ref was encountered - normalizedRef := normalizeFileRef(&target.Ref, basePath) + normalizedRef := normalizeRef(&target.Ref, basePath) normalizedBasePath := normalizedRef.RemoteURI() if resolver.isCircular(normalizedRef, basePath, parentRefs...) { @@ -325,7 +338,7 @@ func expandSchemaRef(target Schema, parentRefs []string, resolver *schemaLoader, debugLog("short circuit circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s", basePath, normalizedBasePath, normalizedRef.String()) if !resolver.options.AbsoluteCircularRef { - target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath) + target.Ref = denormalizeRef(normalizedRef, resolver.context.basePath, resolver.context.rootID) } else { target.Ref = *normalizedRef } @@ -434,9 +447,7 @@ func expandOperation(op *Operation, resolver *schemaLoader, basePath string) err func ExpandResponseWithRoot(response *Response, root interface{}, cache ResolutionCache) error { cache = cacheOrDefault(cache) opts := &ExpandOptions{ - RelativeBase: baseForRoot(root, cache), - SkipSchemas: false, - ContinueOnError: false, + RelativeBase: baseForRoot(root, cache), } resolver := defaultSchemaLoader(root, opts, cache, nil) @@ -447,13 +458,9 @@ func ExpandResponseWithRoot(response *Response, root interface{}, cache Resoluti // // All refs inside response will be resolved relative to basePath func ExpandResponse(response *Response, basePath string) error { - var specBasePath string - if basePath != "" { - specBasePath, _ = absPath(basePath) - } - opts := &ExpandOptions{ - RelativeBase: specBasePath, - } + opts := optionsOrDefault(&ExpandOptions{ + RelativeBase: basePath, + }) resolver := defaultSchemaLoader(nil, opts, nil, nil) return expandParameterOrResponse(response, resolver, opts.RelativeBase) @@ -465,10 +472,9 @@ func ExpandResponse(response *Response, basePath string) error { // (use ExpandParameter to resolve external references). func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache ResolutionCache) error { cache = cacheOrDefault(cache) + opts := &ExpandOptions{ - RelativeBase: baseForRoot(root, cache), - SkipSchemas: false, - ContinueOnError: false, + RelativeBase: baseForRoot(root, cache), } resolver := defaultSchemaLoader(root, opts, cache, nil) @@ -479,13 +485,9 @@ func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache Resol // This is the exported version of expandParameter // all refs inside parameter will be resolved relative to basePath func ExpandParameter(parameter *Parameter, basePath string) error { - var specBasePath string - if basePath != "" { - specBasePath, _ = absPath(basePath) - } - opts := &ExpandOptions{ - RelativeBase: specBasePath, - } + opts := optionsOrDefault(&ExpandOptions{ + RelativeBase: basePath, + }) resolver := defaultSchemaLoader(nil, opts, nil, nil) return expandParameterOrResponse(parameter, resolver, opts.RelativeBase) @@ -548,7 +550,7 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa } if sch.Ref.String() != "" { - rebasedRef, ern := NewRef(normalizePaths(sch.Ref.String(), basePath)) + rebasedRef, ern := NewRef(normalizeURI(sch.Ref.String(), basePath)) if ern != nil { return ern } @@ -557,16 +559,17 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa case resolver.isCircular(&rebasedRef, basePath, parentRefs...): // this is a circular $ref: stop expansion if !resolver.options.AbsoluteCircularRef { - sch.Ref = *denormalizeFileRef(&rebasedRef, basePath, resolver.context.basePath) + sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID) } else { sch.Ref = rebasedRef } case !resolver.options.SkipSchemas: // schema expanded to a $ref in another root sch.Ref = rebasedRef + debugLog("rebased to: %s", sch.Ref.String()) default: // skip schema expansion but rebase $ref to schema - sch.Ref = *denormalizeFileRef(&rebasedRef, basePath, resolver.context.basePath) + sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID) } } diff --git a/vendor/github.com/go-openapi/spec/go.mod b/vendor/github.com/go-openapi/spec/go.mod index 1717d0836c..63d9e82e99 100644 --- a/vendor/github.com/go-openapi/spec/go.mod +++ b/vendor/github.com/go-openapi/spec/go.mod @@ -3,10 +3,10 @@ module github.com/go-openapi/spec require ( github.com/go-openapi/jsonpointer v0.19.5 github.com/go-openapi/jsonreference v0.19.5 - github.com/go-openapi/swag v0.19.12 + github.com/go-openapi/swag v0.19.14 github.com/stretchr/testify v1.6.1 - golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect - golang.org/x/text v0.3.4 // indirect + golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect + golang.org/x/text v0.3.5 // indirect gopkg.in/yaml.v2 v2.4.0 ) diff --git a/vendor/github.com/go-openapi/spec/go.sum b/vendor/github.com/go-openapi/spec/go.sum index 730dddba7e..9e86ed981a 100644 --- a/vendor/github.com/go-openapi/spec/go.sum +++ b/vendor/github.com/go-openapi/spec/go.sum @@ -12,20 +12,17 @@ github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUe github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= -github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -43,8 +40,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -52,18 +49,14 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/vendor/github.com/go-openapi/spec/normalizer.go b/vendor/github.com/go-openapi/spec/normalizer.go index e9010a7d03..d6c4839712 100644 --- a/vendor/github.com/go-openapi/spec/normalizer.go +++ b/vendor/github.com/go-openapi/spec/normalizer.go @@ -15,163 +15,189 @@ package spec import ( - "fmt" "net/url" - "os" "path" - "path/filepath" - "runtime" "strings" ) -const windowsOS = "windows" +const fileScheme = "file" -// normalize absolute path for cache. -// on Windows, drive letters should be converted to lower as scheme in net/url.URL -func normalizeAbsPath(path string) string { - u, err := url.Parse(path) +// normalizeURI ensures that all $ref paths used internally by the expander are canonicalized. +// +// NOTE(windows): there is a tolerance over the strict URI format on windows. +// +// The normalizer accepts relative file URLs like 'Path\File.JSON' as well as absolute file URLs like +// 'C:\Path\file.Yaml'. +// +// Both are canonicalized with a "file://" scheme, slashes and a lower-cased path: +// 'file:///c:/path/file.yaml' +// +// URLs can be specified with a file scheme, like in 'file:///folder/file.json' or +// 'file:///c:\folder\File.json'. +// +// URLs like file://C:\folder are considered invalid (i.e. there is no host 'c:\folder') and a "repair" +// is attempted. +// +// The base path argument is assumed to be canonicalized (e.g. using normalizeBase()). +func normalizeURI(refPath, base string) string { + refURL, err := url.Parse(refPath) if err != nil { - debugLog("normalize absolute path failed: %s", err) - return path + specLogger.Printf("warning: invalid URI in $ref %q: %v", refPath, err) + refURL, refPath = repairURI(refPath) } - return u.String() -} -// base or refPath could be a file path or a URL -// given a base absolute path and a ref path, return the absolute path of refPath -// 1) if refPath is absolute, return it -// 2) if refPath is relative, join it with basePath keeping the scheme, hosts, and ports if exists -// base could be a directory or a full file path -func normalizePaths(refPath, base string) string { - refURL, _ := url.Parse(refPath) - if path.IsAbs(refURL.Path) || filepath.IsAbs(refPath) { - // refPath is actually absolute - if refURL.Host != "" { - return refPath - } - parts := strings.Split(refPath, "#") - result := filepath.FromSlash(parts[0]) - if len(parts) == 2 { - result += "#" + parts[1] - } - return result + fixWindowsURI(refURL, refPath) // noop on non-windows OS + + refURL.Path = path.Clean(refURL.Path) + if refURL.Path == "." { + refURL.Path = "" } - // relative refPath - baseURL, _ := url.Parse(base) - if !strings.HasPrefix(refPath, "#") { - // combining paths - if baseURL.Host != "" { - baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path) - } else { // base is a file - newBase := fmt.Sprintf("%s#%s", filepath.Join(filepath.Dir(base), filepath.FromSlash(refURL.Path)), refURL.Fragment) - return newBase - } + r := MustCreateRef(refURL.String()) + if r.IsCanonical() { + return refURL.String() + } + baseURL, _ := url.Parse(base) + if path.IsAbs(refURL.Path) { + baseURL.Path = refURL.Path + } else if refURL.Path != "" { + baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path) } // copying fragment from ref to base baseURL.Fragment = refURL.Fragment + return baseURL.String() } -// isRoot is a temporary hack to discern windows file ref for ref.IsRoot(). -// TODO: a more thorough change is needed to handle windows file refs. -func isRoot(ref *Ref) bool { - if runtime.GOOS != windowsOS { - return ref.IsRoot() - } - return !filepath.IsAbs(ref.String()) -} +// denormalizeRef returns the simplest notation for a normalized $ref, given the path of the original root document. +// +// When calling this, we assume that: +// * $ref is a canonical URI +// * originalRelativeBase is a canonical URI +// +// denormalizeRef is currently used when we rewrite a $ref after a circular $ref has been detected. +// In this case, expansion stops and normally renders the internal canonical $ref. +// +// This internal $ref is eventually rebased to the original RelativeBase used for the expansion. +// +// There is a special case for schemas that are anchored with an "id": +// in that case, the rebasing is performed // against the id only if this is an anchor for the initial root document. +// All other intermediate "id"'s found along the way are ignored for the purpose of rebasing. +// +func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref { + debugLog("denormalizeRef called:\n$ref: %q\noriginal: %s\nroot ID:%s", ref.String(), originalRelativeBase, id) -// isAbs is a temporary hack to discern windows file ref for url IsAbs(). -// TODO: a more thorough change is needed to handle windows file refs. -func isAbs(u *url.URL) bool { - if runtime.GOOS != windowsOS { - return u.IsAbs() + if ref.String() == "" || ref.IsRoot() || ref.HasFragmentOnly { + // short circuit: $ref to current doc + return *ref } - if len(u.Scheme) <= 1 { - // drive letter got caught as URI scheme - return false + + if id != "" { + idBaseURL, err := url.Parse(id) + if err == nil { // if the schema id is not usable as a URI, ignore it + if ref, ok := rebase(ref, idBaseURL, true); ok { // rebase, but keep references to root unchaged (do not want $ref: "") + // $ref relative to the ID of the schema in the root document + return ref + } + } } - return u.IsAbs() + + originalRelativeBaseURL, _ := url.Parse(originalRelativeBase) + + r, _ := rebase(ref, originalRelativeBaseURL, false) + + return r } -// denormalizePaths returns to simplest notation on file $ref, -// i.e. strips the absolute path and sets a path relative to the base path. -// -// This is currently used when we rewrite ref after a circular ref has been detected -func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Ref { - debugLog("denormalizeFileRef for: %s (relative: %s, original: %s)", ref.String(), - relativeBase, originalRelativeBase) +func rebase(ref *Ref, v *url.URL, notEqual bool) (Ref, bool) { + var newBase url.URL - // log.Printf("denormalize: %s, IsRoot: %t,HasFragmentOnly: %t, HasFullURL: %t", ref.String(), ref.IsRoot(), ref.HasFragmentOnly, ref.HasFullURL) - if ref.String() == "" || isRoot(ref) || ref.HasFragmentOnly { - return ref - } - // strip relativeBase from URI - relativeBaseURL, _ := url.Parse(relativeBase) - relativeBaseURL.Fragment = "" - - if isAbs(relativeBaseURL) && strings.HasPrefix(ref.String(), relativeBase) { - // this should work for absolute URI (e.g. http://...): we have an exact match, just trim prefix - r, _ := NewRef(strings.TrimPrefix(ref.String(), relativeBase)) - return &r + u := ref.GetURL() + + if u.Scheme != v.Scheme || u.Host != v.Host { + return *ref, false } - if isAbs(relativeBaseURL) { - // other absolute URL get unchanged (i.e. with a non-empty scheme) - return ref + docPath := v.Path + v.Path = path.Dir(v.Path) + + if v.Path == "." { + v.Path = "" + } else if !strings.HasSuffix(v.Path, "/") { + v.Path += "/" } - // for relative file URIs: - originalRelativeBaseURL, _ := url.Parse(originalRelativeBase) - originalRelativeBaseURL.Fragment = "" - if strings.HasPrefix(ref.String(), originalRelativeBaseURL.String()) { - // the resulting ref is in the expanded spec: return a local ref - r, _ := NewRef(strings.TrimPrefix(ref.String(), originalRelativeBaseURL.String())) - return &r + newBase.Fragment = u.Fragment + + if strings.HasPrefix(u.Path, docPath) { + newBase.Path = strings.TrimPrefix(u.Path, docPath) + } else { + newBase.Path = strings.TrimPrefix(u.Path, v.Path) } - // check if we may set a relative path, considering the original base path for this spec. - // Example: - // spec is located at /mypath/spec.json - // my normalized ref points to: /mypath/item.json#/target - // expected result: item.json#/target - parts := strings.Split(ref.String(), "#") - relativePath, err := filepath.Rel(filepath.Dir(originalRelativeBaseURL.String()), parts[0]) - if err != nil { - // there is no common ancestor (e.g. different drives on windows) - // leaves the ref unchanged - return ref + if notEqual && newBase.Path == "" && newBase.Fragment == "" { + // do not want rebasing to end up in an empty $ref + return *ref, false } - if len(parts) == 2 { - relativePath += "#" + parts[1] + + if path.IsAbs(newBase.Path) { + // whenever we end up with an absolute path, specify the scheme and host + newBase.Scheme = v.Scheme + newBase.Host = v.Host } - r, _ := NewRef(relativePath) + + return MustCreateRef(newBase.String()), true +} + +// normalizeRef canonicalize a Ref, using a canonical relativeBase as its absolute anchor +func normalizeRef(ref *Ref, relativeBase string) *Ref { + r := MustCreateRef(normalizeURI(ref.String(), relativeBase)) return &r } -// relativeBase could be an ABSOLUTE file path or an ABSOLUTE URL -func normalizeFileRef(ref *Ref, relativeBase string) *Ref { - // This is important for when the reference is pointing to the root schema - if ref.String() == "" { - r, _ := NewRef(relativeBase) - return &r +// normalizeBase performs a normalization of the input base path. +// +// This always yields a canonical URI (absolute), usable for the document cache. +// +// It ensures that all further internal work on basePath may safely assume +// a non-empty, cross-platform, canonical URI (i.e. absolute). +// +// This normalization tolerates windows paths (e.g. C:\x\y\File.dat) and transform this +// in a file:// URL with lower cased drive letter and path. +// +// See also: https://en.wikipedia.org/wiki/File_URI_scheme +func normalizeBase(in string) string { + u, err := url.Parse(in) + if err != nil { + specLogger.Printf("warning: invalid URI in RelativeBase %q: %v", in, err) + u, in = repairURI(in) } - s := normalizePaths(ref.String(), relativeBase) - r, _ := NewRef(s) - return &r -} + u.Fragment = "" // any fragment in the base is irrelevant -// absPath returns the absolute path of a file -func absPath(fname string) (string, error) { - if strings.HasPrefix(fname, "http") { - return fname, nil + fixWindowsURI(u, in) // noop on non-windows OS + + u.Path = path.Clean(u.Path) + if u.Path == "." { // empty after Clean() + u.Path = "" } - if filepath.IsAbs(fname) { - return fname, nil + + if u.Scheme != "" { + if path.IsAbs(u.Path) || u.Scheme != fileScheme { + // this is absolute or explicitly not a local file: we're good + return u.String() + } } - wd, err := os.Getwd() - return normalizeAbsPath(filepath.Join(wd, fname)), err + + // no scheme or file scheme with relative path: assume file and make it absolute + // enforce scheme file://... with absolute path. + // + // If the input path is relative, we anchor the path to the current working directory. + // NOTE: we may end up with a host component. Leave it unchanged: e.g. file://host/folder/file.json + + u.Scheme = fileScheme + u.Path = absPath(u.Path) // platform-dependent + u.RawQuery = "" // any query component is irrelevant for a base + return u.String() } diff --git a/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go b/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go new file mode 100644 index 0000000000..c8a0645347 --- /dev/null +++ b/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go @@ -0,0 +1,43 @@ +// +build !windows + +// 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 spec + +import ( + "net/url" + "path/filepath" +) + +// absPath makes a file path absolute and compatible with a URI path component. +// +// The parameter must be a path, not an URI. +func absPath(in string) string { + anchored, err := filepath.Abs(in) + if err != nil { + specLogger.Printf("warning: could not resolve current working directory: %v", err) + return in + } + return anchored +} + +func repairURI(in string) (*url.URL, string) { + u, _ := url.Parse("") + debugLog("repaired URI: original: %q, repaired: %q", in, "") + return u, "" +} + +func fixWindowsURI(u *url.URL, in string) { +} diff --git a/vendor/github.com/go-openapi/spec/normalizer_windows.go b/vendor/github.com/go-openapi/spec/normalizer_windows.go new file mode 100644 index 0000000000..fe2d1ecd43 --- /dev/null +++ b/vendor/github.com/go-openapi/spec/normalizer_windows.go @@ -0,0 +1,154 @@ +// -build windows + +// 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 spec + +import ( + "net/url" + "os" + "path" + "path/filepath" + "strings" +) + +// absPath makes a file path absolute and compatible with a URI path component +// +// The parameter must be a path, not an URI. +func absPath(in string) string { + // NOTE(windows): filepath.Abs exhibits a special behavior on windows for empty paths. + // See https://github.com/golang/go/issues/24441 + if in == "" { + in = "." + } + + anchored, err := filepath.Abs(in) + if err != nil { + specLogger.Printf("warning: could not resolve current working directory: %v", err) + return in + } + + pth := strings.ReplaceAll(strings.ToLower(anchored), `\`, `/`) + if !strings.HasPrefix(pth, "/") { + pth = "/" + pth + } + + return path.Clean(pth) +} + +// repairURI tolerates invalid file URIs with common typos +// such as 'file://E:\folder\file', that break the regular URL parser. +// +// Adopting the same defaults as for unixes (e.g. return an empty path) would +// result into a counter-intuitive result for that case (e.g. E:\folder\file is +// eventually resolved as the current directory). The repair will detect the missing "/". +// +// Note that this only works for the file scheme. +func repairURI(in string) (*url.URL, string) { + const prefix = fileScheme + "://" + if !strings.HasPrefix(in, prefix) { + // giving up: resolve to empty path + u, _ := url.Parse("") + + return u, "" + } + + // attempt the repair, stripping the scheme should be sufficient + u, _ := url.Parse(strings.TrimPrefix(in, prefix)) + debugLog("repaired URI: original: %q, repaired: %q", in, u.String()) + + return u, u.String() +} + +// fixWindowsURI tolerates an absolute file path on windows such as C:\Base\File.yaml or \\host\share\Base\File.yaml +// and makes it a canonical URI: file:///c:/base/file.yaml +// +// Catch 22 notes for Windows: +// +// * There may be a drive letter on windows (it is lower-cased) +// * There may be a share UNC, e.g. \\server\folder\data.xml +// * Paths are case insensitive +// * Paths may already contain slashes +// * Paths must be slashed +// +// NOTE: there is no escaping. "/" may be valid separators just like "\". +// We don't use ToSlash() (which escapes everything) because windows now also +// tolerates the use of "/". Hence, both C:\File.yaml and C:/File.yaml will work. +func fixWindowsURI(u *url.URL, in string) { + drive := filepath.VolumeName(in) + + if len(drive) > 0 { + if len(u.Scheme) == 1 && strings.EqualFold(u.Scheme, drive[:1]) { // a path with a drive letter + u.Scheme = fileScheme + u.Host = "" + u.Path = strings.Join([]string{drive, u.Opaque, u.Path}, `/`) // reconstruct the full path component (no fragment, no query) + } else if u.Host == "" && strings.HasPrefix(u.Path, drive) { // a path with a \\host volume + // NOTE: the special host@port syntax for UNC is not supported (yet) + u.Scheme = fileScheme + + // this is a modified version of filepath.Dir() to apply on the VolumeName itself + i := len(drive) - 1 + for i >= 0 && !os.IsPathSeparator(drive[i]) { + i-- + } + host := drive[:i] // \\host\share => host + + u.Path = strings.TrimPrefix(u.Path, host) + u.Host = strings.TrimPrefix(host, `\\`) + } + + u.Opaque = "" + u.Path = strings.ReplaceAll(strings.ToLower(u.Path), `\`, `/`) + + // ensure we form an absolute path + if !strings.HasPrefix(u.Path, "/") { + u.Path = "/" + u.Path + } + + u.Path = path.Clean(u.Path) + + return + } + + if u.Scheme == fileScheme { + // Handle dodgy cases for file://{...} URIs on windows. + // A canonical URI should always be followed by an absolute path. + // + // Examples: + // * file:///folder/file => valid, unchanged + // * file:///c:\folder\file => slashed + // * file:///./folder/file => valid, cleaned to remove the dot + // * file:///.\folder\file => remapped to cwd + // * file:///. => dodgy, remapped to / (consistent with the behavior on unix) + // * file:///.. => dodgy, remapped to / (consistent with the behavior on unix) + if (!path.IsAbs(u.Path) && !filepath.IsAbs(u.Path)) || (strings.HasPrefix(u.Path, `/.`) && strings.Contains(u.Path, `\`)) { + // ensure we form an absolute path + u.Path, _ = filepath.Abs(strings.TrimLeft(u.Path, `/`)) + if !strings.HasPrefix(u.Path, "/") { + u.Path = "/" + u.Path + } + } + u.Path = strings.ToLower(u.Path) + } + + // NOTE: lower case normalization does not propagate to inner resources, + // generated when rebasing: when joining a relative URI with a file to an absolute base, + // only the base is currently lower-cased. + // + // For now, we assume this is good enough for most use cases + // and try not to generate too many differences + // between the output produced on different platforms. + u.Path = path.Clean(strings.ReplaceAll(u.Path, `\`, `/`)) +} diff --git a/vendor/github.com/go-openapi/spec/resolver.go b/vendor/github.com/go-openapi/spec/resolver.go index 177292ad23..47d1ee13fc 100644 --- a/vendor/github.com/go-openapi/spec/resolver.go +++ b/vendor/github.com/go-openapi/spec/resolver.go @@ -1,18 +1,16 @@ package spec import ( + "fmt" + "github.com/go-openapi/swag" ) func resolveAnyWithBase(root interface{}, ref *Ref, result interface{}, options *ExpandOptions) error { + options = optionsOrDefault(options) resolver := defaultSchemaLoader(root, options, nil, nil) - basePath := "" - if options != nil && options.RelativeBase != "" { - basePath, _ = absPath(options.RelativeBase) - } - - if err := resolver.Resolve(ref, result, basePath); err != nil { + if err := resolver.Resolve(ref, result, options.RelativeBase); err != nil { return err } @@ -22,8 +20,8 @@ func resolveAnyWithBase(root interface{}, ref *Ref, result interface{}, options // ResolveRefWithBase resolves a reference against a context root with preservation of base path func ResolveRefWithBase(root interface{}, ref *Ref, options *ExpandOptions) (*Schema, error) { result := new(Schema) - err := resolveAnyWithBase(root, ref, result, options) - if err != nil { + + if err := resolveAnyWithBase(root, ref, result, options); err != nil { return nil, err } @@ -52,15 +50,15 @@ func ResolveRef(root interface{}, ref *Ref) (*Schema, error) { } return newSch, nil default: - return nil, ErrUnknownTypeForReference + return nil, fmt.Errorf("type: %T: %w", sch, ErrUnknownTypeForReference) } } // ResolveParameterWithBase resolves a parameter reference against a context root and base path func ResolveParameterWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Parameter, error) { result := new(Parameter) - err := resolveAnyWithBase(root, &ref, result, options) - if err != nil { + + if err := resolveAnyWithBase(root, &ref, result, options); err != nil { return nil, err } @@ -75,6 +73,7 @@ func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) { // ResolveResponseWithBase resolves response a reference against a context root and base path func ResolveResponseWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Response, error) { result := new(Response) + err := resolveAnyWithBase(root, &ref, result, options) if err != nil { return nil, err @@ -91,8 +90,8 @@ func ResolveResponse(root interface{}, ref Ref) (*Response, error) { // ResolvePathItemWithBase resolves response a path item against a context root and base path func ResolvePathItemWithBase(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) { result := new(PathItem) - err := resolveAnyWithBase(root, &ref, result, options) - if err != nil { + + if err := resolveAnyWithBase(root, &ref, result, options); err != nil { return nil, err } @@ -112,8 +111,8 @@ func ResolvePathItem(root interface{}, ref Ref, options *ExpandOptions) (*PathIt // Similarly, $ref are forbidden in response headers. func ResolveItemsWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) { result := new(Items) - err := resolveAnyWithBase(root, &ref, result, options) - if err != nil { + + if err := resolveAnyWithBase(root, &ref, result, options); err != nil { return nil, err } diff --git a/vendor/github.com/go-openapi/spec/schema_loader.go b/vendor/github.com/go-openapi/spec/schema_loader.go index 9ea78b5d52..0059b99aed 100644 --- a/vendor/github.com/go-openapi/spec/schema_loader.go +++ b/vendor/github.com/go-openapi/spec/schema_loader.go @@ -33,16 +33,12 @@ import ( // NOTE: if you are using the go-openapi/loads package, it will override // this value with its own default (a loader to retrieve YAML documents as // well as JSON ones). -var PathLoader func(string) (json.RawMessage, error) - -func init() { - PathLoader = func(path string) (json.RawMessage, error) { - data, err := swag.LoadFromFileOrHTTP(path) - if err != nil { - return nil, err - } - return json.RawMessage(data), nil +var PathLoader = func(pth string) (json.RawMessage, error) { + data, err := swag.LoadFromFileOrHTTP(pth) + if err != nil { + return nil, err } + return json.RawMessage(data), nil } // resolverContext allows to share a context during spec processing. @@ -55,12 +51,13 @@ type resolverContext struct { circulars map[string]bool basePath string loadDoc func(string) (json.RawMessage, error) + rootID string } -func newResolverContext(expandOptions *ExpandOptions) *resolverContext { - absBase, _ := absPath(expandOptions.RelativeBase) +func newResolverContext(options *ExpandOptions) *resolverContext { + expandOptions := optionsOrDefault(options) - // path loader may be overridden from option + // path loader may be overridden by options var loader func(string) (json.RawMessage, error) if expandOptions.PathLoader == nil { loader = PathLoader @@ -70,7 +67,7 @@ func newResolverContext(expandOptions *ExpandOptions) *resolverContext { return &resolverContext{ circulars: make(map[string]bool), - basePath: absBase, // keep the root base path in context + basePath: expandOptions.RelativeBase, // keep the root base path in context loadDoc: loader, } } @@ -88,7 +85,7 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) *schemaLoade } baseRef := MustCreateRef(basePath) - currentRef := normalizeFileRef(&ref, basePath) + currentRef := normalizeRef(&ref, basePath) if strings.HasPrefix(currentRef.String(), baseRef.String()) { return r } @@ -102,15 +99,17 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) *schemaLoade // traversing multiple documents newOptions := r.options newOptions.RelativeBase = rootURL.String() + return defaultSchemaLoader(root, newOptions, r.cache, r.context) } func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string { if transitive != r { if transitive.options != nil && transitive.options.RelativeBase != "" { - basePath, _ = absPath(transitive.options.RelativeBase) + return normalizeBase(transitive.options.RelativeBase) } } + return basePath } @@ -142,7 +141,7 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) if (ref.IsRoot() || ref.HasFragmentOnly) && root != nil { data = root } else { - baseRef := normalizeFileRef(ref, basePath) + baseRef := normalizeRef(ref, basePath) data, _, _, err = r.load(baseRef.GetURL()) if err != nil { return err @@ -166,43 +165,39 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error) var err error pth := toFetch.String() - if pth == rootBase { - pth, err = absPath(rootBase) - if err != nil { - return nil, url.URL{}, false, err - } - } - normalized := normalizeAbsPath(pth) + normalized := normalizeBase(pth) + debugLog("loading doc from: %s", normalized) data, fromCache := r.cache.Get(normalized) - if !fromCache { - b, err := r.context.loadDoc(normalized) - if err != nil { - return nil, url.URL{}, false, fmt.Errorf("%s [%s]: %w", pth, normalized, err) - } + if fromCache { + return data, toFetch, fromCache, nil + } - var doc interface{} - if err := json.Unmarshal(b, &doc); err != nil { - return nil, url.URL{}, false, err - } - r.cache.Set(normalized, doc) + b, err := r.context.loadDoc(normalized) + if err != nil { + return nil, url.URL{}, false, err + } - return doc, toFetch, fromCache, nil + var doc interface{} + if err := json.Unmarshal(b, &doc); err != nil { + return nil, url.URL{}, false, err } + r.cache.Set(normalized, doc) - return data, toFetch, fromCache, nil + return doc, toFetch, fromCache, nil } // isCircular detects cycles in sequences of $ref. +// // It relies on a private context (which needs not be locked). func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...string) (foundCycle bool) { - normalizedRef := normalizePaths(ref.String(), basePath) + normalizedRef := normalizeURI(ref.String(), basePath) if _, ok := r.context.circulars[normalizedRef]; ok { // circular $ref has been already detected in another explored cycle foundCycle = true return } - foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef) // TODO(fred): normalize windows url and remove CI equality + foundCycle = swag.ContainsStrings(parentRefs, normalizedRef) // normalized windows url's are lower cased if foundCycle { r.context.circulars[normalizedRef] = true } @@ -240,7 +235,7 @@ func (r *schemaLoader) deref(input interface{}, parentRefs []string, basePath st return nil } - normalizedRef := normalizeFileRef(ref, basePath) + normalizedRef := normalizeRef(ref, basePath) normalizedBasePath := normalizedRef.RemoteURI() if r.isCircular(normalizedRef, basePath, parentRefs...) { @@ -279,7 +274,7 @@ func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (str // remember that basePath has to point to a file var refPath string if strings.HasSuffix(id, "/") { - // path.Clean here would not work correctly if there is a scheme (e.g. https://...) + // ensure this is detected as a file, not a folder refPath = fmt.Sprintf("%s%s", id, "placeholder.json") } else { refPath = id @@ -288,11 +283,18 @@ func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (str // updates the current base path // * important: ID can be a relative path // * registers target to be fetchable from the new base proposed by this id - newBasePath := normalizePaths(refPath, basePath) + newBasePath := normalizeURI(refPath, basePath) // store found IDs for possible future reuse in $ref r.cache.Set(newBasePath, target) + // the root document has an ID: all $ref relative to that ID may + // be rebased relative to the root document + if basePath == r.context.basePath { + debugLog("root document is a schema with ID: %s (normalized as:%s)", id, newBasePath) + r.context.rootID = newBasePath + } + return newBasePath, refPath } @@ -306,6 +308,16 @@ func defaultSchemaLoader( expandOptions = &ExpandOptions{} } + cache = cacheOrDefault(cache) + + if expandOptions.RelativeBase == "" { + // if no relative base is provided, assume the root document + // contains all $ref, or at least, that the relative documents + // may be resolved from the current working directory. + expandOptions.RelativeBase = baseForRoot(root, cache) + } + debugLog("effective expander options: %#v", expandOptions) + if context == nil { context = newResolverContext(expandOptions) } @@ -313,7 +325,7 @@ func defaultSchemaLoader( return &schemaLoader{ root: root, options: expandOptions, - cache: cacheOrDefault(cache), + cache: cache, context: context, } } diff --git a/vendor/github.com/go-openapi/spec/security_scheme.go b/vendor/github.com/go-openapi/spec/security_scheme.go index f7176ef6ae..9d0bdae908 100644 --- a/vendor/github.com/go-openapi/spec/security_scheme.go +++ b/vendor/github.com/go-openapi/spec/security_scheme.go @@ -125,8 +125,8 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) { err error ) - if s.Type == oauth2 { - // when oauth2, empty AuthorizationURL is added as empty string + if s.Type == oauth2 && (s.Flow == "implicit" || s.Flow == "accessCode") { + // when oauth2 for implicit or accessCode flows, empty AuthorizationURL is added as empty string b1, err = json.Marshal(s.SecuritySchemeProps) } else { // when not oauth2, empty AuthorizationURL should be omitted diff --git a/vendor/github.com/go-openapi/spec/unused.go b/vendor/github.com/go-openapi/spec/unused.go deleted file mode 100644 index aa12b56f6e..0000000000 --- a/vendor/github.com/go-openapi/spec/unused.go +++ /dev/null @@ -1,174 +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 spec - -/* - -import ( - "net/url" - "os" - "path" - "path/filepath" - - "github.com/go-openapi/jsonpointer" -) - - // Some currently unused functions and definitions that - // used to be part of the expander. - - // Moved here for the record and possible future reuse - -var ( - idPtr, _ = jsonpointer.New("/id") - refPtr, _ = jsonpointer.New("/$ref") -) - -func idFromNode(node interface{}) (*Ref, error) { - if idValue, _, err := idPtr.Get(node); err == nil { - if refStr, ok := idValue.(string); ok && refStr != "" { - idRef, err := NewRef(refStr) - if err != nil { - return nil, err - } - return &idRef, nil - } - } - return nil, nil -} - -func nextRef(startingNode interface{}, startingRef *Ref, ptr *jsonpointer.Pointer) *Ref { - if startingRef == nil { - return nil - } - - if ptr == nil { - return startingRef - } - - ret := startingRef - var idRef *Ref - node := startingNode - - for _, tok := range ptr.DecodedTokens() { - node, _, _ = jsonpointer.GetForToken(node, tok) - if node == nil { - break - } - - idRef, _ = idFromNode(node) - if idRef != nil { - nw, err := ret.Inherits(*idRef) - if err != nil { - break - } - ret = nw - } - - refRef, _, _ := refPtr.Get(node) - if refRef != nil { - var rf Ref - switch value := refRef.(type) { - case string: - rf, _ = NewRef(value) - } - nw, err := ret.Inherits(rf) - if err != nil { - break - } - nwURL := nw.GetURL() - if nwURL.Scheme == "file" || (nwURL.Scheme == "" && nwURL.Host == "") { - nwpt := filepath.ToSlash(nwURL.Path) - if filepath.IsAbs(nwpt) { - _, err := os.Stat(nwpt) - if err != nil { - nwURL.Path = filepath.Join(".", nwpt) - } - } - } - - ret = nw - } - - } - - return ret -} - -// basePathFromSchemaID returns a new basePath based on an existing basePath and a schema ID -func basePathFromSchemaID(oldBasePath, id string) string { - u, err := url.Parse(oldBasePath) - if err != nil { - panic(err) - } - uid, err := url.Parse(id) - if err != nil { - panic(err) - } - - if path.IsAbs(uid.Path) { - return id - } - u.Path = path.Join(path.Dir(u.Path), uid.Path) - return u.String() -} -*/ - -// type ExtraSchemaProps map[string]interface{} - -// // JSONSchema represents a structure that is a json schema draft 04 -// type JSONSchema struct { -// SchemaProps -// ExtraSchemaProps -// } - -// // MarshalJSON marshal this to JSON -// func (s JSONSchema) MarshalJSON() ([]byte, error) { -// b1, err := json.Marshal(s.SchemaProps) -// if err != nil { -// return nil, err -// } -// b2, err := s.Ref.MarshalJSON() -// if err != nil { -// return nil, err -// } -// b3, err := s.Schema.MarshalJSON() -// if err != nil { -// return nil, err -// } -// b4, err := json.Marshal(s.ExtraSchemaProps) -// if err != nil { -// return nil, err -// } -// return swag.ConcatJSON(b1, b2, b3, b4), nil -// } - -// // UnmarshalJSON marshal this from JSON -// func (s *JSONSchema) UnmarshalJSON(data []byte) error { -// var sch JSONSchema -// if err := json.Unmarshal(data, &sch.SchemaProps); err != nil { -// return err -// } -// if err := json.Unmarshal(data, &sch.Ref); err != nil { -// return err -// } -// if err := json.Unmarshal(data, &sch.Schema); err != nil { -// return err -// } -// if err := json.Unmarshal(data, &sch.ExtraSchemaProps); err != nil { -// return err -// } -// *s = sch -// return nil -// } |