update prometheus dependencies (#5520)
Signed-off-by: junot <junotxiang@kubesphere.io>
This commit is contained in:
19
vendor/github.com/alecthomas/units/COPYING
generated
vendored
Normal file
19
vendor/github.com/alecthomas/units/COPYING
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2014 Alec Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
11
vendor/github.com/alecthomas/units/README.md
generated
vendored
Normal file
11
vendor/github.com/alecthomas/units/README.md
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Units - Helpful unit multipliers and functions for Go
|
||||
|
||||
The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package.
|
||||
|
||||
It allows for code like this:
|
||||
|
||||
```go
|
||||
n, err := ParseBase2Bytes("1KB")
|
||||
// n == 1024
|
||||
n = units.Mebibyte * 512
|
||||
```
|
||||
85
vendor/github.com/alecthomas/units/bytes.go
generated
vendored
Normal file
85
vendor/github.com/alecthomas/units/bytes.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
package units
|
||||
|
||||
// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte,
|
||||
// etc.).
|
||||
type Base2Bytes int64
|
||||
|
||||
// Base-2 byte units.
|
||||
const (
|
||||
Kibibyte Base2Bytes = 1024
|
||||
KiB = Kibibyte
|
||||
Mebibyte = Kibibyte * 1024
|
||||
MiB = Mebibyte
|
||||
Gibibyte = Mebibyte * 1024
|
||||
GiB = Gibibyte
|
||||
Tebibyte = Gibibyte * 1024
|
||||
TiB = Tebibyte
|
||||
Pebibyte = Tebibyte * 1024
|
||||
PiB = Pebibyte
|
||||
Exbibyte = Pebibyte * 1024
|
||||
EiB = Exbibyte
|
||||
)
|
||||
|
||||
var (
|
||||
bytesUnitMap = MakeUnitMap("iB", "B", 1024)
|
||||
oldBytesUnitMap = MakeUnitMap("B", "B", 1024)
|
||||
)
|
||||
|
||||
// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB
|
||||
// and KiB are both 1024.
|
||||
// However "kB", which is the correct SI spelling of 1000 Bytes, is rejected.
|
||||
func ParseBase2Bytes(s string) (Base2Bytes, error) {
|
||||
n, err := ParseUnit(s, bytesUnitMap)
|
||||
if err != nil {
|
||||
n, err = ParseUnit(s, oldBytesUnitMap)
|
||||
}
|
||||
return Base2Bytes(n), err
|
||||
}
|
||||
|
||||
func (b Base2Bytes) String() string {
|
||||
return ToString(int64(b), 1024, "iB", "B")
|
||||
}
|
||||
|
||||
var (
|
||||
metricBytesUnitMap = MakeUnitMap("B", "B", 1000)
|
||||
)
|
||||
|
||||
// MetricBytes are SI byte units (1000 bytes in a kilobyte).
|
||||
type MetricBytes SI
|
||||
|
||||
// SI base-10 byte units.
|
||||
const (
|
||||
Kilobyte MetricBytes = 1000
|
||||
KB = Kilobyte
|
||||
Megabyte = Kilobyte * 1000
|
||||
MB = Megabyte
|
||||
Gigabyte = Megabyte * 1000
|
||||
GB = Gigabyte
|
||||
Terabyte = Gigabyte * 1000
|
||||
TB = Terabyte
|
||||
Petabyte = Terabyte * 1000
|
||||
PB = Petabyte
|
||||
Exabyte = Petabyte * 1000
|
||||
EB = Exabyte
|
||||
)
|
||||
|
||||
// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes.
|
||||
func ParseMetricBytes(s string) (MetricBytes, error) {
|
||||
n, err := ParseUnit(s, metricBytesUnitMap)
|
||||
return MetricBytes(n), err
|
||||
}
|
||||
|
||||
// TODO: represents 1000B as uppercase "KB", while SI standard requires "kB".
|
||||
func (m MetricBytes) String() string {
|
||||
return ToString(int64(m), 1000, "B", "B")
|
||||
}
|
||||
|
||||
// ParseStrictBytes supports both iB and B suffixes for base 2 and metric,
|
||||
// respectively. That is, KiB represents 1024 and kB, KB represent 1000.
|
||||
func ParseStrictBytes(s string) (int64, error) {
|
||||
n, err := ParseUnit(s, bytesUnitMap)
|
||||
if err != nil {
|
||||
n, err = ParseUnit(s, metricBytesUnitMap)
|
||||
}
|
||||
return int64(n), err
|
||||
}
|
||||
13
vendor/github.com/alecthomas/units/doc.go
generated
vendored
Normal file
13
vendor/github.com/alecthomas/units/doc.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Package units provides helpful unit multipliers and functions for Go.
|
||||
//
|
||||
// The goal of this package is to have functionality similar to the time [1] package.
|
||||
//
|
||||
//
|
||||
// [1] http://golang.org/pkg/time/
|
||||
//
|
||||
// It allows for code like this:
|
||||
//
|
||||
// n, err := ParseBase2Bytes("1KB")
|
||||
// // n == 1024
|
||||
// n = units.Mebibyte * 512
|
||||
package units
|
||||
50
vendor/github.com/alecthomas/units/si.go
generated
vendored
Normal file
50
vendor/github.com/alecthomas/units/si.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
package units
|
||||
|
||||
// SI units.
|
||||
type SI int64
|
||||
|
||||
// SI unit multiples.
|
||||
const (
|
||||
Kilo SI = 1000
|
||||
Mega = Kilo * 1000
|
||||
Giga = Mega * 1000
|
||||
Tera = Giga * 1000
|
||||
Peta = Tera * 1000
|
||||
Exa = Peta * 1000
|
||||
)
|
||||
|
||||
func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 {
|
||||
res := map[string]float64{
|
||||
shortSuffix: 1,
|
||||
// see below for "k" / "K"
|
||||
"M" + suffix: float64(scale * scale),
|
||||
"G" + suffix: float64(scale * scale * scale),
|
||||
"T" + suffix: float64(scale * scale * scale * scale),
|
||||
"P" + suffix: float64(scale * scale * scale * scale * scale),
|
||||
"E" + suffix: float64(scale * scale * scale * scale * scale * scale),
|
||||
}
|
||||
|
||||
// Standard SI prefixes use lowercase "k" for kilo = 1000.
|
||||
// For compatibility, and to be fool-proof, we accept both "k" and "K" in metric mode.
|
||||
//
|
||||
// However, official binary prefixes are always capitalized - "KiB" -
|
||||
// and we specifically never parse "kB" as 1024B because:
|
||||
//
|
||||
// (1) people pedantic enough to use lowercase according to SI unlikely to abuse "k" to mean 1024 :-)
|
||||
//
|
||||
// (2) Use of capital K for 1024 was an informal tradition predating IEC prefixes:
|
||||
// "The binary meaning of the kilobyte for 1024 bytes typically uses the symbol KB, with an
|
||||
// uppercase letter K."
|
||||
// -- https://en.wikipedia.org/wiki/Kilobyte#Base_2_(1024_bytes)
|
||||
// "Capitalization of the letter K became the de facto standard for binary notation, although this
|
||||
// could not be extended to higher powers, and use of the lowercase k did persist.[13][14][15]"
|
||||
// -- https://en.wikipedia.org/wiki/Binary_prefix#History
|
||||
// See also the extensive https://en.wikipedia.org/wiki/Timeline_of_binary_prefixes.
|
||||
if scale == 1024 {
|
||||
res["K"+suffix] = float64(scale)
|
||||
} else {
|
||||
res["k"+suffix] = float64(scale)
|
||||
res["K"+suffix] = float64(scale)
|
||||
}
|
||||
return res
|
||||
}
|
||||
138
vendor/github.com/alecthomas/units/util.go
generated
vendored
Normal file
138
vendor/github.com/alecthomas/units/util.go
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
package units
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
siUnits = []string{"", "K", "M", "G", "T", "P", "E"}
|
||||
)
|
||||
|
||||
func ToString(n int64, scale int64, suffix, baseSuffix string) string {
|
||||
mn := len(siUnits)
|
||||
out := make([]string, mn)
|
||||
for i, m := range siUnits {
|
||||
if n%scale != 0 || i == 0 && n == 0 {
|
||||
s := suffix
|
||||
if i == 0 {
|
||||
s = baseSuffix
|
||||
}
|
||||
out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s)
|
||||
}
|
||||
n /= scale
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(out, "")
|
||||
}
|
||||
|
||||
// Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123
|
||||
var errLeadingInt = errors.New("units: bad [0-9]*") // never printed
|
||||
|
||||
// leadingInt consumes the leading [0-9]* from s.
|
||||
func leadingInt(s string) (x int64, rem string, err error) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
if x >= (1<<63-10)/10 {
|
||||
// overflow
|
||||
return 0, "", errLeadingInt
|
||||
}
|
||||
x = x*10 + int64(c) - '0'
|
||||
}
|
||||
return x, s[i:], nil
|
||||
}
|
||||
|
||||
func ParseUnit(s string, unitMap map[string]float64) (int64, error) {
|
||||
// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
|
||||
orig := s
|
||||
f := float64(0)
|
||||
neg := false
|
||||
|
||||
// Consume [-+]?
|
||||
if s != "" {
|
||||
c := s[0]
|
||||
if c == '-' || c == '+' {
|
||||
neg = c == '-'
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
// Special case: if all that is left is "0", this is zero.
|
||||
if s == "0" {
|
||||
return 0, nil
|
||||
}
|
||||
if s == "" {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
for s != "" {
|
||||
g := float64(0) // this element of the sequence
|
||||
|
||||
var x int64
|
||||
var err error
|
||||
|
||||
// The next character must be [0-9.]
|
||||
if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
// Consume [0-9]*
|
||||
pl := len(s)
|
||||
x, s, err = leadingInt(s)
|
||||
if err != nil {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
g = float64(x)
|
||||
pre := pl != len(s) // whether we consumed anything before a period
|
||||
|
||||
// Consume (\.[0-9]*)?
|
||||
post := false
|
||||
if s != "" && s[0] == '.' {
|
||||
s = s[1:]
|
||||
pl := len(s)
|
||||
x, s, err = leadingInt(s)
|
||||
if err != nil {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
scale := 1.0
|
||||
for n := pl - len(s); n > 0; n-- {
|
||||
scale *= 10
|
||||
}
|
||||
g += float64(x) / scale
|
||||
post = pl != len(s)
|
||||
}
|
||||
if !pre && !post {
|
||||
// no digits (e.g. ".s" or "-.s")
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
|
||||
// Consume unit.
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c == '.' || ('0' <= c && c <= '9') {
|
||||
break
|
||||
}
|
||||
}
|
||||
u := s[:i]
|
||||
s = s[i:]
|
||||
unit, ok := unitMap[u]
|
||||
if !ok {
|
||||
return 0, errors.New("units: unknown unit " + u + " in " + orig)
|
||||
}
|
||||
|
||||
f += g * unit
|
||||
}
|
||||
|
||||
if neg {
|
||||
f = -f
|
||||
}
|
||||
if f < float64(-1<<63) || f > float64(1<<63-1) {
|
||||
return 0, errors.New("units: overflow parsing unit")
|
||||
}
|
||||
return int64(f), nil
|
||||
}
|
||||
22
vendor/github.com/cespare/xxhash/LICENSE.txt
generated
vendored
22
vendor/github.com/cespare/xxhash/LICENSE.txt
generated
vendored
@@ -1,22 +0,0 @@
|
||||
Copyright (c) 2016 Caleb Spare
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
50
vendor/github.com/cespare/xxhash/README.md
generated
vendored
50
vendor/github.com/cespare/xxhash/README.md
generated
vendored
@@ -1,50 +0,0 @@
|
||||
# xxhash
|
||||
|
||||
[](https://godoc.org/github.com/cespare/xxhash)
|
||||
|
||||
xxhash is a Go implementation of the 64-bit
|
||||
[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
|
||||
high-quality hashing algorithm that is much faster than anything in the Go
|
||||
standard library.
|
||||
|
||||
The API is very small, taking its cue from the other hashing packages in the
|
||||
standard library:
|
||||
|
||||
$ go doc github.com/cespare/xxhash !
|
||||
package xxhash // import "github.com/cespare/xxhash"
|
||||
|
||||
Package xxhash implements the 64-bit variant of xxHash (XXH64) as described
|
||||
at http://cyan4973.github.io/xxHash/.
|
||||
|
||||
func New() hash.Hash64
|
||||
func Sum64(b []byte) uint64
|
||||
func Sum64String(s string) uint64
|
||||
|
||||
This implementation provides a fast pure-Go implementation and an even faster
|
||||
assembly implementation for amd64.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Here are some quick benchmarks comparing the pure-Go and assembly
|
||||
implementations of Sum64 against another popular Go XXH64 implementation,
|
||||
[github.com/OneOfOne/xxhash](https://github.com/OneOfOne/xxhash):
|
||||
|
||||
| input size | OneOfOne | cespare (purego) | cespare |
|
||||
| --- | --- | --- | --- |
|
||||
| 5 B | 416 MB/s | 720 MB/s | 872 MB/s |
|
||||
| 100 B | 3980 MB/s | 5013 MB/s | 5252 MB/s |
|
||||
| 4 KB | 12727 MB/s | 12999 MB/s | 13026 MB/s |
|
||||
| 10 MB | 9879 MB/s | 10775 MB/s | 10913 MB/s |
|
||||
|
||||
These numbers were generated with:
|
||||
|
||||
```
|
||||
$ go test -benchtime 10s -bench '/OneOfOne,'
|
||||
$ go test -tags purego -benchtime 10s -bench '/xxhash,'
|
||||
$ go test -benchtime 10s -bench '/xxhash,'
|
||||
```
|
||||
|
||||
## Projects using this package
|
||||
|
||||
- [InfluxDB](https://github.com/influxdata/influxdb)
|
||||
- [Prometheus](https://github.com/prometheus/prometheus)
|
||||
14
vendor/github.com/cespare/xxhash/rotate.go
generated
vendored
14
vendor/github.com/cespare/xxhash/rotate.go
generated
vendored
@@ -1,14 +0,0 @@
|
||||
// +build !go1.9
|
||||
|
||||
package xxhash
|
||||
|
||||
// TODO(caleb): After Go 1.10 comes out, remove this fallback code.
|
||||
|
||||
func rol1(x uint64) uint64 { return (x << 1) | (x >> (64 - 1)) }
|
||||
func rol7(x uint64) uint64 { return (x << 7) | (x >> (64 - 7)) }
|
||||
func rol11(x uint64) uint64 { return (x << 11) | (x >> (64 - 11)) }
|
||||
func rol12(x uint64) uint64 { return (x << 12) | (x >> (64 - 12)) }
|
||||
func rol18(x uint64) uint64 { return (x << 18) | (x >> (64 - 18)) }
|
||||
func rol23(x uint64) uint64 { return (x << 23) | (x >> (64 - 23)) }
|
||||
func rol27(x uint64) uint64 { return (x << 27) | (x >> (64 - 27)) }
|
||||
func rol31(x uint64) uint64 { return (x << 31) | (x >> (64 - 31)) }
|
||||
14
vendor/github.com/cespare/xxhash/rotate19.go
generated
vendored
14
vendor/github.com/cespare/xxhash/rotate19.go
generated
vendored
@@ -1,14 +0,0 @@
|
||||
// +build go1.9
|
||||
|
||||
package xxhash
|
||||
|
||||
import "math/bits"
|
||||
|
||||
func rol1(x uint64) uint64 { return bits.RotateLeft64(x, 1) }
|
||||
func rol7(x uint64) uint64 { return bits.RotateLeft64(x, 7) }
|
||||
func rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }
|
||||
func rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }
|
||||
func rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }
|
||||
func rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }
|
||||
func rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }
|
||||
func rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }
|
||||
168
vendor/github.com/cespare/xxhash/xxhash.go
generated
vendored
168
vendor/github.com/cespare/xxhash/xxhash.go
generated
vendored
@@ -1,168 +0,0 @@
|
||||
// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described
|
||||
// at http://cyan4973.github.io/xxHash/.
|
||||
package xxhash
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
)
|
||||
|
||||
const (
|
||||
prime1 uint64 = 11400714785074694791
|
||||
prime2 uint64 = 14029467366897019727
|
||||
prime3 uint64 = 1609587929392839161
|
||||
prime4 uint64 = 9650029242287828579
|
||||
prime5 uint64 = 2870177450012600261
|
||||
)
|
||||
|
||||
// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where
|
||||
// possible in the Go code is worth a small (but measurable) performance boost
|
||||
// by avoiding some MOVQs. Vars are needed for the asm and also are useful for
|
||||
// convenience in the Go code in a few places where we need to intentionally
|
||||
// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the
|
||||
// result overflows a uint64).
|
||||
var (
|
||||
prime1v = prime1
|
||||
prime2v = prime2
|
||||
prime3v = prime3
|
||||
prime4v = prime4
|
||||
prime5v = prime5
|
||||
)
|
||||
|
||||
type xxh struct {
|
||||
v1 uint64
|
||||
v2 uint64
|
||||
v3 uint64
|
||||
v4 uint64
|
||||
total int
|
||||
mem [32]byte
|
||||
n int // how much of mem is used
|
||||
}
|
||||
|
||||
// New creates a new hash.Hash64 that implements the 64-bit xxHash algorithm.
|
||||
func New() hash.Hash64 {
|
||||
var x xxh
|
||||
x.Reset()
|
||||
return &x
|
||||
}
|
||||
|
||||
func (x *xxh) Reset() {
|
||||
x.n = 0
|
||||
x.total = 0
|
||||
x.v1 = prime1v + prime2
|
||||
x.v2 = prime2
|
||||
x.v3 = 0
|
||||
x.v4 = -prime1v
|
||||
}
|
||||
|
||||
func (x *xxh) Size() int { return 8 }
|
||||
func (x *xxh) BlockSize() int { return 32 }
|
||||
|
||||
// Write adds more data to x. It always returns len(b), nil.
|
||||
func (x *xxh) Write(b []byte) (n int, err error) {
|
||||
n = len(b)
|
||||
x.total += len(b)
|
||||
|
||||
if x.n+len(b) < 32 {
|
||||
// This new data doesn't even fill the current block.
|
||||
copy(x.mem[x.n:], b)
|
||||
x.n += len(b)
|
||||
return
|
||||
}
|
||||
|
||||
if x.n > 0 {
|
||||
// Finish off the partial block.
|
||||
copy(x.mem[x.n:], b)
|
||||
x.v1 = round(x.v1, u64(x.mem[0:8]))
|
||||
x.v2 = round(x.v2, u64(x.mem[8:16]))
|
||||
x.v3 = round(x.v3, u64(x.mem[16:24]))
|
||||
x.v4 = round(x.v4, u64(x.mem[24:32]))
|
||||
b = b[32-x.n:]
|
||||
x.n = 0
|
||||
}
|
||||
|
||||
if len(b) >= 32 {
|
||||
// One or more full blocks left.
|
||||
b = writeBlocks(x, b)
|
||||
}
|
||||
|
||||
// Store any remaining partial block.
|
||||
copy(x.mem[:], b)
|
||||
x.n = len(b)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (x *xxh) Sum(b []byte) []byte {
|
||||
s := x.Sum64()
|
||||
return append(
|
||||
b,
|
||||
byte(s>>56),
|
||||
byte(s>>48),
|
||||
byte(s>>40),
|
||||
byte(s>>32),
|
||||
byte(s>>24),
|
||||
byte(s>>16),
|
||||
byte(s>>8),
|
||||
byte(s),
|
||||
)
|
||||
}
|
||||
|
||||
func (x *xxh) Sum64() uint64 {
|
||||
var h uint64
|
||||
|
||||
if x.total >= 32 {
|
||||
v1, v2, v3, v4 := x.v1, x.v2, x.v3, x.v4
|
||||
h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)
|
||||
h = mergeRound(h, v1)
|
||||
h = mergeRound(h, v2)
|
||||
h = mergeRound(h, v3)
|
||||
h = mergeRound(h, v4)
|
||||
} else {
|
||||
h = x.v3 + prime5
|
||||
}
|
||||
|
||||
h += uint64(x.total)
|
||||
|
||||
i, end := 0, x.n
|
||||
for ; i+8 <= end; i += 8 {
|
||||
k1 := round(0, u64(x.mem[i:i+8]))
|
||||
h ^= k1
|
||||
h = rol27(h)*prime1 + prime4
|
||||
}
|
||||
if i+4 <= end {
|
||||
h ^= uint64(u32(x.mem[i:i+4])) * prime1
|
||||
h = rol23(h)*prime2 + prime3
|
||||
i += 4
|
||||
}
|
||||
for i < end {
|
||||
h ^= uint64(x.mem[i]) * prime5
|
||||
h = rol11(h) * prime1
|
||||
i++
|
||||
}
|
||||
|
||||
h ^= h >> 33
|
||||
h *= prime2
|
||||
h ^= h >> 29
|
||||
h *= prime3
|
||||
h ^= h >> 32
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }
|
||||
func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }
|
||||
|
||||
func round(acc, input uint64) uint64 {
|
||||
acc += input * prime2
|
||||
acc = rol31(acc)
|
||||
acc *= prime1
|
||||
return acc
|
||||
}
|
||||
|
||||
func mergeRound(acc, val uint64) uint64 {
|
||||
val = round(0, val)
|
||||
acc ^= val
|
||||
acc = acc*prime1 + prime4
|
||||
return acc
|
||||
}
|
||||
12
vendor/github.com/cespare/xxhash/xxhash_amd64.go
generated
vendored
12
vendor/github.com/cespare/xxhash/xxhash_amd64.go
generated
vendored
@@ -1,12 +0,0 @@
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !purego
|
||||
|
||||
package xxhash
|
||||
|
||||
// Sum64 computes the 64-bit xxHash digest of b.
|
||||
//
|
||||
//go:noescape
|
||||
func Sum64(b []byte) uint64
|
||||
|
||||
func writeBlocks(x *xxh, b []byte) []byte
|
||||
233
vendor/github.com/cespare/xxhash/xxhash_amd64.s
generated
vendored
233
vendor/github.com/cespare/xxhash/xxhash_amd64.s
generated
vendored
@@ -1,233 +0,0 @@
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Register allocation:
|
||||
// AX h
|
||||
// CX pointer to advance through b
|
||||
// DX n
|
||||
// BX loop end
|
||||
// R8 v1, k1
|
||||
// R9 v2
|
||||
// R10 v3
|
||||
// R11 v4
|
||||
// R12 tmp
|
||||
// R13 prime1v
|
||||
// R14 prime2v
|
||||
// R15 prime4v
|
||||
|
||||
// round reads from and advances the buffer pointer in CX.
|
||||
// It assumes that R13 has prime1v and R14 has prime2v.
|
||||
#define round(r) \
|
||||
MOVQ (CX), R12 \
|
||||
ADDQ $8, CX \
|
||||
IMULQ R14, R12 \
|
||||
ADDQ R12, r \
|
||||
ROLQ $31, r \
|
||||
IMULQ R13, r
|
||||
|
||||
// mergeRound applies a merge round on the two registers acc and val.
|
||||
// It assumes that R13 has prime1v, R14 has prime2v, and R15 has prime4v.
|
||||
#define mergeRound(acc, val) \
|
||||
IMULQ R14, val \
|
||||
ROLQ $31, val \
|
||||
IMULQ R13, val \
|
||||
XORQ val, acc \
|
||||
IMULQ R13, acc \
|
||||
ADDQ R15, acc
|
||||
|
||||
// func Sum64(b []byte) uint64
|
||||
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
||||
// Load fixed primes.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
MOVQ ·prime4v(SB), R15
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+0(FP), CX
|
||||
MOVQ b_len+8(FP), DX
|
||||
LEAQ (CX)(DX*1), BX
|
||||
|
||||
// The first loop limit will be len(b)-32.
|
||||
SUBQ $32, BX
|
||||
|
||||
// Check whether we have at least one block.
|
||||
CMPQ DX, $32
|
||||
JLT noBlocks
|
||||
|
||||
// Set up initial state (v1, v2, v3, v4).
|
||||
MOVQ R13, R8
|
||||
ADDQ R14, R8
|
||||
MOVQ R14, R9
|
||||
XORQ R10, R10
|
||||
XORQ R11, R11
|
||||
SUBQ R13, R11
|
||||
|
||||
// Loop until CX > BX.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
|
||||
CMPQ CX, BX
|
||||
JLE blockLoop
|
||||
|
||||
MOVQ R8, AX
|
||||
ROLQ $1, AX
|
||||
MOVQ R9, R12
|
||||
ROLQ $7, R12
|
||||
ADDQ R12, AX
|
||||
MOVQ R10, R12
|
||||
ROLQ $12, R12
|
||||
ADDQ R12, AX
|
||||
MOVQ R11, R12
|
||||
ROLQ $18, R12
|
||||
ADDQ R12, AX
|
||||
|
||||
mergeRound(AX, R8)
|
||||
mergeRound(AX, R9)
|
||||
mergeRound(AX, R10)
|
||||
mergeRound(AX, R11)
|
||||
|
||||
JMP afterBlocks
|
||||
|
||||
noBlocks:
|
||||
MOVQ ·prime5v(SB), AX
|
||||
|
||||
afterBlocks:
|
||||
ADDQ DX, AX
|
||||
|
||||
// Right now BX has len(b)-32, and we want to loop until CX > len(b)-8.
|
||||
ADDQ $24, BX
|
||||
|
||||
CMPQ CX, BX
|
||||
JG fourByte
|
||||
|
||||
wordLoop:
|
||||
// Calculate k1.
|
||||
MOVQ (CX), R8
|
||||
ADDQ $8, CX
|
||||
IMULQ R14, R8
|
||||
ROLQ $31, R8
|
||||
IMULQ R13, R8
|
||||
|
||||
XORQ R8, AX
|
||||
ROLQ $27, AX
|
||||
IMULQ R13, AX
|
||||
ADDQ R15, AX
|
||||
|
||||
CMPQ CX, BX
|
||||
JLE wordLoop
|
||||
|
||||
fourByte:
|
||||
ADDQ $4, BX
|
||||
CMPQ CX, BX
|
||||
JG singles
|
||||
|
||||
MOVL (CX), R8
|
||||
ADDQ $4, CX
|
||||
IMULQ R13, R8
|
||||
XORQ R8, AX
|
||||
|
||||
ROLQ $23, AX
|
||||
IMULQ R14, AX
|
||||
ADDQ ·prime3v(SB), AX
|
||||
|
||||
singles:
|
||||
ADDQ $4, BX
|
||||
CMPQ CX, BX
|
||||
JGE finalize
|
||||
|
||||
singlesLoop:
|
||||
MOVBQZX (CX), R12
|
||||
ADDQ $1, CX
|
||||
IMULQ ·prime5v(SB), R12
|
||||
XORQ R12, AX
|
||||
|
||||
ROLQ $11, AX
|
||||
IMULQ R13, AX
|
||||
|
||||
CMPQ CX, BX
|
||||
JL singlesLoop
|
||||
|
||||
finalize:
|
||||
MOVQ AX, R12
|
||||
SHRQ $33, R12
|
||||
XORQ R12, AX
|
||||
IMULQ R14, AX
|
||||
MOVQ AX, R12
|
||||
SHRQ $29, R12
|
||||
XORQ R12, AX
|
||||
IMULQ ·prime3v(SB), AX
|
||||
MOVQ AX, R12
|
||||
SHRQ $32, R12
|
||||
XORQ R12, AX
|
||||
|
||||
MOVQ AX, ret+24(FP)
|
||||
RET
|
||||
|
||||
// writeBlocks uses the same registers as above except that it uses AX to store
|
||||
// the x pointer.
|
||||
|
||||
// func writeBlocks(x *xxh, b []byte) []byte
|
||||
TEXT ·writeBlocks(SB), NOSPLIT, $0-56
|
||||
// Load fixed primes needed for round.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+8(FP), CX
|
||||
MOVQ CX, ret_base+32(FP) // initialize return base pointer; see NOTE below
|
||||
MOVQ b_len+16(FP), DX
|
||||
LEAQ (CX)(DX*1), BX
|
||||
SUBQ $32, BX
|
||||
|
||||
// Load vN from x.
|
||||
MOVQ x+0(FP), AX
|
||||
MOVQ 0(AX), R8 // v1
|
||||
MOVQ 8(AX), R9 // v2
|
||||
MOVQ 16(AX), R10 // v3
|
||||
MOVQ 24(AX), R11 // v4
|
||||
|
||||
// We don't need to check the loop condition here; this function is
|
||||
// always called with at least one block of data to process.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
|
||||
CMPQ CX, BX
|
||||
JLE blockLoop
|
||||
|
||||
// Copy vN back to x.
|
||||
MOVQ R8, 0(AX)
|
||||
MOVQ R9, 8(AX)
|
||||
MOVQ R10, 16(AX)
|
||||
MOVQ R11, 24(AX)
|
||||
|
||||
// Construct return slice.
|
||||
// NOTE: It's important that we don't construct a slice that has a base
|
||||
// pointer off the end of the original slice, as in Go 1.7+ this will
|
||||
// cause runtime crashes. (See discussion in, for example,
|
||||
// https://github.com/golang/go/issues/16772.)
|
||||
// Therefore, we calculate the length/cap first, and if they're zero, we
|
||||
// keep the old base. This is what the compiler does as well if you
|
||||
// write code like
|
||||
// b = b[len(b):]
|
||||
|
||||
// New length is 32 - (CX - BX) -> BX+32 - CX.
|
||||
ADDQ $32, BX
|
||||
SUBQ CX, BX
|
||||
JZ afterSetBase
|
||||
|
||||
MOVQ CX, ret_base+32(FP)
|
||||
|
||||
afterSetBase:
|
||||
MOVQ BX, ret_len+40(FP)
|
||||
MOVQ BX, ret_cap+48(FP) // set cap == len
|
||||
|
||||
RET
|
||||
75
vendor/github.com/cespare/xxhash/xxhash_other.go
generated
vendored
75
vendor/github.com/cespare/xxhash/xxhash_other.go
generated
vendored
@@ -1,75 +0,0 @@
|
||||
// +build !amd64 appengine !gc purego
|
||||
|
||||
package xxhash
|
||||
|
||||
// Sum64 computes the 64-bit xxHash digest of b.
|
||||
func Sum64(b []byte) uint64 {
|
||||
// A simpler version would be
|
||||
// x := New()
|
||||
// x.Write(b)
|
||||
// return x.Sum64()
|
||||
// but this is faster, particularly for small inputs.
|
||||
|
||||
n := len(b)
|
||||
var h uint64
|
||||
|
||||
if n >= 32 {
|
||||
v1 := prime1v + prime2
|
||||
v2 := prime2
|
||||
v3 := uint64(0)
|
||||
v4 := -prime1v
|
||||
for len(b) >= 32 {
|
||||
v1 = round(v1, u64(b[0:8:len(b)]))
|
||||
v2 = round(v2, u64(b[8:16:len(b)]))
|
||||
v3 = round(v3, u64(b[16:24:len(b)]))
|
||||
v4 = round(v4, u64(b[24:32:len(b)]))
|
||||
b = b[32:len(b):len(b)]
|
||||
}
|
||||
h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)
|
||||
h = mergeRound(h, v1)
|
||||
h = mergeRound(h, v2)
|
||||
h = mergeRound(h, v3)
|
||||
h = mergeRound(h, v4)
|
||||
} else {
|
||||
h = prime5
|
||||
}
|
||||
|
||||
h += uint64(n)
|
||||
|
||||
i, end := 0, len(b)
|
||||
for ; i+8 <= end; i += 8 {
|
||||
k1 := round(0, u64(b[i:i+8:len(b)]))
|
||||
h ^= k1
|
||||
h = rol27(h)*prime1 + prime4
|
||||
}
|
||||
if i+4 <= end {
|
||||
h ^= uint64(u32(b[i:i+4:len(b)])) * prime1
|
||||
h = rol23(h)*prime2 + prime3
|
||||
i += 4
|
||||
}
|
||||
for ; i < end; i++ {
|
||||
h ^= uint64(b[i]) * prime5
|
||||
h = rol11(h) * prime1
|
||||
}
|
||||
|
||||
h ^= h >> 33
|
||||
h *= prime2
|
||||
h ^= h >> 29
|
||||
h *= prime3
|
||||
h ^= h >> 32
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func writeBlocks(x *xxh, b []byte) []byte {
|
||||
v1, v2, v3, v4 := x.v1, x.v2, x.v3, x.v4
|
||||
for len(b) >= 32 {
|
||||
v1 = round(v1, u64(b[0:8:len(b)]))
|
||||
v2 = round(v2, u64(b[8:16:len(b)]))
|
||||
v3 = round(v3, u64(b[16:24:len(b)]))
|
||||
v4 = round(v4, u64(b[24:32:len(b)]))
|
||||
b = b[32:len(b):len(b)]
|
||||
}
|
||||
x.v1, x.v2, x.v3, x.v4 = v1, v2, v3, v4
|
||||
return b
|
||||
}
|
||||
10
vendor/github.com/cespare/xxhash/xxhash_safe.go
generated
vendored
10
vendor/github.com/cespare/xxhash/xxhash_safe.go
generated
vendored
@@ -1,10 +0,0 @@
|
||||
// +build appengine
|
||||
|
||||
// This file contains the safe implementations of otherwise unsafe-using code.
|
||||
|
||||
package xxhash
|
||||
|
||||
// Sum64String computes the 64-bit xxHash digest of s.
|
||||
func Sum64String(s string) uint64 {
|
||||
return Sum64([]byte(s))
|
||||
}
|
||||
30
vendor/github.com/cespare/xxhash/xxhash_unsafe.go
generated
vendored
30
vendor/github.com/cespare/xxhash/xxhash_unsafe.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
// +build !appengine
|
||||
|
||||
// This file encapsulates usage of unsafe.
|
||||
// xxhash_safe.go contains the safe implementations.
|
||||
|
||||
package xxhash
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Sum64String computes the 64-bit xxHash digest of s.
|
||||
// It may be faster than Sum64([]byte(s)) by avoiding a copy.
|
||||
//
|
||||
// TODO(caleb): Consider removing this if an optimization is ever added to make
|
||||
// it unnecessary: https://golang.org/issue/2205.
|
||||
//
|
||||
// TODO(caleb): We still have a function call; we could instead write Go/asm
|
||||
// copies of Sum64 for strings to squeeze out a bit more speed.
|
||||
func Sum64String(s string) uint64 {
|
||||
// See https://groups.google.com/d/msg/golang-nuts/dcjzJy-bSpw/tcZYBzQqAQAJ
|
||||
// for some discussion about this unsafe conversion.
|
||||
var b []byte
|
||||
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
|
||||
bh.Len = len(s)
|
||||
bh.Cap = len(s)
|
||||
return Sum64(b)
|
||||
}
|
||||
2
vendor/github.com/dennwc/varint/.gitignore
generated
vendored
Normal file
2
vendor/github.com/dennwc/varint/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.o
|
||||
*.txt
|
||||
7
vendor/github.com/dennwc/varint/.travis.yml
generated
vendored
Normal file
7
vendor/github.com/dennwc/varint/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.12.x
|
||||
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
5
vendor/github.com/go-kit/kit/LICENSE → vendor/github.com/dennwc/varint/LICENSE
generated
vendored
5
vendor/github.com/go-kit/kit/LICENSE → vendor/github.com/dennwc/varint/LICENSE
generated
vendored
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 Peter Bourgon
|
||||
Copyright (c) 2019 Denys Smirnov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
47
vendor/github.com/dennwc/varint/README.md
generated
vendored
Normal file
47
vendor/github.com/dennwc/varint/README.md
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# varint
|
||||
|
||||
This package provides an optimized implementation of protobuf's varint encoding/decoding.
|
||||
It has no dependencies.
|
||||
|
||||
Benchmarks comparing to a `binary.Uvarint`:
|
||||
|
||||
```
|
||||
benchmark old ns/op new ns/op delta
|
||||
BenchmarkUvarint/1-8 4.13 2.85 -30.99%
|
||||
BenchmarkUvarint/1_large-8 4.01 2.28 -43.14%
|
||||
BenchmarkUvarint/2-8 6.23 2.87 -53.93%
|
||||
BenchmarkUvarint/2_large-8 5.60 2.86 -48.93%
|
||||
BenchmarkUvarint/3-8 6.55 3.44 -47.48%
|
||||
BenchmarkUvarint/3_large-8 6.54 2.86 -56.27%
|
||||
BenchmarkUvarint/4-8 7.30 3.71 -49.18%
|
||||
BenchmarkUvarint/4_large-8 7.46 3.10 -58.45%
|
||||
BenchmarkUvarint/5-8 8.31 4.12 -50.42%
|
||||
BenchmarkUvarint/5_large-8 8.56 3.48 -59.35%
|
||||
BenchmarkUvarint/6-8 9.42 4.66 -50.53%
|
||||
BenchmarkUvarint/6_large-8 9.91 4.07 -58.93%
|
||||
BenchmarkUvarint/7-8 10.6 5.28 -50.19%
|
||||
BenchmarkUvarint/7_large-8 11.0 4.70 -57.27%
|
||||
BenchmarkUvarint/8-8 11.7 6.02 -48.55%
|
||||
BenchmarkUvarint/8_large-8 12.1 5.19 -57.11%
|
||||
BenchmarkUvarint/9-8 12.9 6.83 -47.05%
|
||||
BenchmarkUvarint/9_large-8 13.1 5.71 -56.41%
|
||||
```
|
||||
|
||||
It also provides additional functionality like `UvarintSize` (similar to `sov*` in `gogo/protobuf`):
|
||||
|
||||
```
|
||||
benchmark old ns/op new ns/op delta
|
||||
BenchmarkUvarintSize/1-8 1.71 0.43 -74.85%
|
||||
BenchmarkUvarintSize/2-8 2.56 0.57 -77.73%
|
||||
BenchmarkUvarintSize/3-8 3.22 0.72 -77.64%
|
||||
BenchmarkUvarintSize/4-8 3.74 0.72 -80.75%
|
||||
BenchmarkUvarintSize/5-8 4.29 0.57 -86.71%
|
||||
BenchmarkUvarintSize/6-8 4.85 0.58 -88.04%
|
||||
BenchmarkUvarintSize/7-8 5.43 0.71 -86.92%
|
||||
BenchmarkUvarintSize/8-8 6.01 0.86 -85.69%
|
||||
BenchmarkUvarintSize/9-8 6.64 1.00 -84.94%
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
244
vendor/github.com/dennwc/varint/proto.go
generated
vendored
Normal file
244
vendor/github.com/dennwc/varint/proto.go
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
package varint
|
||||
|
||||
// ProtoTag decodes a protobuf's field number and wire type pair
|
||||
// from buf and returns that value and the number of bytes read (> 0).
|
||||
// If an error occurred, n = 0 is returned.
|
||||
func ProtoTag(buf []byte) (num int, typ byte, n int) {
|
||||
// Same unrolled implementation as in Uvarint.
|
||||
//
|
||||
// But this time we can check if the wire type and field num
|
||||
// are valid when reading the first byte.
|
||||
//
|
||||
// Also, the swifts are now different, because first 3 bits
|
||||
// are for the wire type.
|
||||
//
|
||||
// The implementation will stop at 9 bytes, returning an error.
|
||||
sz := len(buf)
|
||||
if sz == 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
const (
|
||||
bit = 1 << 7
|
||||
mask = bit - 1
|
||||
step = 7
|
||||
|
||||
// protobuf
|
||||
typBits = 3
|
||||
typMask = 1<<3 - 1
|
||||
)
|
||||
if sz >= 9 { // no bound checks
|
||||
// i == 0
|
||||
b := buf[0]
|
||||
if b == 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
typ = b & typMask
|
||||
if typ > 5 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
if b < bit {
|
||||
num = int(b >> typBits)
|
||||
if num == 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
n = 1
|
||||
return
|
||||
}
|
||||
num = int((b & mask) >> typBits)
|
||||
var s uint = step - typBits
|
||||
|
||||
// i == 1
|
||||
b = buf[1]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 2
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 2
|
||||
b = buf[2]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 3
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 3
|
||||
b = buf[3]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 4
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 4
|
||||
b = buf[4]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 5
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 5
|
||||
b = buf[5]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 6
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 6
|
||||
b = buf[6]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 7
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 7
|
||||
b = buf[7]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 8
|
||||
return
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 8
|
||||
b = buf[8]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 9
|
||||
return
|
||||
}
|
||||
return 0, 0, 0 // too much
|
||||
}
|
||||
|
||||
// i == 0
|
||||
b := buf[0]
|
||||
if b == 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
typ = b & typMask
|
||||
if typ > 5 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
if b < bit {
|
||||
num = int(b >> typBits)
|
||||
if num == 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
n = 1
|
||||
return
|
||||
} else if sz == 1 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num = int((b & mask) >> typBits)
|
||||
var s uint = step - typBits
|
||||
|
||||
// i == 1
|
||||
b = buf[1]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 2
|
||||
return
|
||||
} else if sz == 2 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 2
|
||||
b = buf[2]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 3
|
||||
return
|
||||
} else if sz == 3 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 3
|
||||
b = buf[3]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 4
|
||||
return
|
||||
} else if sz == 4 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 4
|
||||
b = buf[4]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 5
|
||||
return
|
||||
} else if sz == 5 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 5
|
||||
b = buf[5]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 6
|
||||
return
|
||||
} else if sz == 6 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 6
|
||||
b = buf[6]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 7
|
||||
return
|
||||
} else if sz == 7 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 7
|
||||
b = buf[7]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 8
|
||||
return
|
||||
} else if sz == 8 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
num |= int(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 8
|
||||
b = buf[8]
|
||||
if b < bit {
|
||||
num |= int(b) << s
|
||||
n = 9
|
||||
return
|
||||
}
|
||||
return 0, 0, 0 // too much
|
||||
}
|
||||
270
vendor/github.com/dennwc/varint/varint.go
generated
vendored
Normal file
270
vendor/github.com/dennwc/varint/varint.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
package varint
|
||||
|
||||
const maxUint64 = uint64(1<<64 - 1)
|
||||
|
||||
// MaxLenN is the maximum length of a varint-encoded N-bit integer.
|
||||
const (
|
||||
MaxLen8 = 2
|
||||
MaxLen16 = 3
|
||||
MaxLen32 = 5
|
||||
MaxLen64 = 10
|
||||
)
|
||||
|
||||
// MaxValN is the maximum varint-encoded integer that fits in N bytes.
|
||||
const (
|
||||
MaxVal9 = maxUint64 >> (1 + iota*7)
|
||||
MaxVal8
|
||||
MaxVal7
|
||||
MaxVal6
|
||||
MaxVal5
|
||||
MaxVal4
|
||||
MaxVal3
|
||||
MaxVal2
|
||||
MaxVal1
|
||||
)
|
||||
|
||||
// UvarintSize returns the number of bytes necessary to encode a given uint.
|
||||
func UvarintSize(x uint64) int {
|
||||
if x <= MaxVal4 {
|
||||
if x <= MaxVal1 {
|
||||
return 1
|
||||
} else if x <= MaxVal2 {
|
||||
return 2
|
||||
} else if x <= MaxVal3 {
|
||||
return 3
|
||||
}
|
||||
return 4
|
||||
}
|
||||
if x <= MaxVal5 {
|
||||
return 5
|
||||
} else if x <= MaxVal6 {
|
||||
return 6
|
||||
} else if x <= MaxVal7 {
|
||||
return 7
|
||||
} else if x <= MaxVal8 {
|
||||
return 8
|
||||
} else if x <= MaxVal9 {
|
||||
return 9
|
||||
}
|
||||
return 10
|
||||
}
|
||||
|
||||
// Uvarint decodes a uint64 from buf and returns that value and the
|
||||
// number of bytes read (> 0). If an error occurred, the value is 0
|
||||
// and the number of bytes n is <= 0 meaning:
|
||||
//
|
||||
// n == 0: buf too small
|
||||
// n < 0: value larger than 64 bits (overflow)
|
||||
// and -n is the number of bytes read
|
||||
//
|
||||
func Uvarint(buf []byte) (uint64, int) {
|
||||
// Fully unrolled implementation of binary.Uvarint.
|
||||
//
|
||||
// It will also eliminate bound checks for buffers larger than 9 bytes.
|
||||
sz := len(buf)
|
||||
if sz == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
const (
|
||||
step = 7
|
||||
bit = 1 << 7
|
||||
mask = bit - 1
|
||||
)
|
||||
if sz >= 10 { // no bound checks
|
||||
// i == 0
|
||||
b := buf[0]
|
||||
if b < bit {
|
||||
return uint64(b), 1
|
||||
}
|
||||
x := uint64(b & mask)
|
||||
var s uint = step
|
||||
|
||||
// i == 1
|
||||
b = buf[1]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 2
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 2
|
||||
b = buf[2]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 3
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 3
|
||||
b = buf[3]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 4
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 4
|
||||
b = buf[4]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 5
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 5
|
||||
b = buf[5]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 6
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 6
|
||||
b = buf[6]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 7
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 7
|
||||
b = buf[7]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 8
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 8
|
||||
b = buf[8]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 9
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 9
|
||||
b = buf[9]
|
||||
if b < bit {
|
||||
if b > 1 {
|
||||
return 0, -10 // overflow
|
||||
}
|
||||
return x | uint64(b)<<s, 10
|
||||
} else if sz == 10 {
|
||||
return 0, 0
|
||||
}
|
||||
for j, b := range buf[10:] {
|
||||
if b < bit {
|
||||
return 0, -(11 + j)
|
||||
}
|
||||
}
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// i == 0
|
||||
b := buf[0]
|
||||
if b < bit {
|
||||
return uint64(b), 1
|
||||
} else if sz == 1 {
|
||||
return 0, 0
|
||||
}
|
||||
x := uint64(b & mask)
|
||||
var s uint = step
|
||||
|
||||
// i == 1
|
||||
b = buf[1]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 2
|
||||
} else if sz == 2 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 2
|
||||
b = buf[2]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 3
|
||||
} else if sz == 3 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 3
|
||||
b = buf[3]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 4
|
||||
} else if sz == 4 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 4
|
||||
b = buf[4]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 5
|
||||
} else if sz == 5 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 5
|
||||
b = buf[5]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 6
|
||||
} else if sz == 6 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 6
|
||||
b = buf[6]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 7
|
||||
} else if sz == 7 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 7
|
||||
b = buf[7]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 8
|
||||
} else if sz == 8 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 8
|
||||
b = buf[8]
|
||||
if b < bit {
|
||||
return x | uint64(b)<<s, 9
|
||||
} else if sz == 9 {
|
||||
return 0, 0
|
||||
}
|
||||
x |= uint64(b&mask) << s
|
||||
s += step
|
||||
|
||||
// i == 9
|
||||
b = buf[9]
|
||||
if b < bit {
|
||||
if b > 1 {
|
||||
return 0, -10 // overflow
|
||||
}
|
||||
return x | uint64(b)<<s, 10
|
||||
} else if sz == 10 {
|
||||
return 0, 0
|
||||
}
|
||||
for j, b := range buf[10:] {
|
||||
if b < bit {
|
||||
return 0, -(11 + j)
|
||||
}
|
||||
}
|
||||
return 0, 0
|
||||
}
|
||||
20
vendor/github.com/efficientgo/tools/core/pkg/merrors/doc.go
generated
vendored
Normal file
20
vendor/github.com/efficientgo/tools/core/pkg/merrors/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) The EfficientGo Authors.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
package merrors
|
||||
|
||||
// Safe multi error implementation that chains errors on the same level. Supports errors.As and errors.Is functions.
|
||||
//
|
||||
// Example 1:
|
||||
//
|
||||
// return merrors.New(err1, err2).Err()
|
||||
//
|
||||
// Example 2:
|
||||
//
|
||||
// merr := merrors.New(err1)
|
||||
// merr.Add(err2, errOrNil3)
|
||||
// for _, err := range errs {
|
||||
// merr.Add(err)
|
||||
// }
|
||||
// return merr.Err()
|
||||
//
|
||||
215
vendor/github.com/efficientgo/tools/core/pkg/merrors/errors.go
generated
vendored
Normal file
215
vendor/github.com/efficientgo/tools/core/pkg/merrors/errors.go
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
// Copyright (c) The EfficientGo Authors.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
package merrors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NilOrMultiError type allows combining multiple errors into one.
|
||||
type NilOrMultiError struct {
|
||||
errs []error
|
||||
}
|
||||
|
||||
// New returns NilOrMultiError with provided errors added if not nil.
|
||||
func New(errs ...error) *NilOrMultiError {
|
||||
m := &NilOrMultiError{}
|
||||
m.Add(errs...)
|
||||
return m
|
||||
}
|
||||
|
||||
// Add adds single or many errors to the error list. Each error is added only if not nil.
|
||||
// If the error is a multiError type, the errors inside multiError are added to the main NilOrMultiError.
|
||||
func (e *NilOrMultiError) Add(errs ...error) {
|
||||
for _, err := range errs {
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
if merr, ok := err.(multiError); ok {
|
||||
e.errs = append(e.errs, merr.errs...)
|
||||
continue
|
||||
}
|
||||
e.errs = append(e.errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Err returns the error list as an Error (also implements error) or nil if it is empty.
|
||||
func (e NilOrMultiError) Err() Error {
|
||||
if len(e.errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return multiError(e)
|
||||
}
|
||||
|
||||
// Error is extended error interface that allows to use returned read-only multi error in more advanced ways.
|
||||
type Error interface {
|
||||
error
|
||||
|
||||
// Errors returns underlying errors.
|
||||
Errors() []error
|
||||
|
||||
// As finds the first error in multiError slice of error chains that matches target, and if so, sets
|
||||
// target to that error value and returns true. Otherwise, it returns false.
|
||||
//
|
||||
// An error matches target if the error's concrete value is assignable to the value
|
||||
// pointed to by target, or if the error has a method As(interface{}) bool such that
|
||||
// As(target) returns true. In the latter case, the As method is responsible for
|
||||
// setting target.
|
||||
As(target interface{}) bool
|
||||
// Is returns true if any error in multiError's slice of error chains matches the given target or
|
||||
// if the target is of multiError type.
|
||||
//
|
||||
// An error is considered to match a target if it is equal to that target or if
|
||||
// it implements a method Is(error) bool such that Is(target) returns true.
|
||||
Is(target error) bool
|
||||
// Count returns the number of multi error' errors that match the given target.
|
||||
// Matching is defined as in Is method.
|
||||
Count(target error) int
|
||||
}
|
||||
|
||||
// multiError implements the error and Error interfaces, and it represents NilOrMultiError (in other words []error) with at least one error inside it.
|
||||
// NOTE: This type is useful to make sure that NilOrMultiError is not accidentally used for err != nil check.
|
||||
type multiError struct {
|
||||
errs []error
|
||||
}
|
||||
|
||||
// Errors returns underlying errors.
|
||||
func (e multiError) Errors() []error {
|
||||
return e.errs
|
||||
}
|
||||
|
||||
// Error returns a concatenated string of the contained errors.
|
||||
func (e multiError) Error() string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
if len(e.errs) > 1 {
|
||||
fmt.Fprintf(&buf, "%d errors: ", len(e.errs))
|
||||
}
|
||||
for i, err := range e.errs {
|
||||
if i != 0 {
|
||||
buf.WriteString("; ")
|
||||
}
|
||||
buf.WriteString(err.Error())
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// As finds the first error in multiError slice of error chains that matches target, and if so, sets
|
||||
// target to that error value and returns true. Otherwise, it returns false.
|
||||
//
|
||||
// An error matches target if the error's concrete value is assignable to the value
|
||||
// pointed to by target, or if the error has a method As(interface{}) bool such that
|
||||
// As(target) returns true. In the latter case, the As method is responsible for
|
||||
// setting target.
|
||||
func (e multiError) As(target interface{}) bool {
|
||||
if t, ok := target.(*multiError); ok {
|
||||
*t = e
|
||||
return true
|
||||
}
|
||||
|
||||
for _, err := range e.errs {
|
||||
if stderrors.As(err, target) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Is returns true if any error in multiError's slice of error chains matches the given target or
|
||||
// if the target is of multiError type.
|
||||
//
|
||||
// An error is considered to match a target if it is equal to that target or if
|
||||
// it implements a method Is(error) bool such that Is(target) returns true.
|
||||
func (e multiError) Is(target error) bool {
|
||||
if m, ok := target.(multiError); ok {
|
||||
if len(m.errs) != len(e.errs) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(e.errs); i++ {
|
||||
if !stderrors.Is(m.errs[i], e.errs[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
for _, err := range e.errs {
|
||||
if stderrors.Is(err, target) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Count returns the number of all multi error' errors that match the given target (including nested multi errors).
|
||||
// Matching is defined as in Is method.
|
||||
func (e multiError) Count(target error) (count int) {
|
||||
for _, err := range e.errs {
|
||||
if inner, ok := AsMulti(err); ok {
|
||||
count += inner.Count(target)
|
||||
continue
|
||||
}
|
||||
|
||||
if stderrors.Is(err, target) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// AsMulti casts error to multi error read only interface. It returns multi error and true if error matches multi error as
|
||||
// defined by As method. If returns false if no multi error can be found.
|
||||
func AsMulti(err error) (Error, bool) {
|
||||
m := multiError{}
|
||||
if !stderrors.As(err, &m) {
|
||||
return nil, false
|
||||
}
|
||||
return m, true
|
||||
}
|
||||
|
||||
// Merge merges multiple Error to single one, but joining all errors together.
|
||||
// NOTE: Nested multi errors are not merged.
|
||||
func Merge(errs []Error) Error {
|
||||
e := multiError{}
|
||||
for _, err := range errs {
|
||||
e.errs = append(e.errs, err.Errors()...)
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// PrettyPrint prints the same information as multiError.Error() method but with newlines and indentation targeted
|
||||
// for humans.
|
||||
func PrettyPrint(w io.Writer, err Error) error {
|
||||
return prettyPrint(w, "\t", err)
|
||||
}
|
||||
|
||||
func prettyPrint(w io.Writer, indent string, merr Error) error {
|
||||
if len(merr.Errors()) > 1 {
|
||||
if _, err := fmt.Fprintf(w, "%d errors:\n", len(merr.Errors())); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for i, err := range merr.Errors() {
|
||||
if i != 0 {
|
||||
if _, err := w.Write([]byte("\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if merr2, ok := AsMulti(err); ok {
|
||||
if err := prettyPrint(w, indent+"\t", merr2); err != nil {
|
||||
return nil
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := w.Write([]byte(indent + err.Error())); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
15
vendor/github.com/go-kit/log/.gitignore
generated
vendored
Normal file
15
vendor/github.com/go-kit/log/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
21
vendor/github.com/go-kit/log/LICENSE
generated
vendored
Normal file
21
vendor/github.com/go-kit/log/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Go kit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
10
vendor/github.com/go-kit/kit/log/README.md → vendor/github.com/go-kit/log/README.md
generated
vendored
10
vendor/github.com/go-kit/kit/log/README.md → vendor/github.com/go-kit/log/README.md
generated
vendored
@@ -66,7 +66,7 @@ Redirect stdlib logger to Go kit logger.
|
||||
import (
|
||||
"os"
|
||||
stdlog "log"
|
||||
kitlog "github.com/go-kit/kit/log"
|
||||
kitlog "github.com/go-kit/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -105,7 +105,7 @@ logger.Log("msg", "hello")
|
||||
|
||||
## Levels
|
||||
|
||||
Log levels are supported via the [level package](https://godoc.org/github.com/go-kit/kit/log/level).
|
||||
Log levels are supported via the [level package](https://godoc.org/github.com/go-kit/log/level).
|
||||
|
||||
## Supported output formats
|
||||
|
||||
@@ -136,11 +136,11 @@ Also, please see
|
||||
to review historical conversations about package log and the Logger interface.
|
||||
|
||||
Value-add packages and suggestions,
|
||||
like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/kit/log/level),
|
||||
like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/log/level),
|
||||
are of course welcome. Good proposals should
|
||||
|
||||
- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/kit/log#With),
|
||||
- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/kit/log#Caller) in any wrapped contextual loggers, and
|
||||
- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/log#With),
|
||||
- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/log#Caller) in any wrapped contextual loggers, and
|
||||
- Be friendly to packages that accept only an unadorned log.Logger.
|
||||
|
||||
## Benchmarks & comparisons
|
||||
4
vendor/github.com/go-kit/kit/log/doc.go → vendor/github.com/go-kit/log/doc.go
generated
vendored
4
vendor/github.com/go-kit/kit/log/doc.go → vendor/github.com/go-kit/log/doc.go
generated
vendored
@@ -39,8 +39,8 @@
|
||||
//
|
||||
// A contextual logger stores keyvals that it includes in all log events.
|
||||
// Building appropriate contextual loggers reduces repetition and aids
|
||||
// consistency in the resulting log output. With and WithPrefix add context to
|
||||
// a logger. We can use With to improve the RunTask example.
|
||||
// consistency in the resulting log output. With, WithPrefix, and WithSuffix
|
||||
// add context to a logger. We can use With to improve the RunTask example.
|
||||
//
|
||||
// func RunTask(task Task, logger log.Logger) string {
|
||||
// logger = log.With(logger, "taskID", task.ID)
|
||||
@@ -1,6 +1,6 @@
|
||||
package level
|
||||
|
||||
import "github.com/go-kit/kit/log"
|
||||
import "github.com/go-kit/log"
|
||||
|
||||
// Error returns a logger that includes a Key/ErrorValue pair.
|
||||
func Error(logger log.Logger) log.Logger {
|
||||
@@ -172,7 +172,7 @@ func WarnValue() Value { return warnValue }
|
||||
// InfoValue returns the unique value added to log events by Info.
|
||||
func InfoValue() Value { return infoValue }
|
||||
|
||||
// DebugValue returns the unique value added to log events by Warn.
|
||||
// DebugValue returns the unique value added to log events by Debug.
|
||||
func DebugValue() Value { return debugValue }
|
||||
|
||||
var (
|
||||
82
vendor/github.com/go-kit/kit/log/log.go → vendor/github.com/go-kit/log/log.go
generated
vendored
82
vendor/github.com/go-kit/kit/log/log.go → vendor/github.com/go-kit/log/log.go
generated
vendored
@@ -16,8 +16,8 @@ type Logger interface {
|
||||
var ErrMissingValue = errors.New("(MISSING)")
|
||||
|
||||
// With returns a new contextual logger with keyvals prepended to those passed
|
||||
// to calls to Log. If logger is also a contextual logger created by With or
|
||||
// WithPrefix, keyvals is appended to the existing context.
|
||||
// to calls to Log. If logger is also a contextual logger created by With,
|
||||
// WithPrefix, or WithSuffix, keyvals is appended to the existing context.
|
||||
//
|
||||
// The returned Logger replaces all value elements (odd indexes) containing a
|
||||
// Valuer with their generated value for each call to its Log method.
|
||||
@@ -36,14 +36,16 @@ func With(logger Logger, keyvals ...interface{}) Logger {
|
||||
// backing array is created if the slice must grow in Log or With.
|
||||
// Using the extra capacity without copying risks a data race that
|
||||
// would violate the Logger interface contract.
|
||||
keyvals: kvs[:len(kvs):len(kvs)],
|
||||
hasValuer: l.hasValuer || containsValuer(keyvals),
|
||||
keyvals: kvs[:len(kvs):len(kvs)],
|
||||
hasValuer: l.hasValuer || containsValuer(keyvals),
|
||||
sKeyvals: l.sKeyvals,
|
||||
sHasValuer: l.sHasValuer,
|
||||
}
|
||||
}
|
||||
|
||||
// WithPrefix returns a new contextual logger with keyvals prepended to those
|
||||
// passed to calls to Log. If logger is also a contextual logger created by
|
||||
// With or WithPrefix, keyvals is prepended to the existing context.
|
||||
// With, WithPrefix, or WithSuffix, keyvals is prepended to the existing context.
|
||||
//
|
||||
// The returned Logger replaces all value elements (odd indexes) containing a
|
||||
// Valuer with their generated value for each call to its Log method.
|
||||
@@ -67,16 +69,52 @@ func WithPrefix(logger Logger, keyvals ...interface{}) Logger {
|
||||
}
|
||||
kvs = append(kvs, l.keyvals...)
|
||||
return &context{
|
||||
logger: l.logger,
|
||||
keyvals: kvs,
|
||||
hasValuer: l.hasValuer || containsValuer(keyvals),
|
||||
logger: l.logger,
|
||||
keyvals: kvs,
|
||||
hasValuer: l.hasValuer || containsValuer(keyvals),
|
||||
sKeyvals: l.sKeyvals,
|
||||
sHasValuer: l.sHasValuer,
|
||||
}
|
||||
}
|
||||
|
||||
// context is the Logger implementation returned by With and WithPrefix. It
|
||||
// wraps a Logger and holds keyvals that it includes in all log events. Its
|
||||
// Log method calls bindValues to generate values for each Valuer in the
|
||||
// context keyvals.
|
||||
// WithSuffix returns a new contextual logger with keyvals appended to those
|
||||
// passed to calls to Log. If logger is also a contextual logger created by
|
||||
// With, WithPrefix, or WithSuffix, keyvals is appended to the existing context.
|
||||
//
|
||||
// The returned Logger replaces all value elements (odd indexes) containing a
|
||||
// Valuer with their generated value for each call to its Log method.
|
||||
func WithSuffix(logger Logger, keyvals ...interface{}) Logger {
|
||||
if len(keyvals) == 0 {
|
||||
return logger
|
||||
}
|
||||
l := newContext(logger)
|
||||
// Limiting the capacity of the stored keyvals ensures that a new
|
||||
// backing array is created if the slice must grow in Log or With.
|
||||
// Using the extra capacity without copying risks a data race that
|
||||
// would violate the Logger interface contract.
|
||||
n := len(l.sKeyvals) + len(keyvals)
|
||||
if len(keyvals)%2 != 0 {
|
||||
n++
|
||||
}
|
||||
kvs := make([]interface{}, 0, n)
|
||||
kvs = append(kvs, keyvals...)
|
||||
if len(kvs)%2 != 0 {
|
||||
kvs = append(kvs, ErrMissingValue)
|
||||
}
|
||||
kvs = append(l.sKeyvals, kvs...)
|
||||
return &context{
|
||||
logger: l.logger,
|
||||
keyvals: l.keyvals,
|
||||
hasValuer: l.hasValuer,
|
||||
sKeyvals: kvs,
|
||||
sHasValuer: l.sHasValuer || containsValuer(keyvals),
|
||||
}
|
||||
}
|
||||
|
||||
// context is the Logger implementation returned by With, WithPrefix, and
|
||||
// WithSuffix. It wraps a Logger and holds keyvals that it includes in all
|
||||
// log events. Its Log method calls bindValues to generate values for each
|
||||
// Valuer in the context keyvals.
|
||||
//
|
||||
// A context must always have the same number of stack frames between calls to
|
||||
// its Log method and the eventual binding of Valuers to their value. This
|
||||
@@ -89,13 +127,15 @@ func WithPrefix(logger Logger, keyvals ...interface{}) Logger {
|
||||
//
|
||||
// 1. newContext avoids introducing an additional layer when asked to
|
||||
// wrap another context.
|
||||
// 2. With and WithPrefix avoid introducing an additional layer by
|
||||
// returning a newly constructed context with a merged keyvals rather
|
||||
// than simply wrapping the existing context.
|
||||
// 2. With, WithPrefix, and WithSuffix avoid introducing an additional
|
||||
// layer by returning a newly constructed context with a merged keyvals
|
||||
// rather than simply wrapping the existing context.
|
||||
type context struct {
|
||||
logger Logger
|
||||
keyvals []interface{}
|
||||
hasValuer bool
|
||||
logger Logger
|
||||
keyvals []interface{}
|
||||
sKeyvals []interface{} // suffixes
|
||||
hasValuer bool
|
||||
sHasValuer bool
|
||||
}
|
||||
|
||||
func newContext(logger Logger) *context {
|
||||
@@ -119,7 +159,11 @@ func (l *context) Log(keyvals ...interface{}) error {
|
||||
if len(keyvals) == 0 {
|
||||
kvs = append([]interface{}{}, l.keyvals...)
|
||||
}
|
||||
bindValues(kvs[:len(l.keyvals)])
|
||||
bindValues(kvs[:(len(l.keyvals))])
|
||||
}
|
||||
kvs = append(kvs, l.sKeyvals...)
|
||||
if l.sHasValuer {
|
||||
bindValues(kvs[len(kvs)-len(l.sKeyvals):])
|
||||
}
|
||||
return l.logger.Log(kvs...)
|
||||
}
|
||||
45
vendor/github.com/go-kit/kit/log/stdlib.go → vendor/github.com/go-kit/log/stdlib.go
generated
vendored
45
vendor/github.com/go-kit/kit/log/stdlib.go → vendor/github.com/go-kit/log/stdlib.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"regexp"
|
||||
@@ -26,9 +27,11 @@ func (w StdlibWriter) Write(p []byte) (int, error) {
|
||||
// messages, and place them under relevant keys.
|
||||
type StdlibAdapter struct {
|
||||
Logger
|
||||
timestampKey string
|
||||
fileKey string
|
||||
messageKey string
|
||||
timestampKey string
|
||||
fileKey string
|
||||
messageKey string
|
||||
prefix string
|
||||
joinPrefixToMsg bool
|
||||
}
|
||||
|
||||
// StdlibAdapterOption sets a parameter for the StdlibAdapter.
|
||||
@@ -49,6 +52,16 @@ func MessageKey(key string) StdlibAdapterOption {
|
||||
return func(a *StdlibAdapter) { a.messageKey = key }
|
||||
}
|
||||
|
||||
// Prefix configures the adapter to parse a prefix from stdlib log events. If
|
||||
// you provide a non-empty prefix to the stdlib logger, then your should provide
|
||||
// that same prefix to the adapter via this option.
|
||||
//
|
||||
// By default, the prefix isn't included in the msg key. Set joinPrefixToMsg to
|
||||
// true if you want to include the parsed prefix in the msg.
|
||||
func Prefix(prefix string, joinPrefixToMsg bool) StdlibAdapterOption {
|
||||
return func(a *StdlibAdapter) { a.prefix = prefix; a.joinPrefixToMsg = joinPrefixToMsg }
|
||||
}
|
||||
|
||||
// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed
|
||||
// logger. It's designed to be passed to log.SetOutput.
|
||||
func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer {
|
||||
@@ -65,6 +78,8 @@ func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer {
|
||||
}
|
||||
|
||||
func (a StdlibAdapter) Write(p []byte) (int, error) {
|
||||
p = a.handlePrefix(p)
|
||||
|
||||
result := subexps(p)
|
||||
keyvals := []interface{}{}
|
||||
var timestamp string
|
||||
@@ -84,6 +99,7 @@ func (a StdlibAdapter) Write(p []byte) (int, error) {
|
||||
keyvals = append(keyvals, a.fileKey, file)
|
||||
}
|
||||
if msg, ok := result["msg"]; ok {
|
||||
msg = a.handleMessagePrefix(msg)
|
||||
keyvals = append(keyvals, a.messageKey, msg)
|
||||
}
|
||||
if err := a.Logger.Log(keyvals...); err != nil {
|
||||
@@ -92,11 +108,30 @@ func (a StdlibAdapter) Write(p []byte) (int, error) {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (a StdlibAdapter) handlePrefix(p []byte) []byte {
|
||||
if a.prefix != "" {
|
||||
p = bytes.TrimPrefix(p, []byte(a.prefix))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (a StdlibAdapter) handleMessagePrefix(msg string) string {
|
||||
if a.prefix == "" {
|
||||
return msg
|
||||
}
|
||||
|
||||
msg = strings.TrimPrefix(msg, a.prefix)
|
||||
if a.joinPrefixToMsg {
|
||||
msg = a.prefix + msg
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
const (
|
||||
logRegexpDate = `(?P<date>[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?`
|
||||
logRegexpTime = `(?P<time>[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)?[ ]?`
|
||||
logRegexpFile = `(?P<file>.+?:[0-9]+)?`
|
||||
logRegexpMsg = `(: )?(?P<msg>.*)`
|
||||
logRegexpMsg = `(: )?(?P<msg>(?s:.*))`
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -110,7 +145,7 @@ func subexps(line []byte) map[string]string {
|
||||
}
|
||||
result := map[string]string{}
|
||||
for i, name := range logRegexp.SubexpNames() {
|
||||
result[name] = string(m[i])
|
||||
result[name] = strings.TrimRight(string(m[i]), "\n")
|
||||
}
|
||||
return result
|
||||
}
|
||||
15
vendor/github.com/go-kit/kit/log/sync.go → vendor/github.com/go-kit/log/sync.go
generated
vendored
15
vendor/github.com/go-kit/kit/log/sync.go → vendor/github.com/go-kit/log/sync.go
generated
vendored
@@ -65,9 +65,8 @@ type syncWriter struct {
|
||||
// progress, the calling goroutine blocks until the syncWriter is available.
|
||||
func (w *syncWriter) Write(p []byte) (n int, err error) {
|
||||
w.Lock()
|
||||
n, err = w.Writer.Write(p)
|
||||
w.Unlock()
|
||||
return n, err
|
||||
defer w.Unlock()
|
||||
return w.Writer.Write(p)
|
||||
}
|
||||
|
||||
// fdWriter is an io.Writer that also has an Fd method. The most common
|
||||
@@ -87,9 +86,8 @@ type fdSyncWriter struct {
|
||||
// progress, the calling goroutine blocks until the fdSyncWriter is available.
|
||||
func (w *fdSyncWriter) Write(p []byte) (n int, err error) {
|
||||
w.Lock()
|
||||
n, err = w.fdWriter.Write(p)
|
||||
w.Unlock()
|
||||
return n, err
|
||||
defer w.Unlock()
|
||||
return w.fdWriter.Write(p)
|
||||
}
|
||||
|
||||
// syncLogger provides concurrent safe logging for another Logger.
|
||||
@@ -110,7 +108,6 @@ func NewSyncLogger(logger Logger) Logger {
|
||||
// progress, the calling goroutine blocks until the syncLogger is available.
|
||||
func (l *syncLogger) Log(keyvals ...interface{}) error {
|
||||
l.mu.Lock()
|
||||
err := l.logger.Log(keyvals...)
|
||||
l.mu.Unlock()
|
||||
return err
|
||||
defer l.mu.Unlock()
|
||||
return l.logger.Log(keyvals...)
|
||||
}
|
||||
6
vendor/github.com/go-kit/kit/log/value.go → vendor/github.com/go-kit/log/value.go
generated
vendored
6
vendor/github.com/go-kit/kit/log/value.go → vendor/github.com/go-kit/log/value.go
generated
vendored
@@ -7,9 +7,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Valuer generates a log value. When passed to With or WithPrefix in a
|
||||
// value element (odd indexes), it represents a dynamic value which is re-
|
||||
// evaluated with each log event.
|
||||
// A Valuer generates a log value. When passed to With, WithPrefix, or
|
||||
// WithSuffix in a value element (odd indexes), it represents a dynamic
|
||||
// value which is re-evaluated with each log event.
|
||||
type Valuer func() interface{}
|
||||
|
||||
// bindValues replaces all value elements (odd indexes) containing a Valuer
|
||||
2
vendor/github.com/go-openapi/analysis/.gitattributes
generated
vendored
Normal file
2
vendor/github.com/go-openapi/analysis/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.go text eol=lf
|
||||
|
||||
28
vendor/github.com/go-openapi/analysis/.golangci.yml
generated
vendored
28
vendor/github.com/go-openapi/analysis/.golangci.yml
generated
vendored
@@ -5,10 +5,12 @@ linters-settings:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 40
|
||||
gocognit:
|
||||
min-complexity: 40
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
threshold: 150
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 4
|
||||
@@ -27,6 +29,28 @@ linters:
|
||||
- scopelint
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
#- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- testpackage
|
||||
- wrapcheck
|
||||
#- nlreturn
|
||||
- gomnd
|
||||
- goerr113
|
||||
- exhaustivestruct
|
||||
#- errorlint
|
||||
#- nestif
|
||||
- gofumpt
|
||||
- godot
|
||||
- gci
|
||||
- dogsled
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- forbidigo
|
||||
- cyclop
|
||||
- varnamelen
|
||||
- exhaustruct
|
||||
- nonamedreturns
|
||||
- nosnakecase
|
||||
|
||||
13
vendor/github.com/go-openapi/analysis/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/analysis/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -timeout=20m -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
28
vendor/github.com/go-openapi/analysis/README.md
generated
vendored
28
vendor/github.com/go-openapi/analysis/README.md
generated
vendored
@@ -1,9 +1,31 @@
|
||||
# OpenAPI initiative analysis [](https://travis-ci.org/go-openapi/analysis) [](https://ci.appveyor.com/project/casualjim/go-openapi/analysis/branch/master) [](https://codecov.io/gh/go-openapi/analysis)
|
||||
# OpenAPI initiative analysis
|
||||
|
||||
[](https://travis-ci.org/go-openapi/analysis)
|
||||
[](https://ci.appveyor.com/project/casualjim/go-openapi/analysis/branch/master)
|
||||
[](https://codecov.io/gh/go-openapi/analysis)
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/analysis/master/LICENSE)
|
||||
[](http://godoc.org/github.com/go-openapi/analysis)
|
||||
[](https://golangci.com)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/analysis)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/analysis)
|
||||
|
||||
|
||||
A foundational library to analyze an OAI specification document for easier reasoning about the content.
|
||||
|
||||
## What's inside?
|
||||
|
||||
* A analyzer providing methods to walk the functional content of a specification
|
||||
* A spec flattener producing a self-contained document bundle, while preserving `$ref`s
|
||||
* A spec merger ("mixin") to merge several spec documents into a primary spec
|
||||
* A spec "fixer" ensuring that response descriptions are non empty
|
||||
|
||||
[Documentation](https://godoc.org/github.com/go-openapi/analysis)
|
||||
|
||||
## FAQ
|
||||
|
||||
* Does this library support OpenAPI 3?
|
||||
|
||||
> No.
|
||||
> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0).
|
||||
> There is no plan to make it evolve toward supporting OpenAPI 3.x.
|
||||
> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story.
|
||||
>
|
||||
|
||||
246
vendor/github.com/go-openapi/analysis/analyzer.go
generated
vendored
246
vendor/github.com/go-openapi/analysis/analyzer.go
generated
vendored
@@ -149,6 +149,7 @@ func New(doc *spec.Swagger) *Spec {
|
||||
}
|
||||
a.reset()
|
||||
a.initialize()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -212,7 +213,7 @@ func (s *Spec) initialize() {
|
||||
}
|
||||
}
|
||||
for path, pathItem := range s.AllPaths() {
|
||||
s.analyzeOperations(path, &pathItem)
|
||||
s.analyzeOperations(path, &pathItem) //#nosec
|
||||
}
|
||||
|
||||
for name, parameter := range s.spec.Parameters {
|
||||
@@ -277,7 +278,7 @@ func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) {
|
||||
for i, param := range op.Parameters {
|
||||
refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i))
|
||||
if param.Ref.String() != "" {
|
||||
s.references.addParamRef(refPref, ¶m)
|
||||
s.references.addParamRef(refPref, ¶m) //#nosec
|
||||
}
|
||||
if param.Pattern != "" {
|
||||
s.patterns.addParameterPattern(refPref, param.Pattern)
|
||||
@@ -311,6 +312,26 @@ func (s *Spec) analyzeItems(name string, items *spec.Items, prefix, location str
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeParameter(prefix string, i int, param spec.Parameter) {
|
||||
refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
|
||||
if param.Ref.String() != "" {
|
||||
s.references.addParamRef(refPref, ¶m) //#nosec
|
||||
}
|
||||
|
||||
if param.Pattern != "" {
|
||||
s.patterns.addParameterPattern(refPref, param.Pattern)
|
||||
}
|
||||
|
||||
if len(param.Enum) > 0 {
|
||||
s.enums.addParameterEnum(refPref, param.Enum)
|
||||
}
|
||||
|
||||
s.analyzeItems("items", param.Items, refPref, "parameter")
|
||||
if param.In == "body" && param.Schema != nil {
|
||||
s.analyzeSchema("schema", param.Schema, refPref)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
|
||||
if op == nil {
|
||||
return
|
||||
@@ -319,72 +340,80 @@ func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
|
||||
for _, c := range op.Consumes {
|
||||
s.consumes[c] = struct{}{}
|
||||
}
|
||||
|
||||
for _, c := range op.Produces {
|
||||
s.produces[c] = struct{}{}
|
||||
}
|
||||
|
||||
for _, ss := range op.Security {
|
||||
for k := range ss {
|
||||
s.authSchemes[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := s.operations[method]; !ok {
|
||||
s.operations[method] = make(map[string]*spec.Operation)
|
||||
}
|
||||
|
||||
s.operations[method][path] = op
|
||||
prefix := slashpath.Join("/paths", jsonpointer.Escape(path), strings.ToLower(method))
|
||||
for i, param := range op.Parameters {
|
||||
refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
|
||||
if param.Ref.String() != "" {
|
||||
s.references.addParamRef(refPref, ¶m)
|
||||
}
|
||||
if param.Pattern != "" {
|
||||
s.patterns.addParameterPattern(refPref, param.Pattern)
|
||||
}
|
||||
if len(param.Enum) > 0 {
|
||||
s.enums.addParameterEnum(refPref, param.Enum)
|
||||
}
|
||||
s.analyzeItems("items", param.Items, refPref, "parameter")
|
||||
if param.In == "body" && param.Schema != nil {
|
||||
s.analyzeSchema("schema", param.Schema, refPref)
|
||||
s.analyzeParameter(prefix, i, param)
|
||||
}
|
||||
|
||||
if op.Responses == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if op.Responses.Default != nil {
|
||||
s.analyzeDefaultResponse(prefix, op.Responses.Default)
|
||||
}
|
||||
|
||||
for k, res := range op.Responses.StatusCodeResponses {
|
||||
s.analyzeResponse(prefix, k, res)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeDefaultResponse(prefix string, res *spec.Response) {
|
||||
refPref := slashpath.Join(prefix, "responses", "default")
|
||||
if res.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, res)
|
||||
}
|
||||
|
||||
for k, v := range res.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
}
|
||||
if op.Responses != nil {
|
||||
if op.Responses.Default != nil {
|
||||
refPref := slashpath.Join(prefix, "responses", "default")
|
||||
if op.Responses.Default.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, op.Responses.Default)
|
||||
}
|
||||
for k, v := range op.Responses.Default.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
}
|
||||
if op.Responses.Default.Schema != nil {
|
||||
s.analyzeSchema("schema", op.Responses.Default.Schema, refPref)
|
||||
}
|
||||
|
||||
if res.Schema != nil {
|
||||
s.analyzeSchema("schema", res.Schema, refPref)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeResponse(prefix string, k int, res spec.Response) {
|
||||
refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
|
||||
if res.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, &res) //#nosec
|
||||
}
|
||||
|
||||
for k, v := range res.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
for k, res := range op.Responses.StatusCodeResponses {
|
||||
refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
|
||||
if res.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, &res)
|
||||
}
|
||||
for k, v := range res.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
if len(v.Enum) > 0 {
|
||||
s.enums.addHeaderEnum(hRefPref, v.Enum)
|
||||
}
|
||||
}
|
||||
if res.Schema != nil {
|
||||
s.analyzeSchema("schema", res.Schema, refPref)
|
||||
}
|
||||
|
||||
if len(v.Enum) > 0 {
|
||||
s.enums.addHeaderEnum(hRefPref, v.Enum)
|
||||
}
|
||||
}
|
||||
|
||||
if res.Schema != nil {
|
||||
s.analyzeSchema("schema", res.Schema, refPref)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) {
|
||||
@@ -401,9 +430,11 @@ func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) {
|
||||
if schema.Ref.String() != "" {
|
||||
s.references.addSchemaRef(refURI, schRef)
|
||||
}
|
||||
|
||||
if schema.Pattern != "" {
|
||||
s.patterns.addSchemaPattern(refURI, schema.Pattern)
|
||||
}
|
||||
|
||||
if len(schema.Enum) > 0 {
|
||||
s.enums.addSchemaEnum(refURI, schema.Enum)
|
||||
}
|
||||
@@ -412,52 +443,63 @@ func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) {
|
||||
v := v
|
||||
s.analyzeSchema(k, &v, slashpath.Join(refURI, "definitions"))
|
||||
}
|
||||
|
||||
for k, v := range schema.Properties {
|
||||
v := v
|
||||
s.analyzeSchema(k, &v, slashpath.Join(refURI, "properties"))
|
||||
}
|
||||
|
||||
for k, v := range schema.PatternProperties {
|
||||
v := v
|
||||
// NOTE: swagger 2.0 does not support PatternProperties.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema(k, &v, slashpath.Join(refURI, "patternProperties"))
|
||||
}
|
||||
|
||||
for i := range schema.AllOf {
|
||||
v := &schema.AllOf[i]
|
||||
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "allOf"))
|
||||
}
|
||||
|
||||
if len(schema.AllOf) > 0 {
|
||||
s.allOfs["#"+refURI] = schRef
|
||||
}
|
||||
|
||||
for i := range schema.AnyOf {
|
||||
v := &schema.AnyOf[i]
|
||||
// NOTE: swagger 2.0 does not support anyOf constructs.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "anyOf"))
|
||||
}
|
||||
|
||||
for i := range schema.OneOf {
|
||||
v := &schema.OneOf[i]
|
||||
// NOTE: swagger 2.0 does not support oneOf constructs.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "oneOf"))
|
||||
}
|
||||
|
||||
if schema.Not != nil {
|
||||
// NOTE: swagger 2.0 does not support "not" constructs.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema("not", schema.Not, refURI)
|
||||
}
|
||||
|
||||
if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
|
||||
s.analyzeSchema("additionalProperties", schema.AdditionalProperties.Schema, refURI)
|
||||
}
|
||||
|
||||
if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
|
||||
// NOTE: swagger 2.0 does not support AdditionalItems.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema("additionalItems", schema.AdditionalItems.Schema, refURI)
|
||||
}
|
||||
|
||||
if schema.Items != nil {
|
||||
if schema.Items.Schema != nil {
|
||||
s.analyzeSchema("items", schema.Items.Schema, refURI)
|
||||
}
|
||||
|
||||
for i := range schema.Items.Schemas {
|
||||
sch := &schema.Items.Schemas[i]
|
||||
s.analyzeSchema(strconv.Itoa(i), sch, slashpath.Join(refURI, "items"))
|
||||
@@ -487,8 +529,10 @@ func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRe
|
||||
if len(scheme) == 0 {
|
||||
// append a zero object for anonymous
|
||||
result = append(result, []SecurityRequirement{{}})
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
var reqs []SecurityRequirement
|
||||
for k, v := range scheme {
|
||||
if v == nil {
|
||||
@@ -496,8 +540,10 @@ func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRe
|
||||
}
|
||||
reqs = append(reqs, SecurityRequirement{Name: k, Scopes: v})
|
||||
}
|
||||
|
||||
result = append(result, reqs)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -512,6 +558,7 @@ func (s *Spec) SecurityDefinitionsForRequirements(requirements []SecurityRequire
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -529,10 +576,12 @@ func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec
|
||||
// optional requirement
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := result[v.Name]; ok {
|
||||
// duplicate requirement
|
||||
continue
|
||||
}
|
||||
|
||||
if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
|
||||
if definition != nil {
|
||||
result[v.Name] = *definition
|
||||
@@ -540,17 +589,18 @@ func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ConsumesFor gets the mediatypes for the operation
|
||||
func (s *Spec) ConsumesFor(operation *spec.Operation) []string {
|
||||
|
||||
if len(operation.Consumes) == 0 {
|
||||
cons := make(map[string]struct{}, len(s.spec.Consumes))
|
||||
for _, k := range s.spec.Consumes {
|
||||
cons[k] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(cons)
|
||||
}
|
||||
|
||||
@@ -558,6 +608,7 @@ func (s *Spec) ConsumesFor(operation *spec.Operation) []string {
|
||||
for _, c := range operation.Consumes {
|
||||
cons[c] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(cons)
|
||||
}
|
||||
|
||||
@@ -568,6 +619,7 @@ func (s *Spec) ProducesFor(operation *spec.Operation) []string {
|
||||
for _, k := range s.spec.Produces {
|
||||
prod[k] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(prod)
|
||||
}
|
||||
|
||||
@@ -575,6 +627,7 @@ func (s *Spec) ProducesFor(operation *spec.Operation) []string {
|
||||
for _, c := range operation.Produces {
|
||||
prod[c] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(prod)
|
||||
}
|
||||
|
||||
@@ -587,6 +640,7 @@ func fieldNameFromParam(param *spec.Parameter) string {
|
||||
if nm, ok := param.Extensions.GetString("go-name"); ok {
|
||||
return nm
|
||||
}
|
||||
|
||||
return swag.ToGoName(param.Name)
|
||||
}
|
||||
|
||||
@@ -606,31 +660,38 @@ type ErrorOnParamFunc func(spec.Parameter, error) bool
|
||||
func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Parameter, callmeOnError ErrorOnParamFunc) {
|
||||
for _, param := range parameters {
|
||||
pr := param
|
||||
if pr.Ref.String() != "" {
|
||||
obj, _, err := pr.Ref.GetPointer().Get(s.spec)
|
||||
if err != nil {
|
||||
if callmeOnError != nil {
|
||||
if callmeOnError(param, fmt.Errorf("invalid reference: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
} else {
|
||||
panic(fmt.Sprintf("invalid reference: %q", pr.Ref.String()))
|
||||
}
|
||||
}
|
||||
if objAsParam, ok := obj.(spec.Parameter); ok {
|
||||
pr = objAsParam
|
||||
} else {
|
||||
if callmeOnError != nil {
|
||||
if callmeOnError(param, fmt.Errorf("resolved reference is not a parameter: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
} else {
|
||||
panic(fmt.Sprintf("resolved reference is not a parameter: %q", pr.Ref.String()))
|
||||
}
|
||||
if pr.Ref.String() == "" {
|
||||
res[mapKeyFromParam(&pr)] = pr
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// resolve $ref
|
||||
if callmeOnError == nil {
|
||||
callmeOnError = func(_ spec.Parameter, err error) bool {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
obj, _, err := pr.Ref.GetPointer().Get(s.spec)
|
||||
if err != nil {
|
||||
if callmeOnError(param, fmt.Errorf("invalid reference: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
objAsParam, ok := obj.(spec.Parameter)
|
||||
if !ok {
|
||||
if callmeOnError(param, fmt.Errorf("resolved reference is not a parameter: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
pr = objAsParam
|
||||
res[mapKeyFromParam(&pr)] = pr
|
||||
}
|
||||
}
|
||||
@@ -661,31 +722,34 @@ func (s *Spec) SafeParametersFor(operationID string, callmeOnError ErrorOnParamF
|
||||
for _, v := range bag {
|
||||
res = append(res, v)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
for _, pi := range s.spec.Paths.Paths {
|
||||
if pi.Get != nil && pi.Get.ID == operationID {
|
||||
return gatherParams(&pi, pi.Get)
|
||||
return gatherParams(&pi, pi.Get) //#nosec
|
||||
}
|
||||
if pi.Head != nil && pi.Head.ID == operationID {
|
||||
return gatherParams(&pi, pi.Head)
|
||||
return gatherParams(&pi, pi.Head) //#nosec
|
||||
}
|
||||
if pi.Options != nil && pi.Options.ID == operationID {
|
||||
return gatherParams(&pi, pi.Options)
|
||||
return gatherParams(&pi, pi.Options) //#nosec
|
||||
}
|
||||
if pi.Post != nil && pi.Post.ID == operationID {
|
||||
return gatherParams(&pi, pi.Post)
|
||||
return gatherParams(&pi, pi.Post) //#nosec
|
||||
}
|
||||
if pi.Patch != nil && pi.Patch.ID == operationID {
|
||||
return gatherParams(&pi, pi.Patch)
|
||||
return gatherParams(&pi, pi.Patch) //#nosec
|
||||
}
|
||||
if pi.Put != nil && pi.Put.ID == operationID {
|
||||
return gatherParams(&pi, pi.Put)
|
||||
return gatherParams(&pi, pi.Put) //#nosec
|
||||
}
|
||||
if pi.Delete != nil && pi.Delete.ID == operationID {
|
||||
return gatherParams(&pi, pi.Delete)
|
||||
return gatherParams(&pi, pi.Delete) //#nosec
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -713,6 +777,7 @@ func (s *Spec) SafeParamsFor(method, path string, callmeOnError ErrorOnParamFunc
|
||||
s.paramsAsMap(pi.Parameters, res, callmeOnError)
|
||||
s.paramsAsMap(s.operations[strings.ToUpper(method)][path].Parameters, res, callmeOnError)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -725,6 +790,7 @@ func (s *Spec) OperationForName(operationID string) (string, string, *spec.Opera
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", "", nil, false
|
||||
}
|
||||
|
||||
@@ -732,8 +798,10 @@ func (s *Spec) OperationForName(operationID string) (string, string, *spec.Opera
|
||||
func (s *Spec) OperationFor(method, path string) (*spec.Operation, bool) {
|
||||
if mp, ok := s.operations[strings.ToUpper(method)]; ok {
|
||||
op, fn := mp[path]
|
||||
|
||||
return op, fn
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -751,6 +819,7 @@ func (s *Spec) structMapKeys(mp map[string]struct{}) []string {
|
||||
for k := range mp {
|
||||
result = append(result, k)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -759,6 +828,7 @@ func (s *Spec) AllPaths() map[string]spec.PathItem {
|
||||
if s.spec == nil || s.spec.Paths == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.spec.Paths.Paths
|
||||
}
|
||||
|
||||
@@ -767,6 +837,7 @@ func (s *Spec) OperationIDs() []string {
|
||||
if len(s.operations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(s.operations))
|
||||
for method, v := range s.operations {
|
||||
for p, o := range v {
|
||||
@@ -777,6 +848,7 @@ func (s *Spec) OperationIDs() []string {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -785,12 +857,14 @@ func (s *Spec) OperationMethodPaths() []string {
|
||||
if len(s.operations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(s.operations))
|
||||
for method, v := range s.operations {
|
||||
for p := range v {
|
||||
result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -823,6 +897,7 @@ func (s *Spec) SchemasWithAllOf() (result []SchemaRef) {
|
||||
for _, v := range s.allOfs {
|
||||
result = append(result, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -831,6 +906,7 @@ func (s *Spec) AllDefinitions() (result []SchemaRef) {
|
||||
for _, v := range s.allSchemas {
|
||||
result = append(result, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -839,6 +915,7 @@ func (s *Spec) AllDefinitionReferences() (result []string) {
|
||||
for _, v := range s.references.schemas {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -847,6 +924,7 @@ func (s *Spec) AllParameterReferences() (result []string) {
|
||||
for _, v := range s.references.parameters {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -855,6 +933,7 @@ func (s *Spec) AllResponseReferences() (result []string) {
|
||||
for _, v := range s.references.responses {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -863,6 +942,7 @@ func (s *Spec) AllPathItemReferences() (result []string) {
|
||||
for _, v := range s.references.pathItems {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -874,6 +954,7 @@ func (s *Spec) AllItemsReferences() (result []string) {
|
||||
for _, v := range s.references.items {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -882,6 +963,7 @@ func (s *Spec) AllReferences() (result []string) {
|
||||
for _, v := range s.references.allRefs {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -893,11 +975,13 @@ func (s *Spec) AllRefs() (result []spec.Ref) {
|
||||
if a == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := set[a]; !ok {
|
||||
set[a] = struct{}{}
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -906,6 +990,7 @@ func cloneStringMap(source map[string]string) map[string]string {
|
||||
for k, v := range source {
|
||||
res[k] = v
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -914,6 +999,7 @@ func cloneEnumMap(source map[string][]interface{}) map[string][]interface{} {
|
||||
for k, v := range source {
|
||||
res[k] = v
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
5
vendor/github.com/go-openapi/analysis/appveyor.yml
generated
vendored
5
vendor/github.com/go-openapi/analysis/appveyor.yml
generated
vendored
@@ -14,12 +14,11 @@ build: off
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
|
||||
stack: go 1.12
|
||||
stack: go 1.16
|
||||
|
||||
test_script:
|
||||
- go test -v -timeout 20m ./...
|
||||
#artifacts:
|
||||
# - path: '%GOPATH%\bin\*.exe'
|
||||
|
||||
deploy: off
|
||||
|
||||
notifications:
|
||||
|
||||
30
vendor/github.com/go-openapi/analysis/debug.go
generated
vendored
30
vendor/github.com/go-openapi/analysis/debug.go
generated
vendored
@@ -15,33 +15,9 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/debug"
|
||||
)
|
||||
|
||||
var (
|
||||
// Debug is true when the SWAGGER_DEBUG env var is not empty.
|
||||
// It enables a more verbose logging of the spec analyzer.
|
||||
Debug = os.Getenv("SWAGGER_DEBUG") != ""
|
||||
// analysisLogger is a debug logger for this package
|
||||
analysisLogger *log.Logger
|
||||
)
|
||||
|
||||
func init() {
|
||||
debugOptions()
|
||||
}
|
||||
|
||||
func debugOptions() {
|
||||
analysisLogger = log.New(os.Stdout, "analysis:", log.LstdFlags)
|
||||
}
|
||||
|
||||
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)
|
||||
analysisLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
}
|
||||
var debugLog = debug.GetLogger("analysis", os.Getenv("SWAGGER_DEBUG") != "")
|
||||
|
||||
57
vendor/github.com/go-openapi/analysis/fixer.go
generated
vendored
57
vendor/github.com/go-openapi/analysis/fixer.go
generated
vendored
@@ -24,35 +24,38 @@ import "github.com/go-openapi/spec"
|
||||
// due to zero values being omitted upon re-serializing (omitempty) we
|
||||
// lose them unless we stick some chars in there.
|
||||
func FixEmptyResponseDescriptions(s *spec.Swagger) {
|
||||
if s.Paths != nil {
|
||||
for _, v := range s.Paths.Paths {
|
||||
if v.Get != nil {
|
||||
FixEmptyDescs(v.Get.Responses)
|
||||
}
|
||||
if v.Put != nil {
|
||||
FixEmptyDescs(v.Put.Responses)
|
||||
}
|
||||
if v.Post != nil {
|
||||
FixEmptyDescs(v.Post.Responses)
|
||||
}
|
||||
if v.Delete != nil {
|
||||
FixEmptyDescs(v.Delete.Responses)
|
||||
}
|
||||
if v.Options != nil {
|
||||
FixEmptyDescs(v.Options.Responses)
|
||||
}
|
||||
if v.Head != nil {
|
||||
FixEmptyDescs(v.Head.Responses)
|
||||
}
|
||||
if v.Patch != nil {
|
||||
FixEmptyDescs(v.Patch.Responses)
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, v := range s.Responses {
|
||||
FixEmptyDesc(&v)
|
||||
FixEmptyDesc(&v) //#nosec
|
||||
s.Responses[k] = v
|
||||
}
|
||||
|
||||
if s.Paths == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range s.Paths.Paths {
|
||||
if v.Get != nil {
|
||||
FixEmptyDescs(v.Get.Responses)
|
||||
}
|
||||
if v.Put != nil {
|
||||
FixEmptyDescs(v.Put.Responses)
|
||||
}
|
||||
if v.Post != nil {
|
||||
FixEmptyDescs(v.Post.Responses)
|
||||
}
|
||||
if v.Delete != nil {
|
||||
FixEmptyDescs(v.Delete.Responses)
|
||||
}
|
||||
if v.Options != nil {
|
||||
FixEmptyDescs(v.Options.Responses)
|
||||
}
|
||||
if v.Head != nil {
|
||||
FixEmptyDescs(v.Head.Responses)
|
||||
}
|
||||
if v.Patch != nil {
|
||||
FixEmptyDescs(v.Patch.Responses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FixEmptyDescs adds "(empty)" as the description for any Response in
|
||||
@@ -60,7 +63,7 @@ func FixEmptyResponseDescriptions(s *spec.Swagger) {
|
||||
func FixEmptyDescs(rs *spec.Responses) {
|
||||
FixEmptyDesc(rs.Default)
|
||||
for k, v := range rs.StatusCodeResponses {
|
||||
FixEmptyDesc(&v)
|
||||
FixEmptyDesc(&v) //#nosec
|
||||
rs.StatusCodeResponses[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
1849
vendor/github.com/go-openapi/analysis/flatten.go
generated
vendored
1849
vendor/github.com/go-openapi/analysis/flatten.go
generated
vendored
File diff suppressed because it is too large
Load Diff
293
vendor/github.com/go-openapi/analysis/flatten_name.go
generated
vendored
Normal file
293
vendor/github.com/go-openapi/analysis/flatten_name.go
generated
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/flatten/operations"
|
||||
"github.com/go-openapi/analysis/internal/flatten/replace"
|
||||
"github.com/go-openapi/analysis/internal/flatten/schutils"
|
||||
"github.com/go-openapi/analysis/internal/flatten/sortref"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// InlineSchemaNamer finds a new name for an inlined type
|
||||
type InlineSchemaNamer struct {
|
||||
Spec *spec.Swagger
|
||||
Operations map[string]operations.OpRef
|
||||
flattenContext *context
|
||||
opts *FlattenOpts
|
||||
}
|
||||
|
||||
// Name yields a new name for the inline schema
|
||||
func (isn *InlineSchemaNamer) Name(key string, schema *spec.Schema, aschema *AnalyzedSchema) error {
|
||||
debugLog("naming inlined schema at %s", key)
|
||||
|
||||
parts := sortref.KeyParts(key)
|
||||
for _, name := range namesFromKey(parts, aschema, isn.Operations) {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// create unique name
|
||||
newName, isOAIGen := uniqifyName(isn.Spec.Definitions, swag.ToJSONName(name))
|
||||
|
||||
// clone schema
|
||||
sch := schutils.Clone(schema)
|
||||
|
||||
// replace values on schema
|
||||
if err := replace.RewriteSchemaToRef(isn.Spec, key,
|
||||
spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil {
|
||||
return fmt.Errorf("error while creating definition %q from inline schema: %w", newName, err)
|
||||
}
|
||||
|
||||
// rewrite any dependent $ref pointing to this place,
|
||||
// when not already pointing to a top-level definition.
|
||||
//
|
||||
// NOTE: this is important if such referers use arbitrary JSON pointers.
|
||||
an := New(isn.Spec)
|
||||
for k, v := range an.references.allRefs {
|
||||
r, erd := replace.DeepestRef(isn.opts.Swagger(), isn.opts.ExpandOpts(false), v)
|
||||
if erd != nil {
|
||||
return fmt.Errorf("at %s, %w", k, erd)
|
||||
}
|
||||
|
||||
if isn.opts.flattenContext != nil {
|
||||
isn.opts.flattenContext.warnings = append(isn.opts.flattenContext.warnings, r.Warnings...)
|
||||
}
|
||||
|
||||
if r.Ref.String() != key && (r.Ref.String() != path.Join(definitionsPath, newName) || path.Dir(v.String()) == definitionsPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
debugLog("found a $ref to a rewritten schema: %s points to %s", k, v.String())
|
||||
|
||||
// rewrite $ref to the new target
|
||||
if err := replace.UpdateRef(isn.Spec, k,
|
||||
spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this extension is currently not used by go-swagger (provided for information only)
|
||||
sch.AddExtension("x-go-gen-location", GenLocation(parts))
|
||||
|
||||
// save cloned schema to definitions
|
||||
schutils.Save(isn.Spec, newName, sch)
|
||||
|
||||
// keep track of created refs
|
||||
if isn.flattenContext == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
debugLog("track created ref: key=%s, newName=%s, isOAIGen=%t", key, newName, isOAIGen)
|
||||
resolved := false
|
||||
|
||||
if _, ok := isn.flattenContext.newRefs[key]; ok {
|
||||
resolved = isn.flattenContext.newRefs[key].resolved
|
||||
}
|
||||
|
||||
isn.flattenContext.newRefs[key] = &newRef{
|
||||
key: key,
|
||||
newName: newName,
|
||||
path: path.Join(definitionsPath, newName),
|
||||
isOAIGen: isOAIGen,
|
||||
resolved: resolved,
|
||||
schema: sch,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// uniqifyName yields a unique name for a definition
|
||||
func uniqifyName(definitions spec.Definitions, name string) (string, bool) {
|
||||
isOAIGen := false
|
||||
if name == "" {
|
||||
name = "oaiGen"
|
||||
isOAIGen = true
|
||||
}
|
||||
|
||||
if len(definitions) == 0 {
|
||||
return name, isOAIGen
|
||||
}
|
||||
|
||||
unq := true
|
||||
for k := range definitions {
|
||||
if strings.EqualFold(k, name) {
|
||||
unq = false
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if unq {
|
||||
return name, isOAIGen
|
||||
}
|
||||
|
||||
name += "OAIGen"
|
||||
isOAIGen = true
|
||||
var idx int
|
||||
unique := name
|
||||
_, known := definitions[unique]
|
||||
|
||||
for known {
|
||||
idx++
|
||||
unique = fmt.Sprintf("%s%d", name, idx)
|
||||
_, known = definitions[unique]
|
||||
}
|
||||
|
||||
return unique, isOAIGen
|
||||
}
|
||||
|
||||
func namesFromKey(parts sortref.SplitKey, aschema *AnalyzedSchema, operations map[string]operations.OpRef) []string {
|
||||
var (
|
||||
baseNames [][]string
|
||||
startIndex int
|
||||
)
|
||||
|
||||
if parts.IsOperation() {
|
||||
baseNames, startIndex = namesForOperation(parts, operations)
|
||||
}
|
||||
|
||||
// definitions
|
||||
if parts.IsDefinition() {
|
||||
baseNames, startIndex = namesForDefinition(parts)
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(baseNames))
|
||||
for _, segments := range baseNames {
|
||||
nm := parts.BuildName(segments, startIndex, partAdder(aschema))
|
||||
if nm == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, nm)
|
||||
}
|
||||
sort.Strings(result)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func namesForParam(parts sortref.SplitKey, operations map[string]operations.OpRef) ([][]string, int) {
|
||||
var (
|
||||
baseNames [][]string
|
||||
startIndex int
|
||||
)
|
||||
|
||||
piref := parts.PathItemRef()
|
||||
if piref.String() != "" && parts.IsOperationParam() {
|
||||
if op, ok := operations[piref.String()]; ok {
|
||||
startIndex = 5
|
||||
baseNames = append(baseNames, []string{op.ID, "params", "body"})
|
||||
}
|
||||
} else if parts.IsSharedOperationParam() {
|
||||
pref := parts.PathRef()
|
||||
for k, v := range operations {
|
||||
if strings.HasPrefix(k, pref.String()) {
|
||||
startIndex = 4
|
||||
baseNames = append(baseNames, []string{v.ID, "params", "body"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return baseNames, startIndex
|
||||
}
|
||||
|
||||
func namesForOperation(parts sortref.SplitKey, operations map[string]operations.OpRef) ([][]string, int) {
|
||||
var (
|
||||
baseNames [][]string
|
||||
startIndex int
|
||||
)
|
||||
|
||||
// params
|
||||
if parts.IsOperationParam() || parts.IsSharedOperationParam() {
|
||||
baseNames, startIndex = namesForParam(parts, operations)
|
||||
}
|
||||
|
||||
// responses
|
||||
if parts.IsOperationResponse() {
|
||||
piref := parts.PathItemRef()
|
||||
if piref.String() != "" {
|
||||
if op, ok := operations[piref.String()]; ok {
|
||||
startIndex = 6
|
||||
baseNames = append(baseNames, []string{op.ID, parts.ResponseName(), "body"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return baseNames, startIndex
|
||||
}
|
||||
|
||||
func namesForDefinition(parts sortref.SplitKey) ([][]string, int) {
|
||||
nm := parts.DefinitionName()
|
||||
if nm != "" {
|
||||
return [][]string{{parts.DefinitionName()}}, 2
|
||||
}
|
||||
|
||||
return [][]string{}, 0
|
||||
}
|
||||
|
||||
// partAdder knows how to interpret a schema when it comes to build a name from parts
|
||||
func partAdder(aschema *AnalyzedSchema) sortref.PartAdder {
|
||||
return func(part string) []string {
|
||||
segments := make([]string, 0, 2)
|
||||
|
||||
if part == "items" || part == "additionalItems" {
|
||||
if aschema.IsTuple || aschema.IsTupleWithExtra {
|
||||
segments = append(segments, "tuple")
|
||||
} else {
|
||||
segments = append(segments, "items")
|
||||
}
|
||||
|
||||
if part == "additionalItems" {
|
||||
segments = append(segments, part)
|
||||
}
|
||||
|
||||
return segments
|
||||
}
|
||||
|
||||
segments = append(segments, part)
|
||||
|
||||
return segments
|
||||
}
|
||||
}
|
||||
|
||||
func nameFromRef(ref spec.Ref) string {
|
||||
u := ref.GetURL()
|
||||
if u.Fragment != "" {
|
||||
return swag.ToJSONName(path.Base(u.Fragment))
|
||||
}
|
||||
|
||||
if u.Path != "" {
|
||||
bn := path.Base(u.Path)
|
||||
if bn != "" && bn != "/" {
|
||||
ext := path.Ext(bn)
|
||||
if ext != "" {
|
||||
return swag.ToJSONName(bn[:len(bn)-len(ext)])
|
||||
}
|
||||
|
||||
return swag.ToJSONName(bn)
|
||||
}
|
||||
}
|
||||
|
||||
return swag.ToJSONName(strings.ReplaceAll(u.Host, ".", " "))
|
||||
}
|
||||
|
||||
// GenLocation indicates from which section of the specification (models or operations) a definition has been created.
|
||||
//
|
||||
// This is reflected in the output spec with a "x-go-gen-location" extension. At the moment, this is is provided
|
||||
// for information only.
|
||||
func GenLocation(parts sortref.SplitKey) string {
|
||||
switch {
|
||||
case parts.IsOperation():
|
||||
return "operations"
|
||||
case parts.IsDefinition():
|
||||
return "models"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
78
vendor/github.com/go-openapi/analysis/flatten_options.go
generated
vendored
Normal file
78
vendor/github.com/go-openapi/analysis/flatten_options.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
// FlattenOpts configuration for flattening a swagger specification.
|
||||
//
|
||||
// The BasePath parameter is used to locate remote relative $ref found in the specification.
|
||||
// This path is a file: it points to the location of the root document and may be either a local
|
||||
// file path or a URL.
|
||||
//
|
||||
// If none specified, relative references (e.g. "$ref": "folder/schema.yaml#/definitions/...")
|
||||
// found in the spec are searched from the current working directory.
|
||||
type FlattenOpts struct {
|
||||
Spec *Spec // The analyzed spec to work with
|
||||
flattenContext *context // Internal context to track flattening activity
|
||||
|
||||
BasePath string // The location of the root document for this spec to resolve relative $ref
|
||||
|
||||
// Flattening options
|
||||
Expand bool // When true, skip flattening the spec and expand it instead (if Minimal is false)
|
||||
Minimal bool // When true, do not decompose complex structures such as allOf
|
||||
Verbose bool // enable some reporting on possible name conflicts detected
|
||||
RemoveUnused bool // When true, remove unused parameters, responses and definitions after expansion/flattening
|
||||
ContinueOnError bool // Continue when spec expansion issues are found
|
||||
|
||||
/* Extra keys */
|
||||
_ struct{} // require keys
|
||||
}
|
||||
|
||||
// ExpandOpts creates a spec.ExpandOptions to configure expanding a specification document.
|
||||
func (f *FlattenOpts) ExpandOpts(skipSchemas bool) *spec.ExpandOptions {
|
||||
return &spec.ExpandOptions{
|
||||
RelativeBase: f.BasePath,
|
||||
SkipSchemas: skipSchemas,
|
||||
ContinueOnError: f.ContinueOnError,
|
||||
}
|
||||
}
|
||||
|
||||
// Swagger gets the swagger specification for this flatten operation
|
||||
func (f *FlattenOpts) Swagger() *spec.Swagger {
|
||||
return f.Spec.spec
|
||||
}
|
||||
|
||||
// croak logs notifications and warnings about valid, but possibly unwanted constructs resulting
|
||||
// from flattening a spec
|
||||
func (f *FlattenOpts) croak() {
|
||||
if !f.Verbose {
|
||||
return
|
||||
}
|
||||
|
||||
reported := make(map[string]bool, len(f.flattenContext.newRefs))
|
||||
for _, v := range f.Spec.references.allRefs {
|
||||
// warns about duplicate handling
|
||||
for _, r := range f.flattenContext.newRefs {
|
||||
if r.isOAIGen && r.path == v.String() {
|
||||
reported[r.newName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k := range reported {
|
||||
log.Printf("warning: duplicate flattened definition name resolved as %s", k)
|
||||
}
|
||||
|
||||
// warns about possible type mismatches
|
||||
uniqueMsg := make(map[string]bool)
|
||||
for _, msg := range f.flattenContext.warnings {
|
||||
if _, ok := uniqueMsg[msg]; ok {
|
||||
continue
|
||||
}
|
||||
log.Printf("warning: %s", msg)
|
||||
uniqueMsg[msg] = true
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
// +build go1.8
|
||||
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,16 +12,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package internal
|
||||
package debug
|
||||
|
||||
import "net/url"
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// PathUnescape provides url.PathUnescape(), with seamless
|
||||
// go version support for pre-go1.8
|
||||
//
|
||||
// TODO: this function is currently defined in go-openapi/swag,
|
||||
// but unexported. We might chose to export it, or simple phase
|
||||
// out pre-go1.8 support.
|
||||
func PathUnescape(path string) (string, error) {
|
||||
return url.PathUnescape(path)
|
||||
var (
|
||||
output = os.Stdout
|
||||
)
|
||||
|
||||
// GetLogger provides a prefix debug logger
|
||||
func GetLogger(prefix string, debug bool) func(string, ...interface{}) {
|
||||
if debug {
|
||||
logger := log.New(output, fmt.Sprintf("%s:", prefix), log.LstdFlags)
|
||||
|
||||
return func(msg string, args ...interface{}) {
|
||||
_, file1, pos1, _ := runtime.Caller(1)
|
||||
logger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
}
|
||||
|
||||
return func(msg string, args ...interface{}) {}
|
||||
}
|
||||
87
vendor/github.com/go-openapi/analysis/internal/flatten/normalize/normalize.go
generated
vendored
Normal file
87
vendor/github.com/go-openapi/analysis/internal/flatten/normalize/normalize.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
package normalize
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
// RebaseRef rebases a remote ref relative to a base ref.
|
||||
//
|
||||
// NOTE: does not support JSONschema ID for $ref (we assume we are working with swagger specs here).
|
||||
//
|
||||
// NOTE(windows):
|
||||
// * refs are assumed to have been normalized with drive letter lower cased (from go-openapi/spec)
|
||||
// * "/ in paths may appear as escape sequences
|
||||
func RebaseRef(baseRef string, ref string) string {
|
||||
baseRef, _ = url.PathUnescape(baseRef)
|
||||
ref, _ = url.PathUnescape(ref)
|
||||
|
||||
if baseRef == "" || baseRef == "." || strings.HasPrefix(baseRef, "#") {
|
||||
return ref
|
||||
}
|
||||
|
||||
parts := strings.Split(ref, "#")
|
||||
|
||||
baseParts := strings.Split(baseRef, "#")
|
||||
baseURL, _ := url.Parse(baseParts[0])
|
||||
if strings.HasPrefix(ref, "#") {
|
||||
if baseURL.Host == "" {
|
||||
return strings.Join([]string{baseParts[0], parts[1]}, "#")
|
||||
}
|
||||
|
||||
return strings.Join([]string{baseParts[0], parts[1]}, "#")
|
||||
}
|
||||
|
||||
refURL, _ := url.Parse(parts[0])
|
||||
if refURL.Host != "" || filepath.IsAbs(parts[0]) {
|
||||
// not rebasing an absolute path
|
||||
return ref
|
||||
}
|
||||
|
||||
// there is a relative path
|
||||
var basePath string
|
||||
if baseURL.Host != "" {
|
||||
// when there is a host, standard URI rules apply (with "/")
|
||||
baseURL.Path = path.Dir(baseURL.Path)
|
||||
baseURL.Path = path.Join(baseURL.Path, "/"+parts[0])
|
||||
|
||||
return baseURL.String()
|
||||
}
|
||||
|
||||
// this is a local relative path
|
||||
// basePart[0] and parts[0] are local filesystem directories/files
|
||||
basePath = filepath.Dir(baseParts[0])
|
||||
relPath := filepath.Join(basePath, string(filepath.Separator)+parts[0])
|
||||
if len(parts) > 1 {
|
||||
return strings.Join([]string{relPath, parts[1]}, "#")
|
||||
}
|
||||
|
||||
return relPath
|
||||
}
|
||||
|
||||
// Path renders absolute path on remote file refs
|
||||
//
|
||||
// NOTE(windows):
|
||||
// * refs are assumed to have been normalized with drive letter lower cased (from go-openapi/spec)
|
||||
// * "/ in paths may appear as escape sequences
|
||||
func Path(ref spec.Ref, basePath string) string {
|
||||
uri, _ := url.PathUnescape(ref.String())
|
||||
if ref.HasFragmentOnly || filepath.IsAbs(uri) {
|
||||
return uri
|
||||
}
|
||||
|
||||
refURL, _ := url.Parse(uri)
|
||||
if refURL.Host != "" {
|
||||
return uri
|
||||
}
|
||||
|
||||
parts := strings.Split(uri, "#")
|
||||
// BasePath, parts[0] are local filesystem directories, guaranteed to be absolute at this stage
|
||||
parts[0] = filepath.Join(filepath.Dir(basePath), parts[0])
|
||||
|
||||
return strings.Join(parts, "#")
|
||||
}
|
||||
90
vendor/github.com/go-openapi/analysis/internal/flatten/operations/operations.go
generated
vendored
Normal file
90
vendor/github.com/go-openapi/analysis/internal/flatten/operations/operations.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// AllOpRefsByRef returns an index of sortable operations
|
||||
func AllOpRefsByRef(specDoc Provider, operationIDs []string) map[string]OpRef {
|
||||
return OpRefsByRef(GatherOperations(specDoc, operationIDs))
|
||||
}
|
||||
|
||||
// OpRefsByRef indexes a map of sortable operations
|
||||
func OpRefsByRef(oprefs map[string]OpRef) map[string]OpRef {
|
||||
result := make(map[string]OpRef, len(oprefs))
|
||||
for _, v := range oprefs {
|
||||
result[v.Ref.String()] = v
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// OpRef is an indexable, sortable operation
|
||||
type OpRef struct {
|
||||
Method string
|
||||
Path string
|
||||
Key string
|
||||
ID string
|
||||
Op *spec.Operation
|
||||
Ref spec.Ref
|
||||
}
|
||||
|
||||
// OpRefs is a sortable collection of operations
|
||||
type OpRefs []OpRef
|
||||
|
||||
func (o OpRefs) Len() int { return len(o) }
|
||||
func (o OpRefs) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
func (o OpRefs) Less(i, j int) bool { return o[i].Key < o[j].Key }
|
||||
|
||||
// Provider knows how to collect operations from a spec
|
||||
type Provider interface {
|
||||
Operations() map[string]map[string]*spec.Operation
|
||||
}
|
||||
|
||||
// GatherOperations builds a map of sorted operations from a spec
|
||||
func GatherOperations(specDoc Provider, operationIDs []string) map[string]OpRef {
|
||||
var oprefs OpRefs
|
||||
|
||||
for method, pathItem := range specDoc.Operations() {
|
||||
for pth, operation := range pathItem {
|
||||
vv := *operation
|
||||
oprefs = append(oprefs, OpRef{
|
||||
Key: swag.ToGoName(strings.ToLower(method) + " " + pth),
|
||||
Method: method,
|
||||
Path: pth,
|
||||
ID: vv.ID,
|
||||
Op: &vv,
|
||||
Ref: spec.MustCreateRef("#" + path.Join("/paths", jsonpointer.Escape(pth), method)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(oprefs)
|
||||
|
||||
operations := make(map[string]OpRef)
|
||||
for _, opr := range oprefs {
|
||||
nm := opr.ID
|
||||
if nm == "" {
|
||||
nm = opr.Key
|
||||
}
|
||||
|
||||
oo, found := operations[nm]
|
||||
if found && oo.Method != opr.Method && oo.Path != opr.Path {
|
||||
nm = opr.Key
|
||||
}
|
||||
|
||||
if len(operationIDs) == 0 || swag.ContainsStrings(operationIDs, opr.ID) || swag.ContainsStrings(operationIDs, nm) {
|
||||
opr.ID = nm
|
||||
opr.Op.ID = nm
|
||||
operations[nm] = opr
|
||||
}
|
||||
}
|
||||
|
||||
return operations
|
||||
}
|
||||
434
vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
generated
vendored
Normal file
434
vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
generated
vendored
Normal file
@@ -0,0 +1,434 @@
|
||||
package replace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/debug"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
const definitionsPath = "#/definitions"
|
||||
|
||||
var debugLog = debug.GetLogger("analysis/flatten/replace", os.Getenv("SWAGGER_DEBUG") != "")
|
||||
|
||||
// RewriteSchemaToRef replaces a schema with a Ref
|
||||
func RewriteSchemaToRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
debugLog("rewriting schema to ref for %s with %s", key, ref.String())
|
||||
_, value, err := getPointerFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
return rewriteParentRef(sp, key, ref)
|
||||
|
||||
case spec.Schema:
|
||||
return rewriteParentRef(sp, key, ref)
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
}
|
||||
|
||||
case *spec.SchemaOrBool:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
parent, entry, pvalue, err := getParentFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
debugLog("rewriting holder for %T", pvalue)
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Response:
|
||||
if err := rewriteParentRef(sp, "#"+parent, ref); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case *spec.Response:
|
||||
container.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case *spec.Responses:
|
||||
statusCode, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
resp := container.StatusCodeResponses[statusCode]
|
||||
resp.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container.StatusCodeResponses[statusCode] = resp
|
||||
|
||||
case map[string]spec.Response:
|
||||
resp := container[entry]
|
||||
resp.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container[entry] = resp
|
||||
|
||||
case spec.Parameter:
|
||||
if err := rewriteParentRef(sp, "#"+parent, ref); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case map[string]spec.Parameter:
|
||||
param := container[entry]
|
||||
param.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container[entry] = param
|
||||
|
||||
case []spec.Parameter:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
param := container[idx]
|
||||
param.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container[idx] = param
|
||||
|
||||
case spec.Definitions:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case map[string]spec.Schema:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
container[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
container.Schemas[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case spec.SchemaProperties:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled parent schema rewrite %s (%T)", key, pvalue)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPointerFromKey retrieves the content of the JSON pointer "key"
|
||||
func getPointerFromKey(sp interface{}, key string) (string, interface{}, error) {
|
||||
switch sp.(type) {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
}
|
||||
if key == "#/" {
|
||||
return "", sp, nil
|
||||
}
|
||||
// unescape chars in key, e.g. "{}" from path params
|
||||
pth, _ := url.PathUnescape(key[1:])
|
||||
ptr, err := jsonpointer.New(pth)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
value, _, err := ptr.Get(sp)
|
||||
if err != nil {
|
||||
debugLog("error when getting key: %s with path: %s", key, pth)
|
||||
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return pth, value, nil
|
||||
}
|
||||
|
||||
// getParentFromKey retrieves the container of the JSON pointer "key"
|
||||
func getParentFromKey(sp interface{}, key string) (string, string, interface{}, error) {
|
||||
switch sp.(type) {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
}
|
||||
// unescape chars in key, e.g. "{}" from path params
|
||||
pth, _ := url.PathUnescape(key[1:])
|
||||
|
||||
parent, entry := path.Dir(pth), path.Base(pth)
|
||||
debugLog("getting schema holder at: %s, with entry: %s", parent, entry)
|
||||
|
||||
pptr, err := jsonpointer.New(parent)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
pvalue, _, err := pptr.Get(sp)
|
||||
if err != nil {
|
||||
return "", "", nil, fmt.Errorf("can't get parent for %s: %w", parent, err)
|
||||
}
|
||||
|
||||
return parent, entry, pvalue, nil
|
||||
}
|
||||
|
||||
// UpdateRef replaces a ref by another one
|
||||
func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
switch sp.(type) {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
}
|
||||
debugLog("updating ref for %s with %s", key, ref.String())
|
||||
pth, value, err := getPointerFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
refable.Ref = ref
|
||||
case *spec.SchemaOrArray:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema.Ref = ref
|
||||
}
|
||||
case *spec.SchemaOrBool:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema.Ref = ref
|
||||
}
|
||||
case spec.Schema:
|
||||
debugLog("rewriting holder for %T", refable)
|
||||
_, entry, pvalue, erp := getParentFromKey(sp, key)
|
||||
if erp != nil {
|
||||
return err
|
||||
}
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Definitions:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case map[string]spec.Schema:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container.Schemas[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case spec.SchemaProperties:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled container type at %s: %T", key, value)
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateRefWithSchema replaces a ref with a schema (i.e. re-inline schema)
|
||||
func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
debugLog("updating ref for %s with schema", key)
|
||||
pth, value, err := getPointerFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
*refable = *sch
|
||||
case spec.Schema:
|
||||
_, entry, pvalue, erp := getParentFromKey(sp, key)
|
||||
if erp != nil {
|
||||
return err
|
||||
}
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Definitions:
|
||||
container[entry] = *sch
|
||||
|
||||
case map[string]spec.Schema:
|
||||
container[entry] = *sch
|
||||
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container[idx] = *sch
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container.Schemas[idx] = *sch
|
||||
|
||||
case spec.SchemaProperties:
|
||||
container[entry] = *sch
|
||||
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled type for parent of [%s]: %T", key, value)
|
||||
}
|
||||
case *spec.SchemaOrArray:
|
||||
*refable.Schema = *sch
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
case *spec.SchemaOrBool:
|
||||
*refable.Schema = *sch
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepestRefResult holds the results from DeepestRef analysis
|
||||
type DeepestRefResult struct {
|
||||
Ref spec.Ref
|
||||
Schema *spec.Schema
|
||||
Warnings []string
|
||||
}
|
||||
|
||||
// DeepestRef finds the first definition ref, from a cascade of nested refs which are not definitions.
|
||||
// - if no definition is found, returns the deepest ref.
|
||||
// - pointers to external files are expanded
|
||||
//
|
||||
// NOTE: all external $ref's are assumed to be already expanded at this stage.
|
||||
func DeepestRef(sp *spec.Swagger, opts *spec.ExpandOptions, ref spec.Ref) (*DeepestRefResult, error) {
|
||||
if !ref.HasFragmentOnly {
|
||||
// we found an external $ref, which is odd at this stage:
|
||||
// do nothing on external $refs
|
||||
return &DeepestRefResult{Ref: ref}, nil
|
||||
}
|
||||
|
||||
currentRef := ref
|
||||
visited := make(map[string]bool, 64)
|
||||
warnings := make([]string, 0, 2)
|
||||
|
||||
DOWNREF:
|
||||
for currentRef.String() != "" {
|
||||
if path.Dir(currentRef.String()) == definitionsPath {
|
||||
// this is a top-level definition: stop here and return this ref
|
||||
return &DeepestRefResult{Ref: currentRef}, nil
|
||||
}
|
||||
|
||||
if _, beenThere := visited[currentRef.String()]; beenThere {
|
||||
return nil,
|
||||
fmt.Errorf("cannot resolve cyclic chain of pointers under %s", currentRef.String())
|
||||
}
|
||||
|
||||
visited[currentRef.String()] = true
|
||||
value, _, err := currentRef.GetPointer().Get(sp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
if refable.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Ref
|
||||
|
||||
case spec.Schema:
|
||||
if refable.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Ref
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
if refable.Schema == nil || refable.Schema != nil && refable.Schema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Schema.Ref
|
||||
|
||||
case *spec.SchemaOrBool:
|
||||
if refable.Schema == nil || refable.Schema != nil && refable.Schema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Schema.Ref
|
||||
|
||||
case spec.Response:
|
||||
// a pointer points to a schema initially marshalled in responses section...
|
||||
// Attempt to convert this to a schema. If this fails, the spec is invalid
|
||||
asJSON, _ := refable.MarshalJSON()
|
||||
var asSchema spec.Schema
|
||||
|
||||
err := asSchema.UnmarshalJSON(asJSON)
|
||||
if err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
|
||||
currentRef.String(), value)
|
||||
}
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (response) interpreted as schema", currentRef.String()))
|
||||
|
||||
if asSchema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = asSchema.Ref
|
||||
|
||||
case spec.Parameter:
|
||||
// a pointer points to a schema initially marshalled in parameters section...
|
||||
// Attempt to convert this to a schema. If this fails, the spec is invalid
|
||||
asJSON, _ := refable.MarshalJSON()
|
||||
var asSchema spec.Schema
|
||||
if err := asSchema.UnmarshalJSON(asJSON); err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
|
||||
currentRef.String(), value)
|
||||
}
|
||||
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (parameter) interpreted as schema", currentRef.String()))
|
||||
|
||||
if asSchema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = asSchema.Ref
|
||||
|
||||
default:
|
||||
return nil,
|
||||
fmt.Errorf("unhandled type to resolve JSON pointer %s. Expected a Schema, got: %T",
|
||||
currentRef.String(), value)
|
||||
}
|
||||
}
|
||||
|
||||
// assess what schema we're ending with
|
||||
sch, erv := spec.ResolveRefWithBase(sp, ¤tRef, opts)
|
||||
if erv != nil {
|
||||
return nil, erv
|
||||
}
|
||||
|
||||
if sch == nil {
|
||||
return nil, fmt.Errorf("no schema found at %s", currentRef.String())
|
||||
}
|
||||
|
||||
return &DeepestRefResult{Ref: currentRef, Schema: sch, Warnings: warnings}, nil
|
||||
}
|
||||
29
vendor/github.com/go-openapi/analysis/internal/flatten/schutils/flatten_schema.go
generated
vendored
Normal file
29
vendor/github.com/go-openapi/analysis/internal/flatten/schutils/flatten_schema.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Package schutils provides tools to save or clone a schema
|
||||
// when flattening a spec.
|
||||
package schutils
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Save registers a schema as an entry in spec #/definitions
|
||||
func Save(sp *spec.Swagger, name string, schema *spec.Schema) {
|
||||
if schema == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if sp.Definitions == nil {
|
||||
sp.Definitions = make(map[string]spec.Schema, 150)
|
||||
}
|
||||
|
||||
sp.Definitions[name] = *schema
|
||||
}
|
||||
|
||||
// Clone deep-clones a schema
|
||||
func Clone(schema *spec.Schema) *spec.Schema {
|
||||
var sch spec.Schema
|
||||
_ = swag.FromDynamicJSON(schema, &sch)
|
||||
|
||||
return &sch
|
||||
}
|
||||
201
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
generated
vendored
Normal file
201
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
package sortref
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
const (
|
||||
paths = "paths"
|
||||
responses = "responses"
|
||||
parameters = "parameters"
|
||||
definitions = "definitions"
|
||||
)
|
||||
|
||||
var (
|
||||
ignoredKeys map[string]struct{}
|
||||
validMethods map[string]struct{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
ignoredKeys = map[string]struct{}{
|
||||
"schema": {},
|
||||
"properties": {},
|
||||
"not": {},
|
||||
"anyOf": {},
|
||||
"oneOf": {},
|
||||
}
|
||||
|
||||
validMethods = map[string]struct{}{
|
||||
"GET": {},
|
||||
"HEAD": {},
|
||||
"OPTIONS": {},
|
||||
"PATCH": {},
|
||||
"POST": {},
|
||||
"PUT": {},
|
||||
"DELETE": {},
|
||||
}
|
||||
}
|
||||
|
||||
// Key represent a key item constructed from /-separated segments
|
||||
type Key struct {
|
||||
Segments int
|
||||
Key string
|
||||
}
|
||||
|
||||
// Keys is a sortable collable collection of Keys
|
||||
type Keys []Key
|
||||
|
||||
func (k Keys) Len() int { return len(k) }
|
||||
func (k Keys) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
|
||||
func (k Keys) Less(i, j int) bool {
|
||||
return k[i].Segments > k[j].Segments || (k[i].Segments == k[j].Segments && k[i].Key < k[j].Key)
|
||||
}
|
||||
|
||||
// KeyParts construct a SplitKey with all its /-separated segments decomposed. It is sortable.
|
||||
func KeyParts(key string) SplitKey {
|
||||
var res []string
|
||||
for _, part := range strings.Split(key[1:], "/") {
|
||||
if part != "" {
|
||||
res = append(res, jsonpointer.Unescape(part))
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SplitKey holds of the parts of a /-separated key, soi that their location may be determined.
|
||||
type SplitKey []string
|
||||
|
||||
// IsDefinition is true when the split key is in the #/definitions section of a spec
|
||||
func (s SplitKey) IsDefinition() bool {
|
||||
return len(s) > 1 && s[0] == definitions
|
||||
}
|
||||
|
||||
// DefinitionName yields the name of the definition
|
||||
func (s SplitKey) DefinitionName() string {
|
||||
if !s.IsDefinition() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s[1]
|
||||
}
|
||||
|
||||
func (s SplitKey) isKeyName(i int) bool {
|
||||
if i <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
count := 0
|
||||
for idx := i - 1; idx > 0; idx-- {
|
||||
if s[idx] != "properties" {
|
||||
break
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
return count%2 != 0
|
||||
}
|
||||
|
||||
// PartAdder know how to construct the components of a new name
|
||||
type PartAdder func(string) []string
|
||||
|
||||
// BuildName builds a name from segments
|
||||
func (s SplitKey) BuildName(segments []string, startIndex int, adder PartAdder) string {
|
||||
for i, part := range s[startIndex:] {
|
||||
if _, ignored := ignoredKeys[part]; !ignored || s.isKeyName(startIndex+i) {
|
||||
segments = append(segments, adder(part)...)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(segments, " ")
|
||||
}
|
||||
|
||||
// IsOperation is true when the split key is in the operations section
|
||||
func (s SplitKey) IsOperation() bool {
|
||||
return len(s) > 1 && s[0] == paths
|
||||
}
|
||||
|
||||
// IsSharedOperationParam is true when the split key is in the parameters section of a path
|
||||
func (s SplitKey) IsSharedOperationParam() bool {
|
||||
return len(s) > 2 && s[0] == paths && s[2] == parameters
|
||||
}
|
||||
|
||||
// IsSharedParam is true when the split key is in the #/parameters section of a spec
|
||||
func (s SplitKey) IsSharedParam() bool {
|
||||
return len(s) > 1 && s[0] == parameters
|
||||
}
|
||||
|
||||
// IsOperationParam is true when the split key is in the parameters section of an operation
|
||||
func (s SplitKey) IsOperationParam() bool {
|
||||
return len(s) > 3 && s[0] == paths && s[3] == parameters
|
||||
}
|
||||
|
||||
// IsOperationResponse is true when the split key is in the responses section of an operation
|
||||
func (s SplitKey) IsOperationResponse() bool {
|
||||
return len(s) > 3 && s[0] == paths && s[3] == responses
|
||||
}
|
||||
|
||||
// IsSharedResponse is true when the split key is in the #/responses section of a spec
|
||||
func (s SplitKey) IsSharedResponse() bool {
|
||||
return len(s) > 1 && s[0] == responses
|
||||
}
|
||||
|
||||
// IsDefaultResponse is true when the split key is the default response for an operation
|
||||
func (s SplitKey) IsDefaultResponse() bool {
|
||||
return len(s) > 4 && s[0] == paths && s[3] == responses && s[4] == "default"
|
||||
}
|
||||
|
||||
// IsStatusCodeResponse is true when the split key is an operation response with a status code
|
||||
func (s SplitKey) IsStatusCodeResponse() bool {
|
||||
isInt := func() bool {
|
||||
_, err := strconv.Atoi(s[4])
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
return len(s) > 4 && s[0] == paths && s[3] == responses && isInt()
|
||||
}
|
||||
|
||||
// ResponseName yields either the status code or "Default" for a response
|
||||
func (s SplitKey) ResponseName() string {
|
||||
if s.IsStatusCodeResponse() {
|
||||
code, _ := strconv.Atoi(s[4])
|
||||
|
||||
return http.StatusText(code)
|
||||
}
|
||||
|
||||
if s.IsDefaultResponse() {
|
||||
return "Default"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// PathItemRef constructs a $ref object from a split key of the form /{path}/{method}
|
||||
func (s SplitKey) PathItemRef() spec.Ref {
|
||||
if len(s) < 3 {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
pth, method := s[1], s[2]
|
||||
if _, isValidMethod := validMethods[strings.ToUpper(method)]; !isValidMethod && !strings.HasPrefix(method, "x-") {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
return spec.MustCreateRef("#" + path.Join("/", paths, jsonpointer.Escape(pth), strings.ToUpper(method)))
|
||||
}
|
||||
|
||||
// PathRef constructs a $ref object from a split key of the form /paths/{reference}
|
||||
func (s SplitKey) PathRef() spec.Ref {
|
||||
if !s.IsOperation() {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
return spec.MustCreateRef("#" + path.Join("/", paths, jsonpointer.Escape(s[1])))
|
||||
}
|
||||
141
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/sort_ref.go
generated
vendored
Normal file
141
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/sort_ref.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
package sortref
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/flatten/normalize"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
var depthGroupOrder = []string{
|
||||
"sharedParam", "sharedResponse", "sharedOpParam", "opParam", "codeResponse", "defaultResponse", "definition",
|
||||
}
|
||||
|
||||
type mapIterator struct {
|
||||
len int
|
||||
mapIter *reflect.MapIter
|
||||
}
|
||||
|
||||
func (i *mapIterator) Next() bool {
|
||||
return i.mapIter.Next()
|
||||
}
|
||||
|
||||
func (i *mapIterator) Len() int {
|
||||
return i.len
|
||||
}
|
||||
|
||||
func (i *mapIterator) Key() string {
|
||||
return i.mapIter.Key().String()
|
||||
}
|
||||
|
||||
func mustMapIterator(anyMap interface{}) *mapIterator {
|
||||
val := reflect.ValueOf(anyMap)
|
||||
|
||||
return &mapIterator{mapIter: val.MapRange(), len: val.Len()}
|
||||
}
|
||||
|
||||
// DepthFirst sorts a map of anything. It groups keys by category
|
||||
// (shared params, op param, statuscode response, default response, definitions)
|
||||
// sort groups internally by number of parts in the key and lexical names
|
||||
// flatten groups into a single list of keys
|
||||
func DepthFirst(in interface{}) []string {
|
||||
iterator := mustMapIterator(in)
|
||||
sorted := make([]string, 0, iterator.Len())
|
||||
grouped := make(map[string]Keys, iterator.Len())
|
||||
|
||||
for iterator.Next() {
|
||||
k := iterator.Key()
|
||||
split := KeyParts(k)
|
||||
var pk string
|
||||
|
||||
if split.IsSharedOperationParam() {
|
||||
pk = "sharedOpParam"
|
||||
}
|
||||
if split.IsOperationParam() {
|
||||
pk = "opParam"
|
||||
}
|
||||
if split.IsStatusCodeResponse() {
|
||||
pk = "codeResponse"
|
||||
}
|
||||
if split.IsDefaultResponse() {
|
||||
pk = "defaultResponse"
|
||||
}
|
||||
if split.IsDefinition() {
|
||||
pk = "definition"
|
||||
}
|
||||
if split.IsSharedParam() {
|
||||
pk = "sharedParam"
|
||||
}
|
||||
if split.IsSharedResponse() {
|
||||
pk = "sharedResponse"
|
||||
}
|
||||
grouped[pk] = append(grouped[pk], Key{Segments: len(split), Key: k})
|
||||
}
|
||||
|
||||
for _, pk := range depthGroupOrder {
|
||||
res := grouped[pk]
|
||||
sort.Sort(res)
|
||||
|
||||
for _, v := range res {
|
||||
sorted = append(sorted, v.Key)
|
||||
}
|
||||
}
|
||||
|
||||
return sorted
|
||||
}
|
||||
|
||||
// topMostRefs is able to sort refs by hierarchical then lexicographic order,
|
||||
// yielding refs ordered breadth-first.
|
||||
type topmostRefs []string
|
||||
|
||||
func (k topmostRefs) Len() int { return len(k) }
|
||||
func (k topmostRefs) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
|
||||
func (k topmostRefs) Less(i, j int) bool {
|
||||
li, lj := len(strings.Split(k[i], "/")), len(strings.Split(k[j], "/"))
|
||||
if li == lj {
|
||||
return k[i] < k[j]
|
||||
}
|
||||
|
||||
return li < lj
|
||||
}
|
||||
|
||||
// TopmostFirst sorts references by depth
|
||||
func TopmostFirst(refs []string) []string {
|
||||
res := topmostRefs(refs)
|
||||
sort.Sort(res)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// RefRevIdx is a reverse index for references
|
||||
type RefRevIdx struct {
|
||||
Ref spec.Ref
|
||||
Keys []string
|
||||
}
|
||||
|
||||
// ReverseIndex builds a reverse index for references in schemas
|
||||
func ReverseIndex(schemas map[string]spec.Ref, basePath string) map[string]RefRevIdx {
|
||||
collected := make(map[string]RefRevIdx)
|
||||
for key, schRef := range schemas {
|
||||
// normalize paths before sorting,
|
||||
// so we get together keys that are from the same external file
|
||||
normalizedPath := normalize.Path(schRef, basePath)
|
||||
|
||||
entry, ok := collected[normalizedPath]
|
||||
if ok {
|
||||
entry.Keys = append(entry.Keys, key)
|
||||
collected[normalizedPath] = entry
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
collected[normalizedPath] = RefRevIdx{
|
||||
Ref: schRef,
|
||||
Keys: []string{key},
|
||||
}
|
||||
}
|
||||
|
||||
return collected
|
||||
}
|
||||
192
vendor/github.com/go-openapi/analysis/mixin.go
generated
vendored
192
vendor/github.com/go-openapi/analysis/mixin.go
generated
vendored
@@ -80,6 +80,7 @@ func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string {
|
||||
|
||||
skipped = append(skipped, mergeResponses(primary, m)...)
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
@@ -90,12 +91,15 @@ func getOpIds(s *spec.Swagger) map[string]bool {
|
||||
if s.Paths == nil {
|
||||
return rv
|
||||
}
|
||||
|
||||
for _, v := range s.Paths.Paths {
|
||||
piops := pathItemOps(v)
|
||||
|
||||
for _, op := range piops {
|
||||
rv[op.ID] = true
|
||||
}
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
@@ -107,6 +111,7 @@ func pathItemOps(p spec.PathItem) []*spec.Operation {
|
||||
rv = appendOp(rv, p.Delete)
|
||||
rv = appendOp(rv, p.Head)
|
||||
rv = appendOp(rv, p.Patch)
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
@@ -114,6 +119,7 @@ func appendOp(ops []*spec.Operation, op *spec.Operation) []*spec.Operation {
|
||||
if op == nil {
|
||||
return ops
|
||||
}
|
||||
|
||||
return append(ops, op)
|
||||
}
|
||||
|
||||
@@ -123,10 +129,13 @@ func mergeSecurityDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped [
|
||||
warn := fmt.Sprintf(
|
||||
"SecurityDefinitions entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
primary.SecurityDefinitions[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -136,17 +145,21 @@ func mergeSecurityRequirements(primary *spec.Swagger, m *spec.Swagger) (skipped
|
||||
for _, vv := range primary.Security {
|
||||
if reflect.DeepEqual(v, vv) {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
warn := fmt.Sprintf(
|
||||
"Security requirement: '%v' already exists in primary or higher priority mixin, skipping\n", v)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Security = append(primary.Security, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -157,10 +170,12 @@ func mergeDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped []string)
|
||||
warn := fmt.Sprintf(
|
||||
"definitions entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Definitions[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -171,6 +186,7 @@ func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, m
|
||||
warn := fmt.Sprintf(
|
||||
"paths entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -190,6 +206,7 @@ func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, m
|
||||
primary.Paths.Paths[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -202,10 +219,12 @@ func mergeParameters(primary *spec.Swagger, m *spec.Swagger) (skipped []string)
|
||||
warn := fmt.Sprintf(
|
||||
"top level parameters entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Parameters[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -218,10 +237,12 @@ func mergeResponses(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
|
||||
warn := fmt.Sprintf(
|
||||
"top level responses entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Responses[k] = v
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
@@ -231,15 +252,18 @@ func mergeConsumes(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
for _, vv := range primary.Consumes {
|
||||
if v == vv {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
// no warning here: we just skip it
|
||||
continue
|
||||
}
|
||||
primary.Consumes = append(primary.Consumes, v)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@@ -249,15 +273,18 @@ func mergeProduces(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
for _, vv := range primary.Produces {
|
||||
if v == vv {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
// no warning here: we just skip it
|
||||
continue
|
||||
}
|
||||
primary.Produces = append(primary.Produces, v)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@@ -267,17 +294,24 @@ func mergeTags(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
|
||||
for _, vv := range primary.Tags {
|
||||
if v.Name == vv.Name {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
warn := fmt.Sprintf(
|
||||
"top level tags entry with name '%v' already exists in primary or higher priority mixin, skipping\n", v.Name)
|
||||
"top level tags entry with name '%v' already exists in primary or higher priority mixin, skipping\n",
|
||||
v.Name,
|
||||
)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
primary.Tags = append(primary.Tags, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -287,110 +321,150 @@ func mergeSchemes(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
for _, vv := range primary.Schemes {
|
||||
if v == vv {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
// no warning here: we just skip it
|
||||
continue
|
||||
}
|
||||
primary.Schemes = append(primary.Schemes, v)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func mergeSwaggerProps(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
var skipped []string
|
||||
var skipped, skippedInfo, skippedDocs []string
|
||||
|
||||
primary.Extensions, skipped = mergeExtensions(primary.Extensions, m.Extensions)
|
||||
|
||||
// merging details in swagger top properties
|
||||
if primary.Host == "" {
|
||||
primary.Host = m.Host
|
||||
}
|
||||
|
||||
if primary.BasePath == "" {
|
||||
primary.BasePath = m.BasePath
|
||||
}
|
||||
|
||||
if primary.Info == nil {
|
||||
primary.Info = m.Info
|
||||
} else if m.Info != nil {
|
||||
var sk []string
|
||||
primary.Info.Extensions, sk = mergeExtensions(primary.Info.Extensions, m.Info.Extensions)
|
||||
skipped = append(skipped, sk...)
|
||||
if primary.Info.Description == "" {
|
||||
primary.Info.Description = m.Info.Description
|
||||
}
|
||||
if primary.Info.Title == "" {
|
||||
primary.Info.Description = m.Info.Description
|
||||
}
|
||||
if primary.Info.TermsOfService == "" {
|
||||
primary.Info.TermsOfService = m.Info.TermsOfService
|
||||
}
|
||||
if primary.Info.Version == "" {
|
||||
primary.Info.Version = m.Info.Version
|
||||
}
|
||||
|
||||
if primary.Info.Contact == nil {
|
||||
primary.Info.Contact = m.Info.Contact
|
||||
} else if m.Info.Contact != nil {
|
||||
var csk []string
|
||||
primary.Info.Contact.Extensions, csk = mergeExtensions(primary.Info.Contact.Extensions, m.Info.Contact.Extensions)
|
||||
skipped = append(skipped, csk...)
|
||||
if primary.Info.Contact.Name == "" {
|
||||
primary.Info.Contact.Name = m.Info.Contact.Name
|
||||
}
|
||||
if primary.Info.Contact.URL == "" {
|
||||
primary.Info.Contact.URL = m.Info.Contact.URL
|
||||
}
|
||||
if primary.Info.Contact.Email == "" {
|
||||
primary.Info.Contact.Email = m.Info.Contact.Email
|
||||
}
|
||||
}
|
||||
|
||||
if primary.Info.License == nil {
|
||||
primary.Info.License = m.Info.License
|
||||
} else if m.Info.License != nil {
|
||||
var lsk []string
|
||||
primary.Info.License.Extensions, lsk = mergeExtensions(primary.Info.License.Extensions, m.Info.License.Extensions)
|
||||
skipped = append(skipped, lsk...)
|
||||
if primary.Info.License.Name == "" {
|
||||
primary.Info.License.Name = m.Info.License.Name
|
||||
}
|
||||
if primary.Info.License.URL == "" {
|
||||
primary.Info.License.URL = m.Info.License.URL
|
||||
}
|
||||
}
|
||||
|
||||
skippedInfo = mergeInfo(primary.Info, m.Info)
|
||||
skipped = append(skipped, skippedInfo...)
|
||||
}
|
||||
|
||||
if primary.ExternalDocs == nil {
|
||||
primary.ExternalDocs = m.ExternalDocs
|
||||
} else if m.ExternalDocs != nil {
|
||||
if primary.ExternalDocs.Description == "" {
|
||||
primary.ExternalDocs.Description = m.ExternalDocs.Description
|
||||
} else if m != nil {
|
||||
skippedDocs = mergeExternalDocs(primary.ExternalDocs, m.ExternalDocs)
|
||||
skipped = append(skipped, skippedDocs...)
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func mergeExternalDocs(primary *spec.ExternalDocumentation, m *spec.ExternalDocumentation) []string {
|
||||
if primary.Description == "" {
|
||||
primary.Description = m.Description
|
||||
}
|
||||
|
||||
if primary.URL == "" {
|
||||
primary.URL = m.URL
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func mergeInfo(primary *spec.Info, m *spec.Info) []string {
|
||||
var sk, skipped []string
|
||||
|
||||
primary.Extensions, sk = mergeExtensions(primary.Extensions, m.Extensions)
|
||||
skipped = append(skipped, sk...)
|
||||
|
||||
if primary.Description == "" {
|
||||
primary.Description = m.Description
|
||||
}
|
||||
|
||||
if primary.Title == "" {
|
||||
primary.Description = m.Description
|
||||
}
|
||||
|
||||
if primary.TermsOfService == "" {
|
||||
primary.TermsOfService = m.TermsOfService
|
||||
}
|
||||
|
||||
if primary.Version == "" {
|
||||
primary.Version = m.Version
|
||||
}
|
||||
|
||||
if primary.Contact == nil {
|
||||
primary.Contact = m.Contact
|
||||
} else if m.Contact != nil {
|
||||
var csk []string
|
||||
primary.Contact.Extensions, csk = mergeExtensions(primary.Contact.Extensions, m.Contact.Extensions)
|
||||
skipped = append(skipped, csk...)
|
||||
|
||||
if primary.Contact.Name == "" {
|
||||
primary.Contact.Name = m.Contact.Name
|
||||
}
|
||||
if primary.ExternalDocs.URL == "" {
|
||||
primary.ExternalDocs.URL = m.ExternalDocs.URL
|
||||
|
||||
if primary.Contact.URL == "" {
|
||||
primary.Contact.URL = m.Contact.URL
|
||||
}
|
||||
|
||||
if primary.Contact.Email == "" {
|
||||
primary.Contact.Email = m.Contact.Email
|
||||
}
|
||||
}
|
||||
|
||||
if primary.License == nil {
|
||||
primary.License = m.License
|
||||
} else if m.License != nil {
|
||||
var lsk []string
|
||||
primary.License.Extensions, lsk = mergeExtensions(primary.License.Extensions, m.License.Extensions)
|
||||
skipped = append(skipped, lsk...)
|
||||
|
||||
if primary.License.Name == "" {
|
||||
primary.License.Name = m.License.Name
|
||||
}
|
||||
|
||||
if primary.License.URL == "" {
|
||||
primary.License.URL = m.License.URL
|
||||
}
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
func mergeExtensions(primary spec.Extensions, m spec.Extensions) (result spec.Extensions, skipped []string) {
|
||||
if primary == nil {
|
||||
result = m
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if m == nil {
|
||||
result = primary
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
result = primary
|
||||
for k, v := range m {
|
||||
if _, found := primary[k]; found {
|
||||
skipped = append(skipped, k)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
primary[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -398,33 +472,43 @@ func initPrimary(primary *spec.Swagger) {
|
||||
if primary.SecurityDefinitions == nil {
|
||||
primary.SecurityDefinitions = make(map[string]*spec.SecurityScheme)
|
||||
}
|
||||
|
||||
if primary.Security == nil {
|
||||
primary.Security = make([]map[string][]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Produces == nil {
|
||||
primary.Produces = make([]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Consumes == nil {
|
||||
primary.Consumes = make([]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Tags == nil {
|
||||
primary.Tags = make([]spec.Tag, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Schemes == nil {
|
||||
primary.Schemes = make([]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Paths == nil {
|
||||
primary.Paths = &spec.Paths{Paths: make(map[string]spec.PathItem)}
|
||||
}
|
||||
|
||||
if primary.Paths.Paths == nil {
|
||||
primary.Paths.Paths = make(map[string]spec.PathItem)
|
||||
}
|
||||
|
||||
if primary.Definitions == nil {
|
||||
primary.Definitions = make(spec.Definitions)
|
||||
}
|
||||
|
||||
if primary.Parameters == nil {
|
||||
primary.Parameters = make(map[string]spec.Parameter)
|
||||
}
|
||||
|
||||
if primary.Responses == nil {
|
||||
primary.Responses = make(map[string]spec.Response)
|
||||
}
|
||||
|
||||
64
vendor/github.com/go-openapi/analysis/schema.go
generated
vendored
64
vendor/github.com/go-openapi/analysis/schema.go
generated
vendored
@@ -47,6 +47,7 @@ func Schema(opts SchemaOpts) (*AnalyzedSchema, error) {
|
||||
}
|
||||
|
||||
a.inferSimpleSchema()
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
@@ -123,6 +124,7 @@ func (a *AnalyzedSchema) inferFromRef() error {
|
||||
}
|
||||
a.inherits(rsch)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -142,26 +144,33 @@ func (a *AnalyzedSchema) inferKnownType() {
|
||||
}
|
||||
|
||||
func (a *AnalyzedSchema) inferMap() error {
|
||||
if a.isObjectType() {
|
||||
hasExtra := a.hasProps || a.hasAllOf
|
||||
a.IsMap = a.hasAdditionalProps && !hasExtra
|
||||
a.IsExtendedObject = a.hasAdditionalProps && hasExtra
|
||||
if a.IsMap {
|
||||
if a.schema.AdditionalProperties.Schema != nil {
|
||||
msch, err := Schema(SchemaOpts{
|
||||
Schema: a.schema.AdditionalProperties.Schema,
|
||||
Root: a.root,
|
||||
BasePath: a.basePath,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.IsSimpleMap = msch.IsSimpleSchema
|
||||
} else if a.schema.AdditionalProperties.Allows {
|
||||
a.IsSimpleMap = true
|
||||
}
|
||||
}
|
||||
if !a.isObjectType() {
|
||||
return nil
|
||||
}
|
||||
|
||||
hasExtra := a.hasProps || a.hasAllOf
|
||||
a.IsMap = a.hasAdditionalProps && !hasExtra
|
||||
a.IsExtendedObject = a.hasAdditionalProps && hasExtra
|
||||
|
||||
if !a.IsMap {
|
||||
return nil
|
||||
}
|
||||
|
||||
// maps
|
||||
if a.schema.AdditionalProperties.Schema != nil {
|
||||
msch, err := Schema(SchemaOpts{
|
||||
Schema: a.schema.AdditionalProperties.Schema,
|
||||
Root: a.root,
|
||||
BasePath: a.basePath,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.IsSimpleMap = msch.IsSimpleSchema
|
||||
} else if a.schema.AdditionalProperties.Allows {
|
||||
a.IsSimpleMap = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -184,12 +193,15 @@ func (a *AnalyzedSchema) inferArray() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.IsSimpleArray = itsch.IsSimpleSchema
|
||||
}
|
||||
}
|
||||
|
||||
if a.IsArray && !a.hasItems {
|
||||
a.IsSimpleArray = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -218,11 +230,10 @@ func (a *AnalyzedSchema) initializeFlags() {
|
||||
(a.schema.Items.Schema != nil || len(a.schema.Items.Schemas) > 0)
|
||||
|
||||
a.hasAdditionalProps = a.schema.AdditionalProperties != nil &&
|
||||
(a.schema.AdditionalProperties != nil || a.schema.AdditionalProperties.Allows)
|
||||
(a.schema.AdditionalProperties.Schema != nil || a.schema.AdditionalProperties.Allows)
|
||||
|
||||
a.hasAdditionalItems = a.schema.AdditionalItems != nil &&
|
||||
(a.schema.AdditionalItems.Schema != nil || a.schema.AdditionalItems.Allows)
|
||||
|
||||
}
|
||||
|
||||
func (a *AnalyzedSchema) isObjectType() bool {
|
||||
@@ -232,3 +243,14 @@ func (a *AnalyzedSchema) isObjectType() bool {
|
||||
func (a *AnalyzedSchema) isArrayType() bool {
|
||||
return !a.hasRef && (a.schema.Type != nil && a.schema.Type.Contains("array"))
|
||||
}
|
||||
|
||||
// isAnalyzedAsComplex determines if an analyzed schema is eligible to flattening (i.e. it is "complex").
|
||||
//
|
||||
// Complex means the schema is any of:
|
||||
// - a simple type (primitive)
|
||||
// - an array of something (items are possibly complex ; if this is the case, items will generate a definition)
|
||||
// - a map of something (additionalProperties are possibly complex ; if this is the case, additionalProperties will
|
||||
// generate a definition)
|
||||
func (a *AnalyzedSchema) isAnalyzedAsComplex() bool {
|
||||
return !a.IsSimpleSchema && !a.IsArray && !a.IsMap
|
||||
}
|
||||
|
||||
1
vendor/github.com/go-openapi/errors/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/go-openapi/errors/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.go text eol=lf
|
||||
28
vendor/github.com/go-openapi/errors/.golangci.yml
generated
vendored
28
vendor/github.com/go-openapi/errors/.golangci.yml
generated
vendored
@@ -18,3 +18,31 @@ linters:
|
||||
- maligned
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- exhaustive
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- gci
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gomnd
|
||||
- tparallel
|
||||
- nestif
|
||||
- godot
|
||||
- errorlint
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- cyclop
|
||||
- errname
|
||||
- varnamelen
|
||||
- exhaustruct
|
||||
- maintidx
|
||||
|
||||
13
vendor/github.com/go-openapi/errors/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/errors/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: gZGp9NaHxi7zawlXJXKY92BGeDR1x0tbIcTyU5nMKLq0fhIaiEBJEeALwZ4VgqsSv3DytSSF5mLH8fevAM3ixE6hxjKQ+lQuf7V/w3btCN1CSWgoua5LOh1kTnqZQtJuRvO4pzoJcT3bJWBsVZ07VGNVzzJEy/zAKCHFqBUCXShw7QemlLBcYWFNqveTlvDIfCzvouoLnPoXwxEpkjxe9uz/ZKZgAnup/fXjC8RFctmgCnkCyvJTk0Y/fZCsufixJrJhshBWTnlrFCzRmgNkz2d+i1Ls3+MJ5EJJ2Tx/A5S63dL49J1f9Kr0AKHADmulSy8JNzIckKwbyFMYUecrsW+Lsu9DhnVMy1jj5pKsJDLRi2iIU3fXTMWbcyQbXjbbnBO2mPdP3Tzme75y4D9fc8hUPeyqVv2BU26NEbQ7EF2pKJ93OXvci7HlwRBgdJa8j6mP2LEDClcPQW00g7N/OZe0cTOMa8L5AwiBlbArwqt9wv6YLJoTG0wpDhzWsFvbCg5bJxe28Yn3fIDD0Lk1I7iSnBbp/5gzF19jmxqvcT8tHRkDL4xfjbENFTZjA5uB4Z4pj4WSyWQILLV/Jwhe3fi9uQwdviFHfj5pnVrmNUiGSOQL672K5wl2c3E9mGwejvsu2dfEz28n7Y/FUnOpY3/cBS0n27JJaerS0zMKNLE=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
7
vendor/github.com/go-openapi/errors/README.md
generated
vendored
7
vendor/github.com/go-openapi/errors/README.md
generated
vendored
@@ -1,7 +1,10 @@
|
||||
# OpenAPI errors [](https://travis-ci.org/go-openapi/errors) [](https://codecov.io/gh/go-openapi/errors) [](https://slackin.goswagger.io)
|
||||
# OpenAPI errors
|
||||
|
||||
[](https://travis-ci.org/go-openapi/errors)
|
||||
[](https://codecov.io/gh/go-openapi/errors)
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE)
|
||||
[](http://godoc.org/github.com/go-openapi/errors)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/errors)
|
||||
[](https://golangci.com)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/errors)
|
||||
|
||||
|
||||
20
vendor/github.com/go-openapi/errors/api.go
generated
vendored
20
vendor/github.com/go-openapi/errors/api.go
generated
vendored
@@ -44,6 +44,14 @@ func (a *apiError) Code() int32 {
|
||||
return a.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (a apiError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": a.code,
|
||||
"message": a.message,
|
||||
})
|
||||
}
|
||||
|
||||
// New creates a new API error with a code and a message
|
||||
func New(code int32, message string, args ...interface{}) Error {
|
||||
if len(args) > 0 {
|
||||
@@ -81,7 +89,17 @@ func (m *MethodNotAllowedError) Code() int32 {
|
||||
return m.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (m MethodNotAllowedError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": m.code,
|
||||
"message": m.message,
|
||||
"allowed": m.Allowed,
|
||||
})
|
||||
}
|
||||
|
||||
func errorAsJSON(err Error) []byte {
|
||||
//nolint:errchkjson
|
||||
b, _ := json.Marshal(struct {
|
||||
Code int32 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
@@ -129,7 +147,7 @@ func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
|
||||
ServeError(rw, r, nil)
|
||||
}
|
||||
case *MethodNotAllowedError:
|
||||
rw.Header().Add("Allow", strings.Join(err.(*MethodNotAllowedError).Allowed, ","))
|
||||
rw.Header().Add("Allow", strings.Join(e.Allowed, ","))
|
||||
rw.WriteHeader(asHTTPCode(int(e.Code())))
|
||||
if r == nil || r.Method != http.MethodHead {
|
||||
_, _ = rw.Write(errorAsJSON(e))
|
||||
|
||||
2
vendor/github.com/go-openapi/errors/doc.go
generated
vendored
2
vendor/github.com/go-openapi/errors/doc.go
generated
vendored
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
|
||||
Package errors provides an Error interface and several concrete types
|
||||
implementing this interface to manage API errors and JSON-schema validation
|
||||
errors.
|
||||
@@ -23,6 +22,5 @@ it defines.
|
||||
|
||||
It is used throughout the various go-openapi toolkit libraries
|
||||
(https://github.com/go-openapi).
|
||||
|
||||
*/
|
||||
package errors
|
||||
|
||||
26
vendor/github.com/go-openapi/errors/headers.go
generated
vendored
26
vendor/github.com/go-openapi/errors/headers.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
@@ -38,11 +39,28 @@ func (e *Validation) Code() int32 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// ValidateName produces an error message name for an aliased property
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (e Validation) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": e.code,
|
||||
"message": e.message,
|
||||
"in": e.In,
|
||||
"name": e.Name,
|
||||
"value": e.Value,
|
||||
"values": e.Values,
|
||||
})
|
||||
}
|
||||
|
||||
// ValidateName sets the name for a validation or updates it for a nested property
|
||||
func (e *Validation) ValidateName(name string) *Validation {
|
||||
if e.Name == "" && name != "" {
|
||||
e.Name = name
|
||||
e.message = name + e.message
|
||||
if name != "" {
|
||||
if e.Name == "" {
|
||||
e.Name = name
|
||||
e.message = name + e.message
|
||||
} else {
|
||||
e.Name = name + "." + e.Name
|
||||
e.message = name + "." + e.message
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
7
vendor/github.com/go-openapi/errors/middleware.go
generated
vendored
7
vendor/github.com/go-openapi/errors/middleware.go
generated
vendored
@@ -23,12 +23,11 @@ import (
|
||||
// APIVerificationFailed is an error that contains all the missing info for a mismatched section
|
||||
// between the api registrations and the api spec
|
||||
type APIVerificationFailed struct {
|
||||
Section string
|
||||
MissingSpecification []string
|
||||
MissingRegistration []string
|
||||
Section string `json:"section,omitempty"`
|
||||
MissingSpecification []string `json:"missingSpecification,omitempty"`
|
||||
MissingRegistration []string `json:"missingRegistration,omitempty"`
|
||||
}
|
||||
|
||||
//
|
||||
func (v *APIVerificationFailed) Error() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
|
||||
21
vendor/github.com/go-openapi/errors/parsing.go
generated
vendored
21
vendor/github.com/go-openapi/errors/parsing.go
generated
vendored
@@ -14,7 +14,10 @@
|
||||
|
||||
package errors
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ParseError represents a parsing error
|
||||
type ParseError struct {
|
||||
@@ -35,6 +38,22 @@ func (e *ParseError) Code() int32 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (e ParseError) MarshalJSON() ([]byte, error) {
|
||||
var reason string
|
||||
if e.Reason != nil {
|
||||
reason = e.Reason.Error()
|
||||
}
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": e.code,
|
||||
"message": e.message,
|
||||
"in": e.In,
|
||||
"name": e.Name,
|
||||
"value": e.Value,
|
||||
"reason": reason,
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
parseErrorTemplContent = `parsing %s %s from %q failed, because %s`
|
||||
parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s`
|
||||
|
||||
89
vendor/github.com/go-openapi/errors/schema.go
generated
vendored
89
vendor/github.com/go-openapi/errors/schema.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
@@ -25,6 +26,7 @@ const (
|
||||
typeFailWithData = "%s in %s must be of type %s: %q"
|
||||
typeFailWithError = "%s in %s must be of type %s, because: %s"
|
||||
requiredFail = "%s in %s is required"
|
||||
readOnlyFail = "%s in %s is readOnly"
|
||||
tooLongMessage = "%s in %s should be at most %d chars long"
|
||||
tooShortMessage = "%s in %s should be at least %d chars long"
|
||||
patternFail = "%s in %s should match '%s'"
|
||||
@@ -41,6 +43,7 @@ const (
|
||||
typeFailWithDataNoIn = "%s must be of type %s: %q"
|
||||
typeFailWithErrorNoIn = "%s must be of type %s, because: %s"
|
||||
requiredFailNoIn = "%s is required"
|
||||
readOnlyFailNoIn = "%s is readOnly"
|
||||
tooLongMessageNoIn = "%s should be at most %d chars long"
|
||||
tooShortMessageNoIn = "%s should be at least %d chars long"
|
||||
patternFailNoIn = "%s should match '%s'"
|
||||
@@ -91,6 +94,7 @@ const (
|
||||
UnallowedPropertyCode
|
||||
FailedAllPatternPropsCode
|
||||
MultipleOfMustBePositiveCode
|
||||
ReadOnlyFailCode
|
||||
)
|
||||
|
||||
// CompositeError is an error that groups several errors together
|
||||
@@ -116,6 +120,15 @@ func (c *CompositeError) Error() string {
|
||||
return c.message
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (c CompositeError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": c.code,
|
||||
"message": c.message,
|
||||
"errors": c.Errors,
|
||||
})
|
||||
}
|
||||
|
||||
// CompositeValidationError an error to wrap a bunch of other errors
|
||||
func CompositeValidationError(errors ...error) *CompositeError {
|
||||
return &CompositeError{
|
||||
@@ -125,6 +138,19 @@ func CompositeValidationError(errors ...error) *CompositeError {
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateName recursively sets the name for all validations or updates them for nested properties
|
||||
func (c *CompositeError) ValidateName(name string) *CompositeError {
|
||||
for i, e := range c.Errors {
|
||||
if ve, ok := e.(*Validation); ok {
|
||||
c.Errors[i] = ve.ValidateName(name)
|
||||
} else if ce, ok := e.(*CompositeError); ok {
|
||||
c.Errors[i] = ce.ValidateName(name)
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// FailedAllPatternProperties an error for when the property doesn't match a pattern
|
||||
func FailedAllPatternProperties(name, in, key string) *Validation {
|
||||
msg := fmt.Sprintf(failedAllPatternProps, name, key, in)
|
||||
@@ -268,7 +294,7 @@ func DuplicateItems(name, in string) *Validation {
|
||||
}
|
||||
|
||||
// TooManyItems error for when an array contains too many items
|
||||
func TooManyItems(name, in string, max int64) *Validation {
|
||||
func TooManyItems(name, in string, max int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(maxItemsFail, name, in, max)
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(maxItemsFailNoIn, name, max)
|
||||
@@ -278,12 +304,13 @@ func TooManyItems(name, in string, max int64) *Validation {
|
||||
code: MaxItemsFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// TooFewItems error for when an array contains too few items
|
||||
func TooFewItems(name, in string, min int64) *Validation {
|
||||
func TooFewItems(name, in string, min int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(minItemsFail, name, in, min)
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(minItemsFailNoIn, name, min)
|
||||
@@ -292,12 +319,13 @@ func TooFewItems(name, in string, min int64) *Validation {
|
||||
code: MinItemsFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumInt error for when maximum validation fails
|
||||
func ExceedsMaximumInt(name, in string, max int64, exclusive bool) *Validation {
|
||||
func ExceedsMaximumInt(name, in string, max int64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
@@ -316,13 +344,13 @@ func ExceedsMaximumInt(name, in string, max int64, exclusive bool) *Validation {
|
||||
code: MaxFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: max,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumUint error for when maximum validation fails
|
||||
func ExceedsMaximumUint(name, in string, max uint64, exclusive bool) *Validation {
|
||||
func ExceedsMaximumUint(name, in string, max uint64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
@@ -341,13 +369,13 @@ func ExceedsMaximumUint(name, in string, max uint64, exclusive bool) *Validation
|
||||
code: MaxFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: max,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximum error for when maximum validation fails
|
||||
func ExceedsMaximum(name, in string, max float64, exclusive bool) *Validation {
|
||||
func ExceedsMaximum(name, in string, max float64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
@@ -366,13 +394,13 @@ func ExceedsMaximum(name, in string, max float64, exclusive bool) *Validation {
|
||||
code: MaxFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: max,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimumInt error for when minimum validation fails
|
||||
func ExceedsMinimumInt(name, in string, min int64, exclusive bool) *Validation {
|
||||
func ExceedsMinimumInt(name, in string, min int64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
@@ -391,13 +419,13 @@ func ExceedsMinimumInt(name, in string, min int64, exclusive bool) *Validation {
|
||||
code: MinFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: min,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimumUint error for when minimum validation fails
|
||||
func ExceedsMinimumUint(name, in string, min uint64, exclusive bool) *Validation {
|
||||
func ExceedsMinimumUint(name, in string, min uint64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
@@ -416,13 +444,13 @@ func ExceedsMinimumUint(name, in string, min uint64, exclusive bool) *Validation
|
||||
code: MinFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: min,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimum error for when minimum validation fails
|
||||
func ExceedsMinimum(name, in string, min float64, exclusive bool) *Validation {
|
||||
func ExceedsMinimum(name, in string, min float64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
@@ -441,13 +469,13 @@ func ExceedsMinimum(name, in string, min float64, exclusive bool) *Validation {
|
||||
code: MinFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: min,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// NotMultipleOf error for when multiple of validation fails
|
||||
func NotMultipleOf(name, in string, multiple interface{}) *Validation {
|
||||
func NotMultipleOf(name, in string, multiple, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(multipleOfFailNoIn, name, multiple)
|
||||
@@ -458,7 +486,7 @@ func NotMultipleOf(name, in string, multiple interface{}) *Validation {
|
||||
code: MultipleOfFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: multiple,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
@@ -483,7 +511,7 @@ func EnumFail(name, in string, value interface{}, values []interface{}) *Validat
|
||||
}
|
||||
|
||||
// Required error for when a value is missing
|
||||
func Required(name, in string) *Validation {
|
||||
func Required(name, in string, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(requiredFailNoIn, name)
|
||||
@@ -494,12 +522,30 @@ func Required(name, in string) *Validation {
|
||||
code: RequiredFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOnly error for when a value is present in request
|
||||
func ReadOnly(name, in string, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(readOnlyFailNoIn, name)
|
||||
} else {
|
||||
msg = fmt.Sprintf(readOnlyFail, name, in)
|
||||
}
|
||||
return &Validation{
|
||||
code: ReadOnlyFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// TooLong error for when a string is too long
|
||||
func TooLong(name, in string, max int64) *Validation {
|
||||
func TooLong(name, in string, max int64, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(tooLongMessageNoIn, name, max)
|
||||
@@ -510,12 +556,13 @@ func TooLong(name, in string, max int64) *Validation {
|
||||
code: TooLongFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// TooShort error for when a string is too short
|
||||
func TooShort(name, in string, min int64) *Validation {
|
||||
func TooShort(name, in string, min int64, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(tooShortMessageNoIn, name, min)
|
||||
@@ -527,13 +574,14 @@ func TooShort(name, in string, min int64) *Validation {
|
||||
code: TooShortFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// FailedPattern error for when a string fails a regex pattern match
|
||||
// the pattern that is returned is the ECMA syntax version of the pattern not the golang version.
|
||||
func FailedPattern(name, in, pattern string) *Validation {
|
||||
func FailedPattern(name, in, pattern string, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(patternFailNoIn, name, pattern)
|
||||
@@ -545,6 +593,7 @@ func FailedPattern(name, in, pattern string) *Validation {
|
||||
code: PatternFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
5
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
5
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
@@ -26,11 +26,16 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
||||
// - FlagLowercaseHost
|
||||
// - FlagRemoveDefaultPort
|
||||
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
|
||||
//
|
||||
// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment.
|
||||
func NormalizeURL(u *url.URL) {
|
||||
lowercaseScheme(u)
|
||||
lowercaseHost(u)
|
||||
removeDefaultPort(u)
|
||||
removeDuplicateSlashes(u)
|
||||
|
||||
u.RawPath = ""
|
||||
u.RawFragment = ""
|
||||
}
|
||||
|
||||
func lowercaseScheme(u *url.URL) {
|
||||
|
||||
22
vendor/github.com/go-openapi/loads/.golangci.yml
generated
vendored
22
vendor/github.com/go-openapi/loads/.golangci.yml
generated
vendored
@@ -20,3 +20,25 @@ linters:
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- exhaustive
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- gci
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gomnd
|
||||
- tparallel
|
||||
- nestif
|
||||
- godot
|
||||
- errorlint
|
||||
- paralleltest
|
||||
|
||||
18
vendor/github.com/go-openapi/loads/.travis.yml
generated
vendored
18
vendor/github.com/go-openapi/loads/.travis.yml
generated
vendored
@@ -1,11 +1,23 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
- 1.16.x
|
||||
- 1.x
|
||||
install:
|
||||
- go get -u gotest.tools/gotestsum
|
||||
- go get gotest.tools/gotestsum
|
||||
language: go
|
||||
arch:
|
||||
- amd64
|
||||
- ppc64le
|
||||
jobs:
|
||||
include:
|
||||
# include linting job, but only for latest go version and amd64 arch
|
||||
- go: 1.x
|
||||
arch: amd64
|
||||
install:
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
script:
|
||||
- golangci-lint run --new-from-rev master
|
||||
notifications:
|
||||
slack:
|
||||
secure: OxkPwVp35qBTUilgWC8xykSj+sGMcj0h8IIOKD+Rflx2schZVlFfdYdyVBM+s9OqeOfvtuvnR9v1Ye2rPKAvcjWdC4LpRGUsgmItZaI6Um8Aj6+K9udCw5qrtZVfOVmRu8LieH//XznWWKdOultUuniW0MLqw5+II87Gd00RWbCGi0hk0PykHe7uK+PDA2BEbqyZ2WKKYCvfB3j+0nrFOHScXqnh0V05l2E83J4+Sgy1fsPy+1WdX58ZlNBG333ibaC1FS79XvKSmTgKRkx3+YBo97u6ZtUmJa5WZjf2OdLG3KIckGWAv6R5xgxeU31N0Ng8L332w/Edpp2O/M2bZwdnKJ8hJQikXIAQbICbr+lTDzsoNzMdEIYcHpJ5hjPbiUl3Bmd+Jnsjf5McgAZDiWIfpCKZ29tPCEkVwRsOCqkyPRMNMzHHmoja495P5jR+ODS7+J8RFg5xgcnOgpP9D4Wlhztlf5WyZMpkLxTUD+bZq2SRf50HfHFXTkfq22zPl3d1eq0yrLwh/Z/fWKkfb6SyysROL8y6s8u3dpFX1YHSg0BR6i913h4aoZw9B2BG27cafLLTwKYsp2dFo1PWl4O6u9giFJIeqwloZHLKKrwh0cBFhB7RH0I58asxkZpCH6uWjJierahmHe7iS+E6i+9oCHkOZ59hmCYNimIs3hM=
|
||||
|
||||
3
vendor/github.com/go-openapi/loads/README.md
generated
vendored
3
vendor/github.com/go-openapi/loads/README.md
generated
vendored
@@ -1,7 +1,6 @@
|
||||
# Loads OAI specs [](https://travis-ci.org/go-openapi/loads) [](https://codecov.io/gh/go-openapi/loads) [](https://slackin.goswagger.io)
|
||||
# Loads OAI specs [](https://travis-ci.org/go-openapi/loads) [](https://codecov.io/gh/go-openapi/loads) [](https://slackin.goswagger.io) [](https://github.com/go-openapi/loads/actions?query=workflow%3A"Go+Test")
|
||||
|
||||
[](https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE) [](http://godoc.org/github.com/go-openapi/loads)
|
||||
[](https://golangci.com)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/loads)
|
||||
|
||||
Loading of OAI specification documents from local or remote locations. Supports JSON and YAML documents.
|
||||
|
||||
134
vendor/github.com/go-openapi/loads/loaders.go
generated
vendored
Normal file
134
vendor/github.com/go-openapi/loads/loaders.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package loads
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
var (
|
||||
// Default chain of loaders, defined at the package level.
|
||||
//
|
||||
// By default this matches json and yaml documents.
|
||||
//
|
||||
// May be altered with AddLoader().
|
||||
loaders *loader
|
||||
)
|
||||
|
||||
func init() {
|
||||
jsonLoader := &loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: func(pth string) bool {
|
||||
return true
|
||||
},
|
||||
Fn: JSONDoc,
|
||||
},
|
||||
}
|
||||
|
||||
loaders = jsonLoader.WithHead(&loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: swag.YAMLMatcher,
|
||||
Fn: swag.YAMLDoc,
|
||||
},
|
||||
})
|
||||
|
||||
// sets the global default loader for go-openapi/spec
|
||||
spec.PathLoader = loaders.Load
|
||||
}
|
||||
|
||||
// DocLoader represents a doc loader type
|
||||
type DocLoader func(string) (json.RawMessage, error)
|
||||
|
||||
// DocMatcher represents a predicate to check if a loader matches
|
||||
type DocMatcher func(string) bool
|
||||
|
||||
// DocLoaderWithMatch describes a loading function for a given extension match.
|
||||
type DocLoaderWithMatch struct {
|
||||
Fn DocLoader
|
||||
Match DocMatcher
|
||||
}
|
||||
|
||||
// NewDocLoaderWithMatch builds a DocLoaderWithMatch to be used in load options
|
||||
func NewDocLoaderWithMatch(fn DocLoader, matcher DocMatcher) DocLoaderWithMatch {
|
||||
return DocLoaderWithMatch{
|
||||
Fn: fn,
|
||||
Match: matcher,
|
||||
}
|
||||
}
|
||||
|
||||
type loader struct {
|
||||
DocLoaderWithMatch
|
||||
Next *loader
|
||||
}
|
||||
|
||||
// WithHead adds a loader at the head of the current stack
|
||||
func (l *loader) WithHead(head *loader) *loader {
|
||||
if head == nil {
|
||||
return l
|
||||
}
|
||||
head.Next = l
|
||||
return head
|
||||
}
|
||||
|
||||
// WithNext adds a loader at the trail of the current stack
|
||||
func (l *loader) WithNext(next *loader) *loader {
|
||||
l.Next = next
|
||||
return next
|
||||
}
|
||||
|
||||
// Load the raw document from path
|
||||
func (l *loader) Load(path string) (json.RawMessage, error) {
|
||||
_, erp := url.Parse(path)
|
||||
if erp != nil {
|
||||
return nil, erp
|
||||
}
|
||||
|
||||
var lastErr error = errors.New("no loader matched") // default error if no match was found
|
||||
for ldr := l; ldr != nil; ldr = ldr.Next {
|
||||
if ldr.Match != nil && !ldr.Match(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
// try then move to next one if there is an error
|
||||
b, err := ldr.Fn(path)
|
||||
if err == nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
lastErr = err
|
||||
}
|
||||
|
||||
return nil, lastErr
|
||||
}
|
||||
|
||||
// JSONDoc loads a json document from either a file or a remote url
|
||||
func JSONDoc(path string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
}
|
||||
|
||||
// AddLoader for a document, executed before other previously set loaders.
|
||||
//
|
||||
// This sets the configuration at the package level.
|
||||
//
|
||||
// NOTE:
|
||||
// * this updates the default loader used by github.com/go-openapi/spec
|
||||
// * since this sets package level globals, you shouln't call this concurrently
|
||||
//
|
||||
func AddLoader(predicate DocMatcher, load DocLoader) {
|
||||
loaders = loaders.WithHead(&loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: predicate,
|
||||
Fn: load,
|
||||
},
|
||||
})
|
||||
|
||||
// sets the global default loader for go-openapi/spec
|
||||
spec.PathLoader = loaders.Load
|
||||
}
|
||||
61
vendor/github.com/go-openapi/loads/options.go
generated
vendored
Normal file
61
vendor/github.com/go-openapi/loads/options.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package loads
|
||||
|
||||
type options struct {
|
||||
loader *loader
|
||||
}
|
||||
|
||||
func defaultOptions() *options {
|
||||
return &options{
|
||||
loader: loaders,
|
||||
}
|
||||
}
|
||||
|
||||
func loaderFromOptions(options []LoaderOption) *loader {
|
||||
opts := defaultOptions()
|
||||
for _, apply := range options {
|
||||
apply(opts)
|
||||
}
|
||||
|
||||
return opts.loader
|
||||
}
|
||||
|
||||
// LoaderOption allows to fine-tune the spec loader behavior
|
||||
type LoaderOption func(*options)
|
||||
|
||||
// WithDocLoader sets a custom loader for loading specs
|
||||
func WithDocLoader(l DocLoader) LoaderOption {
|
||||
return func(opt *options) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
opt.loader = &loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Fn: l,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithDocLoaderMatches sets a chain of custom loaders for loading specs
|
||||
// for different extension matches.
|
||||
//
|
||||
// Loaders are executed in the order of provided DocLoaderWithMatch'es.
|
||||
func WithDocLoaderMatches(l ...DocLoaderWithMatch) LoaderOption {
|
||||
return func(opt *options) {
|
||||
var final, prev *loader
|
||||
for _, ldr := range l {
|
||||
if ldr.Fn == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if prev == nil {
|
||||
final = &loader{DocLoaderWithMatch: ldr}
|
||||
prev = final
|
||||
continue
|
||||
}
|
||||
|
||||
prev = prev.WithNext(&loader{DocLoaderWithMatch: ldr})
|
||||
}
|
||||
opt.loader = final
|
||||
}
|
||||
}
|
||||
188
vendor/github.com/go-openapi/loads/spec.go
generated
vendored
188
vendor/github.com/go-openapi/loads/spec.go
generated
vendored
@@ -19,69 +19,15 @@ import (
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// JSONDoc loads a json document from either a file or a remote url
|
||||
func JSONDoc(path string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
}
|
||||
|
||||
// DocLoader represents a doc loader type
|
||||
type DocLoader func(string) (json.RawMessage, error)
|
||||
|
||||
// DocMatcher represents a predicate to check if a loader matches
|
||||
type DocMatcher func(string) bool
|
||||
|
||||
var (
|
||||
loaders *loader
|
||||
defaultLoader *loader
|
||||
)
|
||||
|
||||
func init() {
|
||||
defaultLoader = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc}
|
||||
loaders = defaultLoader
|
||||
spec.PathLoader = loaders.Fn
|
||||
AddLoader(swag.YAMLMatcher, swag.YAMLDoc)
|
||||
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]interface{}{})
|
||||
//gob.Register(spec.Refable{})
|
||||
}
|
||||
|
||||
// AddLoader for a document
|
||||
func AddLoader(predicate DocMatcher, load DocLoader) {
|
||||
prev := loaders
|
||||
loaders = &loader{
|
||||
Match: predicate,
|
||||
Fn: load,
|
||||
Next: prev,
|
||||
}
|
||||
spec.PathLoader = loaders.Fn
|
||||
}
|
||||
|
||||
type loader struct {
|
||||
Fn DocLoader
|
||||
Match DocMatcher
|
||||
Next *loader
|
||||
}
|
||||
|
||||
// JSONSpec loads a spec from a json document
|
||||
func JSONSpec(path string) (*Document, error) {
|
||||
data, err := JSONDoc(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// convert to json
|
||||
return Analyzed(data, "")
|
||||
}
|
||||
|
||||
// Document represents a swagger spec document
|
||||
@@ -93,10 +39,21 @@ type Document struct {
|
||||
origSpec *spec.Swagger
|
||||
schema *spec.Schema
|
||||
raw json.RawMessage
|
||||
pathLoader *loader
|
||||
}
|
||||
|
||||
// JSONSpec loads a spec from a json document
|
||||
func JSONSpec(path string, options ...LoaderOption) (*Document, error) {
|
||||
data, err := JSONDoc(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// convert to json
|
||||
return Analyzed(data, "", options...)
|
||||
}
|
||||
|
||||
// Embedded returns a Document based on embedded specs. No analysis is required
|
||||
func Embedded(orig, flat json.RawMessage) (*Document, error) {
|
||||
func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, error) {
|
||||
var origSpec, flatSpec spec.Swagger
|
||||
if err := json.Unmarshal(orig, &origSpec); err != nil {
|
||||
return nil, err
|
||||
@@ -105,54 +62,38 @@ func Embedded(orig, flat json.RawMessage) (*Document, error) {
|
||||
return nil, err
|
||||
}
|
||||
return &Document{
|
||||
raw: orig,
|
||||
origSpec: &origSpec,
|
||||
spec: &flatSpec,
|
||||
raw: orig,
|
||||
origSpec: &origSpec,
|
||||
spec: &flatSpec,
|
||||
pathLoader: loaderFromOptions(options),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Spec loads a new spec document
|
||||
func Spec(path string) (*Document, error) {
|
||||
specURL, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var lastErr error
|
||||
for l := loaders.Next; l != nil; l = l.Next {
|
||||
if loaders.Match(specURL.Path) {
|
||||
b, err2 := loaders.Fn(path)
|
||||
if err2 != nil {
|
||||
lastErr = err2
|
||||
continue
|
||||
}
|
||||
doc, err3 := Analyzed(b, "")
|
||||
if err3 != nil {
|
||||
return nil, err3
|
||||
}
|
||||
if doc != nil {
|
||||
doc.specFilePath = path
|
||||
}
|
||||
return doc, nil
|
||||
}
|
||||
}
|
||||
if lastErr != nil {
|
||||
return nil, lastErr
|
||||
}
|
||||
b, err := defaultLoader.Fn(path)
|
||||
// Spec loads a new spec document from a local or remote path
|
||||
func Spec(path string, options ...LoaderOption) (*Document, error) {
|
||||
|
||||
ldr := loaderFromOptions(options)
|
||||
|
||||
b, err := ldr.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
document, err := Analyzed(b, "", options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
document, err := Analyzed(b, "")
|
||||
if document != nil {
|
||||
document.specFilePath = path
|
||||
document.pathLoader = ldr
|
||||
}
|
||||
|
||||
return document, err
|
||||
}
|
||||
|
||||
// Analyzed creates a new analyzed spec document
|
||||
func Analyzed(data json.RawMessage, version string) (*Document, error) {
|
||||
// Analyzed creates a new analyzed spec document for a root json.RawMessage.
|
||||
func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*Document, error) {
|
||||
if version == "" {
|
||||
version = "2.0"
|
||||
}
|
||||
@@ -160,24 +101,13 @@ func Analyzed(data json.RawMessage, version string) (*Document, error) {
|
||||
return nil, fmt.Errorf("spec version %q is not supported", version)
|
||||
}
|
||||
|
||||
raw := data
|
||||
trimmed := bytes.TrimSpace(data)
|
||||
if len(trimmed) > 0 {
|
||||
if trimmed[0] != '{' && trimmed[0] != '[' {
|
||||
yml, err := swag.BytesToYAMLDoc(trimmed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
d, err := swag.YAMLToJSON(yml)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
raw = d
|
||||
}
|
||||
raw, err := trimData(data) // trim blanks, then convert yaml docs into json
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
swspec := new(spec.Swagger)
|
||||
if err := json.Unmarshal(raw, swspec); err != nil {
|
||||
if err = json.Unmarshal(raw, swspec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -187,17 +117,44 @@ func Analyzed(data json.RawMessage, version string) (*Document, error) {
|
||||
}
|
||||
|
||||
d := &Document{
|
||||
Analyzer: analysis.New(swspec),
|
||||
schema: spec.MustLoadSwagger20Schema(),
|
||||
spec: swspec,
|
||||
raw: raw,
|
||||
origSpec: origsqspec,
|
||||
Analyzer: analysis.New(swspec),
|
||||
schema: spec.MustLoadSwagger20Schema(),
|
||||
spec: swspec,
|
||||
raw: raw,
|
||||
origSpec: origsqspec,
|
||||
pathLoader: loaderFromOptions(options),
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func trimData(in json.RawMessage) (json.RawMessage, error) {
|
||||
trimmed := bytes.TrimSpace(in)
|
||||
if len(trimmed) == 0 {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
if trimmed[0] == '{' || trimmed[0] == '[' {
|
||||
return trimmed, nil
|
||||
}
|
||||
|
||||
// assume yaml doc: convert it to json
|
||||
yml, err := swag.BytesToYAMLDoc(trimmed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
|
||||
d, err := swag.YAMLToJSON(yml)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Expanded expands the ref fields in the spec document and returns a new spec document
|
||||
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
|
||||
|
||||
swspec := new(spec.Swagger)
|
||||
if err := json.Unmarshal(d.raw, swspec); err != nil {
|
||||
return nil, err
|
||||
@@ -212,6 +169,16 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if expandOptions.PathLoader == nil {
|
||||
if d.pathLoader != nil {
|
||||
// use loader from Document options
|
||||
expandOptions.PathLoader = d.pathLoader.Load
|
||||
} else {
|
||||
// use package level loader
|
||||
expandOptions.PathLoader = loaders.Load
|
||||
}
|
||||
}
|
||||
|
||||
if err := spec.ExpandSpec(swspec, expandOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -262,7 +229,7 @@ func (d *Document) OrigSpec() *spec.Swagger {
|
||||
return d.origSpec
|
||||
}
|
||||
|
||||
// ResetDefinitions gives a shallow copy with the models reset
|
||||
// ResetDefinitions gives a shallow copy with the models reset to the original spec
|
||||
func (d *Document) ResetDefinitions() *Document {
|
||||
defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
|
||||
for k, v := range d.origSpec.Definitions {
|
||||
@@ -276,6 +243,7 @@ func (d *Document) ResetDefinitions() *Document {
|
||||
// Pristine creates a new pristine document instance based on the input data
|
||||
func (d *Document) Pristine() *Document {
|
||||
dd, _ := Analyzed(d.Raw(), d.Version())
|
||||
dd.pathLoader = d.pathLoader
|
||||
return dd
|
||||
}
|
||||
|
||||
|
||||
1
vendor/github.com/go-openapi/runtime/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/go-openapi/runtime/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.go text eol=lf
|
||||
44
vendor/github.com/go-openapi/runtime/.golangci.yml
generated
vendored
Normal file
44
vendor/github.com/go-openapi/runtime/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
# Using err repeatedly considered as shadowing.
|
||||
check-shadowing: false
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 30
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 4
|
||||
linters:
|
||||
disable:
|
||||
- maligned
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- exhaustive
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- gci
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gomnd
|
||||
- tparallel
|
||||
- nestif
|
||||
- godot
|
||||
- errorlint
|
||||
- noctx
|
||||
- interfacer
|
||||
- nilerr
|
||||
13
vendor/github.com/go-openapi/runtime/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/runtime/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
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=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -timeout=20m -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
16
vendor/github.com/go-openapi/runtime/bytestream.go
generated
vendored
16
vendor/github.com/go-openapi/runtime/bytestream.go
generated
vendored
@@ -38,7 +38,7 @@ type byteStreamOpts struct {
|
||||
Close bool
|
||||
}
|
||||
|
||||
// ByteStreamConsumer creates a consmer for byte streams,
|
||||
// ByteStreamConsumer creates a consumer for byte streams,
|
||||
// takes a Writer/BinaryUnmarshaler interface or binary slice by reference,
|
||||
// and reads from the provided reader
|
||||
func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
|
||||
@@ -58,6 +58,7 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
|
||||
close = cl.Close
|
||||
}
|
||||
}
|
||||
//nolint:errcheck // closing a reader wouldn't fail.
|
||||
defer close()
|
||||
|
||||
if wrtr, ok := data.(io.Writer); ok {
|
||||
@@ -76,6 +77,13 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
|
||||
return bu.UnmarshalBinary(b)
|
||||
}
|
||||
|
||||
if data != nil {
|
||||
if str, ok := data.(*string); ok {
|
||||
*str = string(b)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if t := reflect.TypeOf(data); data != nil && t.Kind() == reflect.Ptr {
|
||||
v := reflect.Indirect(reflect.ValueOf(data))
|
||||
if t = v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
|
||||
@@ -107,6 +115,7 @@ func ByteStreamProducer(opts ...byteStreamOpt) Producer {
|
||||
close = cl.Close
|
||||
}
|
||||
}
|
||||
//nolint:errcheck // TODO: closing a writer would fail.
|
||||
defer close()
|
||||
|
||||
if rc, ok := data.(io.ReadCloser); ok {
|
||||
@@ -129,6 +138,11 @@ func ByteStreamProducer(opts ...byteStreamOpt) Producer {
|
||||
}
|
||||
|
||||
if data != nil {
|
||||
if str, ok := data.(string); ok {
|
||||
_, err := writer.Write([]byte(str))
|
||||
return err
|
||||
}
|
||||
|
||||
if e, ok := data.(error); ok {
|
||||
_, err := writer.Write([]byte(e.Error()))
|
||||
return err
|
||||
|
||||
20
vendor/github.com/go-openapi/runtime/client/auth_info.go
generated
vendored
20
vendor/github.com/go-openapi/runtime/client/auth_info.go
generated
vendored
@@ -33,7 +33,7 @@ func init() {
|
||||
func BasicAuth(username, password string) runtime.ClientAuthInfoWriter {
|
||||
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
|
||||
encoded := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
||||
return r.SetHeaderParam("Authorization", "Basic "+encoded)
|
||||
return r.SetHeaderParam(runtime.HeaderAuthorization, "Basic "+encoded)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -56,6 +56,22 @@ func APIKeyAuth(name, in, value string) runtime.ClientAuthInfoWriter {
|
||||
// BearerToken provides a header based oauth2 bearer access token auth info writer
|
||||
func BearerToken(token string) runtime.ClientAuthInfoWriter {
|
||||
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
|
||||
return r.SetHeaderParam("Authorization", "Bearer "+token)
|
||||
return r.SetHeaderParam(runtime.HeaderAuthorization, "Bearer "+token)
|
||||
})
|
||||
}
|
||||
|
||||
// Compose combines multiple ClientAuthInfoWriters into a single one.
|
||||
// Useful when multiple auth headers are needed.
|
||||
func Compose(auths ...runtime.ClientAuthInfoWriter) runtime.ClientAuthInfoWriter {
|
||||
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
|
||||
for _, auth := range auths {
|
||||
if auth == nil {
|
||||
continue
|
||||
}
|
||||
if err := auth.AuthenticateRequest(r, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
8
vendor/github.com/go-openapi/runtime/client/keepalive.go
generated
vendored
8
vendor/github.com/go-openapi/runtime/client/keepalive.go
generated
vendored
@@ -2,7 +2,6 @@ package client
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
)
|
||||
@@ -46,8 +45,11 @@ func (d *drainingReadCloser) Read(p []byte) (n int, err error) {
|
||||
func (d *drainingReadCloser) Close() error {
|
||||
// drain buffer
|
||||
if atomic.LoadUint32(&d.seenEOF) != 1 {
|
||||
//#nosec
|
||||
io.Copy(ioutil.Discard, d.rdr)
|
||||
// If the reader side (a HTTP server) is misbehaving, it still may send
|
||||
// some bytes, but the closer ignores them to keep the underling
|
||||
// connection open.
|
||||
//nolint:errcheck
|
||||
io.Copy(io.Discard, d.rdr)
|
||||
}
|
||||
return d.rdr.Close()
|
||||
}
|
||||
|
||||
207
vendor/github.com/go-openapi/runtime/client/opentelemetry.go
generated
vendored
Normal file
207
vendor/github.com/go-openapi/runtime/client/opentelemetry.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
instrumentationVersion = "1.0.0"
|
||||
tracerName = "go-openapi"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Tracer trace.Tracer
|
||||
Propagator propagation.TextMapPropagator
|
||||
SpanStartOptions []trace.SpanStartOption
|
||||
SpanNameFormatter func(*runtime.ClientOperation) string
|
||||
TracerProvider trace.TracerProvider
|
||||
}
|
||||
|
||||
type OpenTelemetryOpt interface {
|
||||
apply(*config)
|
||||
}
|
||||
|
||||
type optionFunc func(*config)
|
||||
|
||||
func (o optionFunc) apply(c *config) {
|
||||
o(c)
|
||||
}
|
||||
|
||||
// WithTracerProvider specifies a tracer provider to use for creating a tracer.
|
||||
// If none is specified, the global provider is used.
|
||||
func WithTracerProvider(provider trace.TracerProvider) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
if provider != nil {
|
||||
c.TracerProvider = provider
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WithPropagators configures specific propagators. If this
|
||||
// option isn't specified, then the global TextMapPropagator is used.
|
||||
func WithPropagators(ps propagation.TextMapPropagator) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
if ps != nil {
|
||||
c.Propagator = ps
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanOptions configures an additional set of
|
||||
// trace.SpanOptions, which are applied to each new span.
|
||||
func WithSpanOptions(opts ...trace.SpanStartOption) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanStartOptions = append(c.SpanStartOptions, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanNameFormatter takes a function that will be called on every
|
||||
// request and the returned string will become the Span Name.
|
||||
func WithSpanNameFormatter(f func(op *runtime.ClientOperation) string) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanNameFormatter = f
|
||||
})
|
||||
}
|
||||
|
||||
func defaultTransportFormatter(op *runtime.ClientOperation) string {
|
||||
if op.ID != "" {
|
||||
return op.ID
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s_%s", strings.ToLower(op.Method), op.PathPattern)
|
||||
}
|
||||
|
||||
type openTelemetryTransport struct {
|
||||
transport runtime.ClientTransport
|
||||
host string
|
||||
tracer trace.Tracer
|
||||
config *config
|
||||
}
|
||||
|
||||
func newOpenTelemetryTransport(transport runtime.ClientTransport, host string, opts []OpenTelemetryOpt) *openTelemetryTransport {
|
||||
tr := &openTelemetryTransport{
|
||||
transport: transport,
|
||||
host: host,
|
||||
}
|
||||
|
||||
defaultOpts := []OpenTelemetryOpt{
|
||||
WithSpanOptions(trace.WithSpanKind(trace.SpanKindClient)),
|
||||
WithSpanNameFormatter(defaultTransportFormatter),
|
||||
WithPropagators(otel.GetTextMapPropagator()),
|
||||
WithTracerProvider(otel.GetTracerProvider()),
|
||||
}
|
||||
|
||||
c := newConfig(append(defaultOpts, opts...)...)
|
||||
tr.config = c
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (interface{}, error) {
|
||||
if op.Context == nil {
|
||||
return t.transport.Submit(op)
|
||||
}
|
||||
|
||||
params := op.Params
|
||||
reader := op.Reader
|
||||
|
||||
var span trace.Span
|
||||
defer func() {
|
||||
if span != nil {
|
||||
span.End()
|
||||
}
|
||||
}()
|
||||
|
||||
op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
span = t.newOpenTelemetrySpan(op, req.GetHeaderParams())
|
||||
return params.WriteToRequest(req, reg)
|
||||
})
|
||||
|
||||
op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
if span != nil {
|
||||
statusCode := response.Code()
|
||||
span.SetAttributes(attribute.Int(string(semconv.HTTPStatusCodeKey), statusCode))
|
||||
span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(statusCode, trace.SpanKindClient))
|
||||
}
|
||||
|
||||
return reader.ReadResponse(response, consumer)
|
||||
})
|
||||
|
||||
submit, err := t.transport.Submit(op)
|
||||
if err != nil && span != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
|
||||
return submit, err
|
||||
}
|
||||
|
||||
func (t *openTelemetryTransport) newOpenTelemetrySpan(op *runtime.ClientOperation, header http.Header) trace.Span {
|
||||
ctx := op.Context
|
||||
|
||||
tracer := t.tracer
|
||||
if tracer == nil {
|
||||
if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
|
||||
tracer = newTracer(span.TracerProvider())
|
||||
} else {
|
||||
tracer = newTracer(otel.GetTracerProvider())
|
||||
}
|
||||
}
|
||||
|
||||
ctx, span := tracer.Start(ctx, t.config.SpanNameFormatter(op), t.config.SpanStartOptions...)
|
||||
|
||||
var scheme string
|
||||
if len(op.Schemes) > 0 {
|
||||
scheme = op.Schemes[0]
|
||||
}
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.String("net.peer.name", t.host),
|
||||
attribute.String(string(semconv.HTTPRouteKey), op.PathPattern),
|
||||
attribute.String(string(semconv.HTTPMethodKey), op.Method),
|
||||
attribute.String("span.kind", trace.SpanKindClient.String()),
|
||||
attribute.String("http.scheme", scheme),
|
||||
)
|
||||
|
||||
carrier := propagation.HeaderCarrier(header)
|
||||
t.config.Propagator.Inject(ctx, carrier)
|
||||
|
||||
return span
|
||||
}
|
||||
|
||||
func newTracer(tp trace.TracerProvider) trace.Tracer {
|
||||
return tp.Tracer(tracerName, trace.WithInstrumentationVersion(version()))
|
||||
}
|
||||
|
||||
func newConfig(opts ...OpenTelemetryOpt) *config {
|
||||
c := &config{
|
||||
Propagator: otel.GetTextMapPropagator(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt.apply(c)
|
||||
}
|
||||
|
||||
// Tracer is only initialized if manually specified. Otherwise, can be passed with the tracing context.
|
||||
if c.TracerProvider != nil {
|
||||
c.Tracer = newTracer(c.TracerProvider)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// Version is the current release version of the go-runtime instrumentation.
|
||||
func version() string {
|
||||
return instrumentationVersion
|
||||
}
|
||||
99
vendor/github.com/go-openapi/runtime/client/opentracing.go
generated
vendored
Normal file
99
vendor/github.com/go-openapi/runtime/client/opentracing.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
)
|
||||
|
||||
type tracingTransport struct {
|
||||
transport runtime.ClientTransport
|
||||
host string
|
||||
opts []opentracing.StartSpanOption
|
||||
}
|
||||
|
||||
func newOpenTracingTransport(transport runtime.ClientTransport, host string, opts []opentracing.StartSpanOption,
|
||||
) runtime.ClientTransport {
|
||||
return &tracingTransport{
|
||||
transport: transport,
|
||||
host: host,
|
||||
opts: opts,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracingTransport) Submit(op *runtime.ClientOperation) (interface{}, error) {
|
||||
if op.Context == nil {
|
||||
return t.transport.Submit(op)
|
||||
}
|
||||
|
||||
params := op.Params
|
||||
reader := op.Reader
|
||||
|
||||
var span opentracing.Span
|
||||
defer func() {
|
||||
if span != nil {
|
||||
span.Finish()
|
||||
}
|
||||
}()
|
||||
|
||||
op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
span = createClientSpan(op, req.GetHeaderParams(), t.host, t.opts)
|
||||
return params.WriteToRequest(req, reg)
|
||||
})
|
||||
|
||||
op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
if span != nil {
|
||||
code := response.Code()
|
||||
ext.HTTPStatusCode.Set(span, uint16(code))
|
||||
if code >= 400 {
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
}
|
||||
return reader.ReadResponse(response, consumer)
|
||||
})
|
||||
|
||||
submit, err := t.transport.Submit(op)
|
||||
if err != nil && span != nil {
|
||||
ext.Error.Set(span, true)
|
||||
span.LogFields(log.Error(err))
|
||||
}
|
||||
return submit, err
|
||||
}
|
||||
|
||||
func createClientSpan(op *runtime.ClientOperation, header http.Header, host string,
|
||||
opts []opentracing.StartSpanOption) opentracing.Span {
|
||||
ctx := op.Context
|
||||
span := opentracing.SpanFromContext(ctx)
|
||||
|
||||
if span != nil {
|
||||
opts = append(opts, ext.SpanKindRPCClient)
|
||||
span, _ = opentracing.StartSpanFromContextWithTracer(
|
||||
ctx, span.Tracer(), operationName(op), opts...)
|
||||
|
||||
ext.Component.Set(span, "go-openapi")
|
||||
ext.PeerHostname.Set(span, host)
|
||||
span.SetTag("http.path", op.PathPattern)
|
||||
ext.HTTPMethod.Set(span, op.Method)
|
||||
|
||||
_ = span.Tracer().Inject(
|
||||
span.Context(),
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(header))
|
||||
|
||||
return span
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func operationName(op *runtime.ClientOperation) string {
|
||||
if op.ID != "" {
|
||||
return op.ID
|
||||
}
|
||||
return fmt.Sprintf("%s_%s", op.Method, op.PathPattern)
|
||||
}
|
||||
81
vendor/github.com/go-openapi/runtime/client/request.go
generated
vendored
81
vendor/github.com/go-openapi/runtime/client/request.go
generated
vendored
@@ -93,6 +93,15 @@ func (r *request) BuildHTTP(mediaType, basePath string, producers map[string]run
|
||||
func escapeQuotes(s string) string {
|
||||
return strings.NewReplacer("\\", "\\\\", `"`, "\\\"").Replace(s)
|
||||
}
|
||||
|
||||
func logClose(err error, pw *io.PipeWriter) {
|
||||
log.Println(err)
|
||||
closeErr := pw.CloseWithError(err)
|
||||
if closeErr != nil {
|
||||
log.Println(closeErr)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) {
|
||||
// build the data
|
||||
if err := r.writer.WriteToRequest(r, registry); err != nil {
|
||||
@@ -137,8 +146,8 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
for fn, v := range r.formFields {
|
||||
for _, vi := range v {
|
||||
if err := mp.WriteField(fn, vi); err != nil {
|
||||
pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
logClose(err, pw)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,18 +161,15 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
}()
|
||||
for fn, f := range r.fileFields {
|
||||
for _, fi := range f {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
|
||||
// Need to read the data so that we can detect the content type
|
||||
_, err := io.Copy(buf, fi)
|
||||
buf := make([]byte, 512)
|
||||
size, err := fi.Read(buf)
|
||||
if err != nil {
|
||||
_ = pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
logClose(err, pw)
|
||||
return
|
||||
}
|
||||
fileBytes := buf.Bytes()
|
||||
fileContentType := http.DetectContentType(fileBytes)
|
||||
|
||||
newFi := runtime.NamedReader(fi.Name(), buf)
|
||||
fileContentType := http.DetectContentType(buf)
|
||||
newFi := runtime.NamedReader(fi.Name(), io.MultiReader(bytes.NewReader(buf[:size]), fi))
|
||||
|
||||
// Create the MIME headers for the new part
|
||||
h := make(textproto.MIMEHeader)
|
||||
@@ -174,11 +180,11 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
|
||||
wrtr, err := mp.CreatePart(h)
|
||||
if err != nil {
|
||||
pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
} else if _, err := io.Copy(wrtr, newFi); err != nil {
|
||||
pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
logClose(err, pw)
|
||||
return
|
||||
}
|
||||
if _, err := io.Copy(wrtr, newFi); err != nil {
|
||||
logClose(err, pw)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,7 +217,7 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
|
||||
DoneChoosingBodySource:
|
||||
|
||||
if runtime.CanHaveBody(r.method) && body == nil && r.header.Get(runtime.HeaderContentType) == "" {
|
||||
if runtime.CanHaveBody(r.method) && body != nil && r.header.Get(runtime.HeaderContentType) == "" {
|
||||
r.header.Set(runtime.HeaderContentType, mediaType)
|
||||
}
|
||||
|
||||
@@ -273,12 +279,36 @@ DoneChoosingBodySource:
|
||||
}
|
||||
}
|
||||
|
||||
// In case the basePath or the request pathPattern include static query parameters,
|
||||
// parse those out before constructing the final path. The parameters themselves
|
||||
// will be merged with the ones set by the client, with the priority given first to
|
||||
// the ones set by the client, then the path pattern, and lastly the base path.
|
||||
basePathURL, err := url.Parse(basePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
staticQueryParams := basePathURL.Query()
|
||||
|
||||
pathPatternURL, err := url.Parse(r.pathPattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for name, values := range pathPatternURL.Query() {
|
||||
if _, present := staticQueryParams[name]; present {
|
||||
staticQueryParams.Del(name)
|
||||
}
|
||||
for _, value := range values {
|
||||
staticQueryParams.Add(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
// create http request
|
||||
var reinstateSlash bool
|
||||
if r.pathPattern != "" && r.pathPattern != "/" && r.pathPattern[len(r.pathPattern)-1] == '/' {
|
||||
if pathPatternURL.Path != "" && pathPatternURL.Path != "/" && pathPatternURL.Path[len(pathPatternURL.Path)-1] == '/' {
|
||||
reinstateSlash = true
|
||||
}
|
||||
urlPath := path.Join(basePath, r.pathPattern)
|
||||
|
||||
urlPath := path.Join(basePathURL.Path, pathPatternURL.Path)
|
||||
for k, v := range r.pathParams {
|
||||
urlPath = strings.Replace(urlPath, "{"+k+"}", url.PathEscape(v), -1)
|
||||
}
|
||||
@@ -291,6 +321,19 @@ DoneChoosingBodySource:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
originalParams := r.GetQueryParams()
|
||||
|
||||
// Merge the query parameters extracted from the basePath with the ones set by
|
||||
// the client in this struct. In case of conflict, the client wins.
|
||||
for k, v := range staticQueryParams {
|
||||
_, present := originalParams[k]
|
||||
if !present {
|
||||
if err = r.SetQueryParam(k, v...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.URL.RawQuery = r.query.Encode()
|
||||
req.Header = r.header
|
||||
|
||||
|
||||
6
vendor/github.com/go-openapi/runtime/client/response.go
generated
vendored
6
vendor/github.com/go-openapi/runtime/client/response.go
generated
vendored
@@ -23,6 +23,8 @@ import (
|
||||
|
||||
var _ runtime.ClientResponse = response{}
|
||||
|
||||
func newResponse(resp *http.Response) runtime.ClientResponse { return response{resp: resp} }
|
||||
|
||||
type response struct {
|
||||
resp *http.Response
|
||||
}
|
||||
@@ -39,6 +41,10 @@ func (r response) GetHeader(name string) string {
|
||||
return r.resp.Header.Get(name)
|
||||
}
|
||||
|
||||
func (r response) GetHeaders(name string) []string {
|
||||
return r.resp.Header.Values(name)
|
||||
}
|
||||
|
||||
func (r response) Body() io.ReadCloser {
|
||||
return r.resp.Body
|
||||
}
|
||||
|
||||
104
vendor/github.com/go-openapi/runtime/client/runtime.go
generated
vendored
104
vendor/github.com/go-openapi/runtime/client/runtime.go
generated
vendored
@@ -23,19 +23,21 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/logger"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/runtime/yamlpc"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// TLSClientOptions to configure client authentication with mutual TLS
|
||||
@@ -80,7 +82,7 @@ type TLSClientOptions struct {
|
||||
ServerName string
|
||||
|
||||
// InsecureSkipVerify controls whether the certificate chain and hostname presented
|
||||
// by the server are validated. If false, any certificate is accepted.
|
||||
// by the server are validated. If true, any certificate is accepted.
|
||||
InsecureSkipVerify bool
|
||||
|
||||
// VerifyPeerCertificate, if not nil, is called after normal
|
||||
@@ -162,7 +164,7 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
|
||||
cfg.RootCAs = caCertPool
|
||||
} else if opts.CA != "" {
|
||||
// load ca cert
|
||||
caCert, err := ioutil.ReadFile(opts.CA)
|
||||
caCert, err := os.ReadFile(opts.CA)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tls client ca: %v", err)
|
||||
}
|
||||
@@ -179,8 +181,6 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
|
||||
cfg.ServerName = opts.ServerName
|
||||
}
|
||||
|
||||
cfg.BuildNameToCertificate()
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ type Runtime struct {
|
||||
|
||||
Transport http.RoundTripper
|
||||
Jar http.CookieJar
|
||||
//Spec *spec.Document
|
||||
// Spec *spec.Document
|
||||
Host string
|
||||
BasePath string
|
||||
Formats strfmt.Registry
|
||||
@@ -235,6 +235,7 @@ type Runtime struct {
|
||||
clientOnce *sync.Once
|
||||
client *http.Client
|
||||
schemes []string
|
||||
response ClientResponseFunc
|
||||
}
|
||||
|
||||
// New creates a new default runtime for a swagger api runtime.Client
|
||||
@@ -244,6 +245,7 @@ func New(host, basePath string, schemes []string) *Runtime {
|
||||
|
||||
// TODO: actually infer this stuff from the spec
|
||||
rt.Consumers = map[string]runtime.Consumer{
|
||||
runtime.YAMLMime: yamlpc.YAMLConsumer(),
|
||||
runtime.JSONMime: runtime.JSONConsumer(),
|
||||
runtime.XMLMime: runtime.XMLConsumer(),
|
||||
runtime.TextMime: runtime.TextConsumer(),
|
||||
@@ -252,6 +254,7 @@ func New(host, basePath string, schemes []string) *Runtime {
|
||||
runtime.DefaultMime: runtime.ByteStreamConsumer(),
|
||||
}
|
||||
rt.Producers = map[string]runtime.Producer{
|
||||
runtime.YAMLMime: yamlpc.YAMLProducer(),
|
||||
runtime.JSONMime: runtime.JSONProducer(),
|
||||
runtime.XMLMime: runtime.XMLProducer(),
|
||||
runtime.TextMime: runtime.TextProducer(),
|
||||
@@ -271,6 +274,7 @@ func New(host, basePath string, schemes []string) *Runtime {
|
||||
|
||||
rt.Debug = logger.DebugEnabled()
|
||||
rt.logger = logger.StandardLogger{}
|
||||
rt.response = newResponse
|
||||
|
||||
if len(schemes) > 0 {
|
||||
rt.schemes = schemes
|
||||
@@ -289,6 +293,22 @@ func NewWithClient(host, basePath string, schemes []string, client *http.Client)
|
||||
return rt
|
||||
}
|
||||
|
||||
// WithOpenTracing adds opentracing support to the provided runtime.
|
||||
// A new client span is created for each request.
|
||||
// If the context of the client operation does not contain an active span, no span is created.
|
||||
// The provided opts are applied to each spans - for example to add global tags.
|
||||
func (r *Runtime) WithOpenTracing(opts ...opentracing.StartSpanOption) runtime.ClientTransport {
|
||||
return newOpenTracingTransport(r, r.Host, opts)
|
||||
}
|
||||
|
||||
// WithOpenTelemetry adds opentelemetry support to the provided runtime.
|
||||
// A new client span is created for each request.
|
||||
// If the context of the client operation does not contain an active span, no span is created.
|
||||
// The provided opts are applied to each spans - for example to add global tags.
|
||||
func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOpt) runtime.ClientTransport {
|
||||
return newOpenTelemetryTransport(r, r.Host, opts)
|
||||
}
|
||||
|
||||
func (r *Runtime) pickScheme(schemes []string) string {
|
||||
if v := r.selectScheme(r.schemes); v != "" {
|
||||
return v
|
||||
@@ -317,6 +337,7 @@ func (r *Runtime) selectScheme(schemes []string) string {
|
||||
}
|
||||
return scheme
|
||||
}
|
||||
|
||||
func transportOrDefault(left, right http.RoundTripper) http.RoundTripper {
|
||||
if left == nil {
|
||||
return right
|
||||
@@ -346,26 +367,30 @@ func (r *Runtime) EnableConnectionReuse() {
|
||||
)
|
||||
}
|
||||
|
||||
// Submit a request and when there is a body on success it will turn that into the result
|
||||
// all other things are turned into an api error for swagger which retains the status code
|
||||
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
|
||||
params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo
|
||||
// takes a client operation and creates equivalent http.Request
|
||||
func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) {
|
||||
params, _, auth := operation.Params, operation.Reader, operation.AuthInfo
|
||||
|
||||
request, err := newRequest(operation.Method, operation.PathPattern, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var accept []string
|
||||
accept = append(accept, operation.ProducesMediaTypes...)
|
||||
if err = request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if auth == nil && r.DefaultAuthentication != nil {
|
||||
auth = r.DefaultAuthentication
|
||||
auth = runtime.ClientAuthInfoWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
if req.GetHeaderParams().Get(runtime.HeaderAuthorization) != "" {
|
||||
return nil
|
||||
}
|
||||
return r.DefaultAuthentication.AuthenticateRequest(req, reg)
|
||||
})
|
||||
}
|
||||
//if auth != nil {
|
||||
// if auth != nil {
|
||||
// if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
@@ -382,16 +407,33 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
|
||||
}
|
||||
|
||||
if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime {
|
||||
return nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
|
||||
return nil, nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
|
||||
}
|
||||
|
||||
req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
req.URL.Scheme = r.pickScheme(operation.Schemes)
|
||||
req.URL.Host = r.Host
|
||||
req.Host = r.Host
|
||||
return request, req, nil
|
||||
}
|
||||
|
||||
func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) {
|
||||
_, req, err = r.createHttpRequest(operation)
|
||||
return
|
||||
}
|
||||
|
||||
// Submit a request and when there is a body on success it will turn that into the result
|
||||
// all other things are turned into an api error for swagger which retains the status code
|
||||
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
|
||||
_, readResponse, _ := operation.Params, operation.Reader, operation.AuthInfo
|
||||
|
||||
request, req, err := r.createHttpRequest(operation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.clientOnce.Do(func() {
|
||||
r.client = &http.Client{
|
||||
@@ -438,19 +480,23 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
ct := res.Header.Get(runtime.HeaderContentType)
|
||||
if ct == "" { // this should really really never occur
|
||||
ct = r.DefaultMediaType
|
||||
}
|
||||
|
||||
if r.Debug {
|
||||
b, err2 := httputil.DumpResponse(res, true)
|
||||
printBody := true
|
||||
if ct == runtime.DefaultMime {
|
||||
printBody = false // Spare the terminal from a binary blob.
|
||||
}
|
||||
b, err2 := httputil.DumpResponse(res, printBody)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
r.logger.Debugf("%s\n", string(b))
|
||||
}
|
||||
|
||||
ct := res.Header.Get(runtime.HeaderContentType)
|
||||
if ct == "" { // this should really really never occur
|
||||
ct = r.DefaultMediaType
|
||||
}
|
||||
|
||||
mt, _, err := mime.ParseMediaType(ct)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse content type: %s", err)
|
||||
@@ -463,7 +509,7 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
|
||||
return nil, fmt.Errorf("no consumer: %q", ct)
|
||||
}
|
||||
}
|
||||
return readResponse.ReadResponse(response{res}, cons)
|
||||
return readResponse.ReadResponse(r.response(res), cons)
|
||||
}
|
||||
|
||||
// SetDebug changes the debug flag.
|
||||
@@ -479,3 +525,13 @@ func (r *Runtime) SetLogger(logger logger.Logger) {
|
||||
r.logger = logger
|
||||
middleware.Logger = logger
|
||||
}
|
||||
|
||||
type ClientResponseFunc = func(*http.Response) runtime.ClientResponse
|
||||
|
||||
// SetResponseReader changes the response reader implementation.
|
||||
func (r *Runtime) SetResponseReader(f ClientResponseFunc) {
|
||||
if f == nil {
|
||||
return
|
||||
}
|
||||
r.response = f
|
||||
}
|
||||
|
||||
53
vendor/github.com/go-openapi/runtime/client_request.go
generated
vendored
53
vendor/github.com/go-openapi/runtime/client_request.go
generated
vendored
@@ -16,7 +16,6 @@ package runtime
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -79,7 +78,7 @@ type NamedReadCloser interface {
|
||||
func NamedReader(name string, rdr io.Reader) NamedReadCloser {
|
||||
rc, ok := rdr.(io.ReadCloser)
|
||||
if !ok {
|
||||
rc = ioutil.NopCloser(rdr)
|
||||
rc = io.NopCloser(rdr)
|
||||
}
|
||||
return &namedReadCloser{
|
||||
name: name,
|
||||
@@ -101,3 +100,53 @@ func (n *namedReadCloser) Read(p []byte) (int, error) {
|
||||
func (n *namedReadCloser) Name() string {
|
||||
return n.name
|
||||
}
|
||||
|
||||
type TestClientRequest struct {
|
||||
Headers http.Header
|
||||
Body interface{}
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) SetHeaderParam(name string, values ...string) error {
|
||||
if t.Headers == nil {
|
||||
t.Headers = make(http.Header)
|
||||
}
|
||||
t.Headers.Set(name, values[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) SetQueryParam(_ string, _ ...string) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetFormParam(_ string, _ ...string) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetPathParam(_ string, _ string) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetFileParam(_ string, _ ...NamedReadCloser) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetBodyParam(body interface{}) error {
|
||||
t.Body = body
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) SetTimeout(time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) GetQueryParams() url.Values { return nil }
|
||||
|
||||
func (t *TestClientRequest) GetMethod() string { return "" }
|
||||
|
||||
func (t *TestClientRequest) GetPath() string { return "" }
|
||||
|
||||
func (t *TestClientRequest) GetBody() []byte { return nil }
|
||||
|
||||
func (t *TestClientRequest) GetBodyParam() interface{} {
|
||||
return t.Body
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) GetFileParam() map[string][]NamedReadCloser {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) GetHeaderParams() http.Header {
|
||||
return t.Headers
|
||||
}
|
||||
|
||||
51
vendor/github.com/go-openapi/runtime/client_response.go
generated
vendored
51
vendor/github.com/go-openapi/runtime/client_response.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
@@ -25,6 +26,7 @@ type ClientResponse interface {
|
||||
Code() int
|
||||
Message() string
|
||||
GetHeader(string) string
|
||||
GetHeaders(string) []string
|
||||
Body() io.ReadCloser
|
||||
}
|
||||
|
||||
@@ -58,6 +60,51 @@ type APIError struct {
|
||||
Code int
|
||||
}
|
||||
|
||||
func (a *APIError) Error() string {
|
||||
return fmt.Sprintf("%s (status %d): %+v ", a.OperationName, a.Code, a.Response)
|
||||
func (o *APIError) Error() string {
|
||||
var resp []byte
|
||||
if err, ok := o.Response.(error); ok {
|
||||
resp = []byte("'" + err.Error() + "'")
|
||||
} else {
|
||||
resp, _ = json.Marshal(o.Response)
|
||||
}
|
||||
return fmt.Sprintf("%s (status %d): %s", o.OperationName, o.Code, resp)
|
||||
}
|
||||
|
||||
func (o *APIError) String() string {
|
||||
return o.Error()
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this elapse o k response returns a 2xx status code
|
||||
func (o *APIError) IsSuccess() bool {
|
||||
return o.Code/100 == 2
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this elapse o k response returns a 3xx status code
|
||||
func (o *APIError) IsRedirect() bool {
|
||||
return o.Code/100 == 3
|
||||
}
|
||||
|
||||
// IsClientError returns true when this elapse o k response returns a 4xx status code
|
||||
func (o *APIError) IsClientError() bool {
|
||||
return o.Code/100 == 4
|
||||
}
|
||||
|
||||
// IsServerError returns true when this elapse o k response returns a 5xx status code
|
||||
func (o *APIError) IsServerError() bool {
|
||||
return o.Code/100 == 5
|
||||
}
|
||||
|
||||
// IsCode returns true when this elapse o k response returns a 4xx status code
|
||||
func (o *APIError) IsCode(code int) bool {
|
||||
return o.Code == code
|
||||
}
|
||||
|
||||
// A ClientResponseStatus is a common interface implemented by all responses on the generated code
|
||||
// You can use this to treat any client response based on status code
|
||||
type ClientResponseStatus interface {
|
||||
IsSuccess() bool
|
||||
IsRedirect() bool
|
||||
IsClientError() bool
|
||||
IsServerError() bool
|
||||
IsCode(int) bool
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-openapi/runtime/constants.go
generated
vendored
2
vendor/github.com/go-openapi/runtime/constants.go
generated
vendored
@@ -23,6 +23,8 @@ const (
|
||||
|
||||
// HeaderAccept the Accept header
|
||||
HeaderAccept = "Accept"
|
||||
// HeaderAuthorization the Authorization header
|
||||
HeaderAuthorization = "Authorization"
|
||||
|
||||
charsetKey = "charset"
|
||||
|
||||
|
||||
18
vendor/github.com/go-openapi/runtime/file.go
generated
vendored
18
vendor/github.com/go-openapi/runtime/file.go
generated
vendored
@@ -14,20 +14,6 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "mime/multipart"
|
||||
import "github.com/go-openapi/swag"
|
||||
|
||||
// File represents an uploaded file.
|
||||
type File struct {
|
||||
Data multipart.File
|
||||
Header *multipart.FileHeader
|
||||
}
|
||||
|
||||
// Read bytes from the file
|
||||
func (f *File) Read(p []byte) (n int, err error) {
|
||||
return f.Data.Read(p)
|
||||
}
|
||||
|
||||
// Close the file
|
||||
func (f *File) Close() error {
|
||||
return f.Data.Close()
|
||||
}
|
||||
type File = swag.File
|
||||
|
||||
9
vendor/github.com/go-openapi/runtime/interfaces.go
generated
vendored
9
vendor/github.com/go-openapi/runtime/interfaces.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
@@ -101,3 +102,11 @@ type Authorizer interface {
|
||||
type Validatable interface {
|
||||
Validate(strfmt.Registry) error
|
||||
}
|
||||
|
||||
// ContextValidatable types implementing this interface allow customizing their validation
|
||||
// this will be used instead of the reflective validation based on the spec document.
|
||||
// the implementations are assumed to have been generated by the swagger tool so they should
|
||||
// contain all the context validations obtained from the spec
|
||||
type ContextValidatable interface {
|
||||
ContextValidate(context.Context, strfmt.Registry) error
|
||||
}
|
||||
|
||||
39
vendor/github.com/go-openapi/runtime/middleware/context.go
generated
vendored
39
vendor/github.com/go-openapi/runtime/middleware/context.go
generated
vendored
@@ -195,6 +195,17 @@ func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Ro
|
||||
if spec != nil {
|
||||
an = analysis.New(spec.Spec())
|
||||
}
|
||||
|
||||
return NewRoutableContextWithAnalyzedSpec(spec, an, routableAPI, routes)
|
||||
}
|
||||
|
||||
// NewRoutableContextWithAnalyzedSpec is like NewRoutableContext but takes in input the analysed spec too
|
||||
func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context {
|
||||
// Either there are no spec doc and analysis, or both of them.
|
||||
if !((spec == nil && an == nil) || (spec != nil && an != nil)) {
|
||||
panic(errors.New(http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
|
||||
}
|
||||
|
||||
ctx := &Context{spec: spec, api: routableAPI, analyzer: an, router: routes}
|
||||
return ctx
|
||||
}
|
||||
@@ -435,6 +446,10 @@ func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interfa
|
||||
}
|
||||
if route.Authorizer != nil {
|
||||
if err := route.Authorizer.Authorize(request, usr); err != nil {
|
||||
if _, ok := err.(errors.Error); ok {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return nil, nil, errors.New(http.StatusForbidden, err.Error())
|
||||
}
|
||||
}
|
||||
@@ -494,7 +509,9 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
|
||||
if resp, ok := data.(Responder); ok {
|
||||
producers := route.Producers
|
||||
prod, ok := producers[format]
|
||||
// producers contains keys with normalized format, if a format has MIME type parameter such as `text/plain; charset=utf-8`
|
||||
// then you must provide `text/plain` to get the correct producer. HOWEVER, format here is not normalized.
|
||||
prod, ok := producers[normalizeOffer(format)]
|
||||
if !ok {
|
||||
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
|
||||
pr, ok := prods[c.api.DefaultProduces()]
|
||||
@@ -567,6 +584,26 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
|
||||
}
|
||||
|
||||
func (c *Context) APIHandlerSwaggerUI(builder Builder) http.Handler {
|
||||
b := builder
|
||||
if b == nil {
|
||||
b = PassthroughBuilder
|
||||
}
|
||||
|
||||
var title string
|
||||
sp := c.spec.Spec()
|
||||
if sp != nil && sp.Info != nil && sp.Info.Title != "" {
|
||||
title = sp.Info.Title
|
||||
}
|
||||
|
||||
swaggerUIOpts := SwaggerUIOpts{
|
||||
BasePath: c.BasePath(),
|
||||
Title: title,
|
||||
}
|
||||
|
||||
return Spec("", c.spec.Raw(), SwaggerUI(swaggerUIOpts, c.RoutesHandler(b)))
|
||||
}
|
||||
|
||||
// APIHandler returns a handler to serve the API, this includes a swagger spec, router and the contract defined in the swagger spec
|
||||
func (c *Context) APIHandler(builder Builder) http.Handler {
|
||||
b := builder
|
||||
|
||||
6
vendor/github.com/go-openapi/runtime/middleware/denco/router.go
generated
vendored
6
vendor/github.com/go-openapi/runtime/middleware/denco/router.go
generated
vendored
@@ -20,6 +20,9 @@ const (
|
||||
// SeparatorCharacter separates path segments.
|
||||
SeparatorCharacter = '/'
|
||||
|
||||
// PathParamCharacter indicates a RESTCONF path param
|
||||
PathParamCharacter = '='
|
||||
|
||||
// MaxSize is max size of records and internal slice.
|
||||
MaxSize = (1 << 22) - 1
|
||||
)
|
||||
@@ -426,8 +429,9 @@ func makeRecords(srcs []Record) (statics, params []*record) {
|
||||
termChar := string(TerminationCharacter)
|
||||
paramPrefix := string(SeparatorCharacter) + string(ParamCharacter)
|
||||
wildcardPrefix := string(SeparatorCharacter) + string(WildcardCharacter)
|
||||
restconfPrefix := string(PathParamCharacter) + string(ParamCharacter)
|
||||
for _, r := range srcs {
|
||||
if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) {
|
||||
if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) ||strings.Contains(r.Key, restconfPrefix){
|
||||
r.Key += termChar
|
||||
params = append(params, &record{Record: r})
|
||||
} else {
|
||||
|
||||
7
vendor/github.com/go-openapi/runtime/middleware/header/header.go
generated
vendored
7
vendor/github.com/go-openapi/runtime/middleware/header/header.go
generated
vendored
@@ -265,13 +265,16 @@ func expectQuality(s string) (q float64, rest string) {
|
||||
case len(s) == 0:
|
||||
return -1, ""
|
||||
case s[0] == '0':
|
||||
q = 0
|
||||
// q is already 0
|
||||
s = s[1:]
|
||||
case s[0] == '1':
|
||||
s = s[1:]
|
||||
q = 1
|
||||
case s[0] == '.':
|
||||
// q is already 0
|
||||
default:
|
||||
return -1, ""
|
||||
}
|
||||
s = s[1:]
|
||||
if !strings.HasPrefix(s, ".") {
|
||||
return q, s
|
||||
}
|
||||
|
||||
10
vendor/github.com/go-openapi/runtime/middleware/parameter.go
generated
vendored
10
vendor/github.com/go-openapi/runtime/middleware/parameter.go
generated
vendored
@@ -206,7 +206,11 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
|
||||
if p.parameter.Type == "file" {
|
||||
file, header, ffErr := request.FormFile(p.parameter.Name)
|
||||
if ffErr != nil {
|
||||
return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
|
||||
if p.parameter.Required {
|
||||
return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header}))
|
||||
return nil
|
||||
@@ -276,7 +280,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue in
|
||||
}
|
||||
|
||||
if (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) && p.parameter.Required && p.parameter.Default == nil {
|
||||
return errors.Required(p.Name, p.parameter.In)
|
||||
return errors.Required(p.Name, p.parameter.In, data)
|
||||
}
|
||||
|
||||
ok, err := p.tryUnmarshaler(target, defaultValue, data)
|
||||
@@ -451,7 +455,7 @@ func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target re
|
||||
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
|
||||
sz := len(data)
|
||||
if (!hasKey || (!p.parameter.AllowEmptyValue && (sz == 0 || (sz == 1 && data[0] == "")))) && p.parameter.Required && defaultValue == nil {
|
||||
return errors.Required(p.Name, p.parameter.In)
|
||||
return errors.Required(p.Name, p.parameter.In, data)
|
||||
}
|
||||
|
||||
defVal := reflect.Zero(target.Type())
|
||||
|
||||
90
vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
generated
vendored
Normal file
90
vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
)
|
||||
|
||||
// RapiDocOpts configures the RapiDoc middlewares
|
||||
type RapiDocOpts struct {
|
||||
// BasePath for the UI path, defaults to: /
|
||||
BasePath string
|
||||
// Path combines with BasePath for the full UI path, defaults to: docs
|
||||
Path string
|
||||
// SpecURL the url to find the spec for
|
||||
SpecURL string
|
||||
// RapiDocURL for the js that generates the rapidoc site, defaults to: https://cdn.jsdelivr.net/npm/rapidoc/bundles/rapidoc.standalone.js
|
||||
RapiDocURL string
|
||||
// Title for the documentation site, default to: API documentation
|
||||
Title string
|
||||
}
|
||||
|
||||
// EnsureDefaults in case some options are missing
|
||||
func (r *RapiDocOpts) EnsureDefaults() {
|
||||
if r.BasePath == "" {
|
||||
r.BasePath = "/"
|
||||
}
|
||||
if r.Path == "" {
|
||||
r.Path = "docs"
|
||||
}
|
||||
if r.SpecURL == "" {
|
||||
r.SpecURL = "/swagger.json"
|
||||
}
|
||||
if r.RapiDocURL == "" {
|
||||
r.RapiDocURL = rapidocLatest
|
||||
}
|
||||
if r.Title == "" {
|
||||
r.Title = "API documentation"
|
||||
}
|
||||
}
|
||||
|
||||
// RapiDoc creates a middleware to serve a documentation site for a swagger spec.
|
||||
// This allows for altering the spec before starting the http listener.
|
||||
//
|
||||
func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler {
|
||||
opts.EnsureDefaults()
|
||||
|
||||
pth := path.Join(opts.BasePath, opts.Path)
|
||||
tmpl := template.Must(template.New("rapidoc").Parse(rapidocTemplate))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_ = tmpl.Execute(buf, opts)
|
||||
b := buf.Bytes()
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == pth {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
||||
_, _ = rw.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
if next == nil {
|
||||
rw.Header().Set("Content-Type", "text/plain")
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
rapidocLatest = "https://unpkg.com/rapidoc/dist/rapidoc-min.js"
|
||||
rapidocTemplate = `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ .Title }}</title>
|
||||
<meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 charecters -->
|
||||
<script type="module" src="{{ .RapiDocURL }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<rapi-doc spec-url="{{ .SpecURL }}"></rapi-doc>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
)
|
||||
10
vendor/github.com/go-openapi/runtime/middleware/router.go
generated
vendored
10
vendor/github.com/go-openapi/runtime/middleware/router.go
generated
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/runtime/security"
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/errors"
|
||||
@@ -418,6 +419,15 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
|
||||
produces := d.analyzer.ProducesFor(operation)
|
||||
parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp))
|
||||
|
||||
// add API defaults if not part of the spec
|
||||
if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !swag.ContainsStringsCI(consumes, defConsumes) {
|
||||
consumes = append(consumes, defConsumes)
|
||||
}
|
||||
|
||||
if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) {
|
||||
produces = append(produces, defProduces)
|
||||
}
|
||||
|
||||
record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{
|
||||
BasePath: bp,
|
||||
PathPattern: path,
|
||||
|
||||
168
vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
generated
vendored
Normal file
168
vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
)
|
||||
|
||||
// SwaggerUIOpts configures the Swaggerui middlewares
|
||||
type SwaggerUIOpts struct {
|
||||
// BasePath for the UI path, defaults to: /
|
||||
BasePath string
|
||||
// Path combines with BasePath for the full UI path, defaults to: docs
|
||||
Path string
|
||||
// SpecURL the url to find the spec for
|
||||
SpecURL string
|
||||
// OAuthCallbackURL the url called after OAuth2 login
|
||||
OAuthCallbackURL string
|
||||
|
||||
// The three components needed to embed swagger-ui
|
||||
SwaggerURL string
|
||||
SwaggerPresetURL string
|
||||
SwaggerStylesURL string
|
||||
|
||||
Favicon32 string
|
||||
Favicon16 string
|
||||
|
||||
// Title for the documentation site, default to: API documentation
|
||||
Title string
|
||||
}
|
||||
|
||||
// EnsureDefaults in case some options are missing
|
||||
func (r *SwaggerUIOpts) EnsureDefaults() {
|
||||
if r.BasePath == "" {
|
||||
r.BasePath = "/"
|
||||
}
|
||||
if r.Path == "" {
|
||||
r.Path = "docs"
|
||||
}
|
||||
if r.SpecURL == "" {
|
||||
r.SpecURL = "/swagger.json"
|
||||
}
|
||||
if r.OAuthCallbackURL == "" {
|
||||
r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback")
|
||||
}
|
||||
if r.SwaggerURL == "" {
|
||||
r.SwaggerURL = swaggerLatest
|
||||
}
|
||||
if r.SwaggerPresetURL == "" {
|
||||
r.SwaggerPresetURL = swaggerPresetLatest
|
||||
}
|
||||
if r.SwaggerStylesURL == "" {
|
||||
r.SwaggerStylesURL = swaggerStylesLatest
|
||||
}
|
||||
if r.Favicon16 == "" {
|
||||
r.Favicon16 = swaggerFavicon16Latest
|
||||
}
|
||||
if r.Favicon32 == "" {
|
||||
r.Favicon32 = swaggerFavicon32Latest
|
||||
}
|
||||
if r.Title == "" {
|
||||
r.Title = "API documentation"
|
||||
}
|
||||
}
|
||||
|
||||
// SwaggerUI creates a middleware to serve a documentation site for a swagger spec.
|
||||
// This allows for altering the spec before starting the http listener.
|
||||
func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler {
|
||||
opts.EnsureDefaults()
|
||||
|
||||
pth := path.Join(opts.BasePath, opts.Path)
|
||||
tmpl := template.Must(template.New("swaggerui").Parse(swaggeruiTemplate))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_ = tmpl.Execute(buf, &opts)
|
||||
b := buf.Bytes()
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if path.Join(r.URL.Path) == pth {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
||||
_, _ = rw.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
if next == nil {
|
||||
rw.Header().Set("Content-Type", "text/plain")
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
swaggerLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"
|
||||
swaggerPresetLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"
|
||||
swaggerStylesLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui.css"
|
||||
swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png"
|
||||
swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png"
|
||||
swaggeruiTemplate = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ .Title }}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{ .SwaggerStylesURL }}" >
|
||||
<link rel="icon" type="image/png" href="{{ .Favicon32 }}" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="{{ .Favicon16 }}" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="{{ .SwaggerURL }}"> </script>
|
||||
<script src="{{ .SwaggerPresetURL }}"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: '{{ .SpecURL }}',
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
oauth2RedirectUrl: '{{ .OAuthCallbackURL }}'
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
)
|
||||
122
vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
generated
vendored
Normal file
122
vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler {
|
||||
opts.EnsureDefaults()
|
||||
|
||||
pth := opts.OAuthCallbackURL
|
||||
tmpl := template.Must(template.New("swaggeroauth").Parse(swaggerOAuthTemplate))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_ = tmpl.Execute(buf, &opts)
|
||||
b := buf.Bytes()
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if path.Join(r.URL.Path) == pth {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
||||
_, _ = rw.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
if next == nil {
|
||||
rw.Header().Set("Content-Type", "text/plain")
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
swaggerOAuthTemplate = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1).replace('?', '&');
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
}
|
||||
) : {};
|
||||
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
run();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
)
|
||||
2
vendor/github.com/go-openapi/runtime/request.go
generated
vendored
2
vendor/github.com/go-openapi/runtime/request.go
generated
vendored
@@ -48,7 +48,7 @@ func HasBody(r *http.Request) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if r.Header.Get(http.CanonicalHeaderKey("content-length")) != "" {
|
||||
if r.Header.Get("content-length") != "" {
|
||||
// in this case, no Transfer-Encoding should be present
|
||||
// we have a header set but it was explicitly set to 0, so we assume no body
|
||||
return false
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user