summaryrefslogtreecommitdiffstats
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/d5/tengo/README.md1
-rw-r--r--vendor/github.com/d5/tengo/compiler/ast/ident_list.go15
-rw-r--r--vendor/github.com/d5/tengo/compiler/compiler.go1
-rw-r--r--vendor/github.com/d5/tengo/compiler/instructions.go2
-rw-r--r--vendor/github.com/d5/tengo/compiler/parser/parser.go20
-rw-r--r--vendor/github.com/d5/tengo/compiler/symbol_scopes.go6
-rw-r--r--vendor/github.com/d5/tengo/objects/builtin_format.go27
-rw-r--r--vendor/github.com/d5/tengo/objects/builtins.go4
-rw-r--r--vendor/github.com/d5/tengo/objects/bytes.go2
-rw-r--r--vendor/github.com/d5/tengo/objects/compiled_function.go2
-rw-r--r--vendor/github.com/d5/tengo/objects/conversion.go2
-rw-r--r--vendor/github.com/d5/tengo/objects/formatter.go1212
-rw-r--r--vendor/github.com/d5/tengo/objects/map.go4
-rw-r--r--vendor/github.com/d5/tengo/objects/undefined.go20
-rw-r--r--vendor/github.com/d5/tengo/runtime/vm.go63
-rw-r--r--vendor/github.com/d5/tengo/script/script.go9
-rw-r--r--vendor/github.com/d5/tengo/stdlib/fmt.go20
-rw-r--r--vendor/github.com/d5/tengo/stdlib/text.go193
-rw-r--r--vendor/github.com/gorilla/schema/README.md16
-rw-r--r--vendor/github.com/gorilla/schema/cache.go79
-rw-r--r--vendor/github.com/gorilla/schema/decoder.go99
-rw-r--r--vendor/github.com/hashicorp/golang-lru/lru.go30
-rw-r--r--vendor/github.com/labstack/echo/v4/.travis.yml1
-rw-r--r--vendor/github.com/labstack/echo/v4/README.md27
-rw-r--r--vendor/github.com/labstack/echo/v4/bind.go21
-rw-r--r--vendor/github.com/labstack/echo/v4/context.go12
-rw-r--r--vendor/github.com/labstack/echo/v4/echo.go151
-rw-r--r--vendor/github.com/labstack/echo/v4/go.mod16
-rw-r--r--vendor/github.com/labstack/echo/v4/go.sum50
-rw-r--r--vendor/github.com/labstack/echo/v4/group.go25
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/compress.go3
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/cors.go4
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/jwt.go33
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/key_auth.go7
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/logger.go8
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/proxy.go2
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/redirect.go10
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/secure.go23
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/slash.go6
-rw-r--r--vendor/github.com/labstack/echo/v4/middleware/util.go54
-rw-r--r--vendor/github.com/labstack/echo/v4/response.go5
-rw-r--r--vendor/github.com/labstack/echo/v4/router.go12
-rw-r--r--vendor/github.com/labstack/gommon/bytes/bytes.go2
-rw-r--r--vendor/github.com/labstack/gommon/log/log.go35
-rw-r--r--vendor/github.com/mattn/go-colorable/go.mod2
-rw-r--r--vendor/github.com/mattn/go-isatty/isatty_android.go23
-rw-r--r--vendor/github.com/mattn/go-isatty/isatty_others.go2
-rw-r--r--vendor/github.com/mattn/go-isatty/isatty_tcgets.go (renamed from vendor/github.com/mattn/go-isatty/isatty_linux.go)3
-rw-r--r--vendor/github.com/paulrosania/go-charset/charset/ascii.go2
-rw-r--r--vendor/github.com/paulrosania/go-charset/charset/charset.go2
-rw-r--r--vendor/github.com/sirupsen/logrus/.travis.yml65
-rw-r--r--vendor/github.com/sirupsen/logrus/CHANGELOG.md35
-rw-r--r--vendor/github.com/sirupsen/logrus/README.md1
-rw-r--r--vendor/github.com/sirupsen/logrus/alt_exit.go18
-rw-r--r--vendor/github.com/sirupsen/logrus/entry.go32
-rw-r--r--vendor/github.com/sirupsen/logrus/exported.go6
-rw-r--r--vendor/github.com/sirupsen/logrus/go.mod3
-rw-r--r--vendor/github.com/sirupsen/logrus/go.sum5
-rw-r--r--vendor/github.com/sirupsen/logrus/json_formatter.go22
-rw-r--r--vendor/github.com/sirupsen/logrus/logger.go12
-rw-r--r--vendor/github.com/sirupsen/logrus/logrus.go2
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_aix.go9
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_bsd.go13
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go (renamed from vendor/github.com/sirupsen/logrus/terminal_check_js.go)2
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go6
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_solaris.go11
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_unix.go13
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_windows.go18
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_notwindows.go8
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_windows.go18
-rw-r--r--vendor/github.com/sirupsen/logrus/text_formatter.go64
-rw-r--r--vendor/github.com/spf13/viper/go.mod29
-rw-r--r--vendor/github.com/spf13/viper/go.sum157
-rw-r--r--vendor/github.com/spf13/viper/viper.go55
-rw-r--r--vendor/github.com/valyala/fasttemplate/go.mod3
-rw-r--r--vendor/github.com/valyala/fasttemplate/go.sum2
-rw-r--r--vendor/github.com/zfjagann/golang-ring/ring.go2
77 files changed, 2563 insertions, 416 deletions
diff --git a/vendor/github.com/d5/tengo/README.md b/vendor/github.com/d5/tengo/README.md
index e68b0f86..6a35cfd1 100644
--- a/vendor/github.com/d5/tengo/README.md
+++ b/vendor/github.com/d5/tengo/README.md
@@ -7,6 +7,7 @@
[![GoDoc](https://godoc.org/github.com/d5/tengo?status.svg)](https://godoc.org/github.com/d5/tengo/script)
[![Go Report Card](https://goreportcard.com/badge/github.com/d5/tengo)](https://goreportcard.com/report/github.com/d5/tengo)
[![Build Status](https://travis-ci.org/d5/tengo.svg?branch=master)](https://travis-ci.org/d5/tengo)
+[![Sourcegraph](https://sourcegraph.com/github.com/d5/tengo/-/badge.svg)](https://sourcegraph.com/github.com/d5/tengo?badge)
**Tengo is a small, dynamic, fast, secure script language for Go.**
diff --git a/vendor/github.com/d5/tengo/compiler/ast/ident_list.go b/vendor/github.com/d5/tengo/compiler/ast/ident_list.go
index ee8f7db2..8dd6d307 100644
--- a/vendor/github.com/d5/tengo/compiler/ast/ident_list.go
+++ b/vendor/github.com/d5/tengo/compiler/ast/ident_list.go
@@ -8,9 +8,10 @@ import (
// IdentList represents a list of identifiers.
type IdentList struct {
- LParen source.Pos
- List []*Ident
- RParen source.Pos
+ LParen source.Pos
+ VarArgs bool
+ List []*Ident
+ RParen source.Pos
}
// Pos returns the position of first character belonging to the node.
@@ -50,8 +51,12 @@ func (n *IdentList) NumFields() int {
func (n *IdentList) String() string {
var list []string
- for _, e := range n.List {
- list = append(list, e.String())
+ for i, e := range n.List {
+ if n.VarArgs && i == len(n.List)-1 {
+ list = append(list, "..."+e.String())
+ } else {
+ list = append(list, e.String())
+ }
}
return "(" + strings.Join(list, ", ") + ")"
diff --git a/vendor/github.com/d5/tengo/compiler/compiler.go b/vendor/github.com/d5/tengo/compiler/compiler.go
index 4a3ec3ad..8bde5dc9 100644
--- a/vendor/github.com/d5/tengo/compiler/compiler.go
+++ b/vendor/github.com/d5/tengo/compiler/compiler.go
@@ -477,6 +477,7 @@ func (c *Compiler) Compile(node ast.Node) error {
Instructions: instructions,
NumLocals: numLocals,
NumParameters: len(node.Type.Params.List),
+ VarArgs: node.Type.Params.VarArgs,
SourceMap: sourceMap,
}
diff --git a/vendor/github.com/d5/tengo/compiler/instructions.go b/vendor/github.com/d5/tengo/compiler/instructions.go
index 80c88d13..14dde1d8 100644
--- a/vendor/github.com/d5/tengo/compiler/instructions.go
+++ b/vendor/github.com/d5/tengo/compiler/instructions.go
@@ -13,7 +13,7 @@ func MakeInstruction(opcode Opcode, operands ...int) []byte {
totalLen += w
}
- instruction := make([]byte, totalLen, totalLen)
+ instruction := make([]byte, totalLen)
instruction[0] = byte(opcode)
offset := 1
diff --git a/vendor/github.com/d5/tengo/compiler/parser/parser.go b/vendor/github.com/d5/tengo/compiler/parser/parser.go
index 1f609ab5..27dd48f0 100644
--- a/vendor/github.com/d5/tengo/compiler/parser/parser.go
+++ b/vendor/github.com/d5/tengo/compiler/parser/parser.go
@@ -610,19 +610,31 @@ func (p *Parser) parseIdentList() *ast.IdentList {
var params []*ast.Ident
lparen := p.expect(token.LParen)
+ isVarArgs := false
if p.token != token.RParen {
+ if p.token == token.Ellipsis {
+ isVarArgs = true
+ p.next()
+ }
+
params = append(params, p.parseIdent())
- for p.token == token.Comma {
+ for !isVarArgs && p.token == token.Comma {
p.next()
+ if p.token == token.Ellipsis {
+ isVarArgs = true
+ p.next()
+ }
params = append(params, p.parseIdent())
}
}
+
rparen := p.expect(token.RParen)
return &ast.IdentList{
- LParen: lparen,
- RParen: rparen,
- List: params,
+ LParen: lparen,
+ RParen: rparen,
+ VarArgs: isVarArgs,
+ List: params,
}
}
diff --git a/vendor/github.com/d5/tengo/compiler/symbol_scopes.go b/vendor/github.com/d5/tengo/compiler/symbol_scopes.go
index 15204b35..e0c0d94b 100644
--- a/vendor/github.com/d5/tengo/compiler/symbol_scopes.go
+++ b/vendor/github.com/d5/tengo/compiler/symbol_scopes.go
@@ -6,7 +6,7 @@ type SymbolScope string
// List of symbol scopes
const (
ScopeGlobal SymbolScope = "GLOBAL"
- ScopeLocal = "LOCAL"
- ScopeBuiltin = "BUILTIN"
- ScopeFree = "FREE"
+ ScopeLocal SymbolScope = "LOCAL"
+ ScopeBuiltin SymbolScope = "BUILTIN"
+ ScopeFree SymbolScope = "FREE"
)
diff --git a/vendor/github.com/d5/tengo/objects/builtin_format.go b/vendor/github.com/d5/tengo/objects/builtin_format.go
new file mode 100644
index 00000000..1f0e75ed
--- /dev/null
+++ b/vendor/github.com/d5/tengo/objects/builtin_format.go
@@ -0,0 +1,27 @@
+package objects
+
+func builtinFormat(args ...Object) (Object, error) {
+ numArgs := len(args)
+ if numArgs == 0 {
+ return nil, ErrWrongNumArguments
+ }
+
+ format, ok := args[0].(*String)
+ if !ok {
+ return nil, ErrInvalidArgumentType{
+ Name: "format",
+ Expected: "string",
+ Found: args[0].TypeName(),
+ }
+ }
+ if numArgs == 1 {
+ return format, nil // okay to return 'format' directly as String is immutable
+ }
+
+ s, err := Format(format.Value, args[1:]...)
+ if err != nil {
+ return nil, err
+ }
+
+ return &String{Value: s}, nil
+}
diff --git a/vendor/github.com/d5/tengo/objects/builtins.go b/vendor/github.com/d5/tengo/objects/builtins.go
index bfd004dd..773636ec 100644
--- a/vendor/github.com/d5/tengo/objects/builtins.go
+++ b/vendor/github.com/d5/tengo/objects/builtins.go
@@ -111,4 +111,8 @@ var Builtins = []*BuiltinFunction{
Name: "type_name",
Value: builtinTypeName,
},
+ {
+ Name: "format",
+ Value: builtinFormat,
+ },
}
diff --git a/vendor/github.com/d5/tengo/objects/bytes.go b/vendor/github.com/d5/tengo/objects/bytes.go
index 6710c7c1..5159c22f 100644
--- a/vendor/github.com/d5/tengo/objects/bytes.go
+++ b/vendor/github.com/d5/tengo/objects/bytes.go
@@ -57,7 +57,7 @@ func (o *Bytes) Equals(x Object) bool {
return false
}
- return bytes.Compare(o.Value, t.Value) == 0
+ return bytes.Equal(o.Value, t.Value)
}
// IndexGet returns an element (as Int) at a given index.
diff --git a/vendor/github.com/d5/tengo/objects/compiled_function.go b/vendor/github.com/d5/tengo/objects/compiled_function.go
index 606e3d90..d42e69ec 100644
--- a/vendor/github.com/d5/tengo/objects/compiled_function.go
+++ b/vendor/github.com/d5/tengo/objects/compiled_function.go
@@ -10,6 +10,7 @@ type CompiledFunction struct {
Instructions []byte
NumLocals int // number of local variables (including function parameters)
NumParameters int
+ VarArgs bool
SourceMap map[int]source.Pos
}
@@ -34,6 +35,7 @@ func (o *CompiledFunction) Copy() Object {
Instructions: append([]byte{}, o.Instructions...),
NumLocals: o.NumLocals,
NumParameters: o.NumParameters,
+ VarArgs: o.VarArgs,
}
}
diff --git a/vendor/github.com/d5/tengo/objects/conversion.go b/vendor/github.com/d5/tengo/objects/conversion.go
index d7cb3a03..27514132 100644
--- a/vendor/github.com/d5/tengo/objects/conversion.go
+++ b/vendor/github.com/d5/tengo/objects/conversion.go
@@ -254,7 +254,7 @@ func FromInterface(v interface{}) (Object, error) {
case []Object:
return &Array{Value: v}, nil
case []interface{}:
- arr := make([]Object, len(v), len(v))
+ arr := make([]Object, len(v))
for i, e := range v {
vo, err := FromInterface(e)
if err != nil {
diff --git a/vendor/github.com/d5/tengo/objects/formatter.go b/vendor/github.com/d5/tengo/objects/formatter.go
new file mode 100644
index 00000000..95d7f6b1
--- /dev/null
+++ b/vendor/github.com/d5/tengo/objects/formatter.go
@@ -0,0 +1,1212 @@
+package objects
+
+import (
+ "strconv"
+ "sync"
+ "unicode/utf8"
+
+ "github.com/d5/tengo"
+)
+
+// Strings for use with buffer.WriteString.
+// This is less overhead than using buffer.Write with byte arrays.
+const (
+ commaSpaceString = ", "
+ nilParenString = "(nil)"
+ percentBangString = "%!"
+ missingString = "(MISSING)"
+ badIndexString = "(BADINDEX)"
+ extraString = "%!(EXTRA "
+ badWidthString = "%!(BADWIDTH)"
+ badPrecString = "%!(BADPREC)"
+ noVerbString = "%!(NOVERB)"
+)
+
+const (
+ ldigits = "0123456789abcdefx"
+ udigits = "0123456789ABCDEFX"
+)
+
+const (
+ signed = true
+ unsigned = false
+)
+
+// flags placed in a separate struct for easy clearing.
+type fmtFlags struct {
+ widPresent bool
+ precPresent bool
+ minus bool
+ plus bool
+ sharp bool
+ space bool
+ zero bool
+
+ // For the formats %+v %#v, we set the plusV/sharpV flags
+ // and clear the plus/sharp flags since %+v and %#v are in effect
+ // different, flagless formats set at the top level.
+ plusV bool
+ sharpV bool
+
+ // error-related flags.
+ inDetail bool
+ needNewline bool
+ needColon bool
+}
+
+// A formatter is the raw formatter used by Printf etc.
+// It prints into a buffer that must be set up separately.
+type formatter struct {
+ buf *buffer
+
+ fmtFlags
+
+ wid int // width
+ prec int // precision
+
+ // intbuf is large enough to store %b of an int64 with a sign and
+ // avoids padding at the end of the struct on 32 bit architectures.
+ intbuf [68]byte
+}
+
+func (f *formatter) clearflags() {
+ f.fmtFlags = fmtFlags{}
+}
+
+func (f *formatter) init(buf *buffer) {
+ f.buf = buf
+ f.clearflags()
+}
+
+// writePadding generates n bytes of padding.
+func (f *formatter) writePadding(n int) {
+ if n <= 0 { // No padding bytes needed.
+ return
+ }
+ buf := *f.buf
+ oldLen := len(buf)
+ newLen := oldLen + n
+
+ if newLen > tengo.MaxStringLen {
+ panic(ErrStringLimit)
+ }
+
+ // Make enough room for padding.
+ if newLen > cap(buf) {
+ buf = make(buffer, cap(buf)*2+n)
+ copy(buf, *f.buf)
+ }
+ // Decide which byte the padding should be filled with.
+ padByte := byte(' ')
+ if f.zero {
+ padByte = byte('0')
+ }
+ // Fill padding with padByte.
+ padding := buf[oldLen:newLen]
+ for i := range padding {
+ padding[i] = padByte
+ }
+ *f.buf = buf[:newLen]
+}
+
+// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
+func (f *formatter) pad(b []byte) {
+ if !f.widPresent || f.wid == 0 {
+ f.buf.Write(b)
+ return
+ }
+ width := f.wid - utf8.RuneCount(b)
+ if !f.minus {
+ // left padding
+ f.writePadding(width)
+ f.buf.Write(b)
+ } else {
+ // right padding
+ f.buf.Write(b)
+ f.writePadding(width)
+ }
+}
+
+// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
+func (f *formatter) padString(s string) {
+ if !f.widPresent || f.wid == 0 {
+ f.buf.WriteString(s)
+ return
+ }
+ width := f.wid - utf8.RuneCountInString(s)
+ if !f.minus {
+ // left padding
+ f.writePadding(width)
+ f.buf.WriteString(s)
+ } else {
+ // right padding
+ f.buf.WriteString(s)
+ f.writePadding(width)
+ }
+}
+
+// fmtBoolean formats a boolean.
+func (f *formatter) fmtBoolean(v bool) {
+ if v {
+ f.padString("true")
+ } else {
+ f.padString("false")
+ }
+}
+
+// fmtUnicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
+func (f *formatter) fmtUnicode(u uint64) {
+ buf := f.intbuf[0:]
+
+ // With default precision set the maximum needed buf length is 18
+ // for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
+ // into the already allocated intbuf with a capacity of 68 bytes.
+ prec := 4
+ if f.precPresent && f.prec > 4 {
+ prec = f.prec
+ // Compute space needed for "U+" , number, " '", character, "'".
+ width := 2 + prec + 2 + utf8.UTFMax + 1
+ if width > len(buf) {
+ buf = make([]byte, width)
+ }
+ }
+
+ // Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left.
+ i := len(buf)
+
+ // For %#U we want to add a space and a quoted character at the end of the buffer.
+ if f.sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
+ i--
+ buf[i] = '\''
+ i -= utf8.RuneLen(rune(u))
+ utf8.EncodeRune(buf[i:], rune(u))
+ i--
+ buf[i] = '\''
+ i--
+ buf[i] = ' '
+ }
+ // Format the Unicode code point u as a hexadecimal number.
+ for u >= 16 {
+ i--
+ buf[i] = udigits[u&0xF]
+ prec--
+ u >>= 4
+ }
+ i--
+ buf[i] = udigits[u]
+ prec--
+ // Add zeros in front of the number until requested precision is reached.
+ for prec > 0 {
+ i--
+ buf[i] = '0'
+ prec--
+ }
+ // Add a leading "U+".
+ i--
+ buf[i] = '+'
+ i--
+ buf[i] = 'U'
+
+ oldZero := f.zero
+ f.zero = false
+ f.pad(buf[i:])
+ f.zero = oldZero
+}
+
+// fmtInteger formats signed and unsigned integers.
+func (f *formatter) fmtInteger(u uint64, base int, isSigned bool, verb rune, digits string) {
+ negative := isSigned && int64(u) < 0
+ if negative {
+ u = -u
+ }
+
+ buf := f.intbuf[0:]
+ // The already allocated f.intbuf with a capacity of 68 bytes
+ // is large enough for integer formatting when no precision or width is set.
+ if f.widPresent || f.precPresent {
+ // Account 3 extra bytes for possible addition of a sign and "0x".
+ width := 3 + f.wid + f.prec // wid and prec are always positive.
+ if width > len(buf) {
+ // We're going to need a bigger boat.
+ buf = make([]byte, width)
+ }
+ }
+
+ // Two ways to ask for extra leading zero digits: %.3d or %03d.
+ // If both are specified the f.zero flag is ignored and
+ // padding with spaces is used instead.
+ prec := 0
+ if f.precPresent {
+ prec = f.prec
+ // Precision of 0 and value of 0 means "print nothing" but padding.
+ if prec == 0 && u == 0 {
+ oldZero := f.zero
+ f.zero = false
+ f.writePadding(f.wid)
+ f.zero = oldZero
+ return
+ }
+ } else if f.zero && f.widPresent {
+ prec = f.wid
+ if negative || f.plus || f.space {
+ prec-- // leave room for sign
+ }
+ }
+
+ // Because printing is easier right-to-left: format u into buf, ending at buf[i].
+ // We could make things marginally faster by splitting the 32-bit case out
+ // into a separate block but it's not worth the duplication, so u has 64 bits.
+ i := len(buf)
+ // Use constants for the division and modulo for more efficient code.
+ // Switch cases ordered by popularity.
+ switch base {
+ case 10:
+ for u >= 10 {
+ i--
+ next := u / 10
+ buf[i] = byte('0' + u - next*10)
+ u = next
+ }
+ case 16:
+ for u >= 16 {
+ i--
+ buf[i] = digits[u&0xF]
+ u >>= 4
+ }
+ case 8:
+ for u >= 8 {
+ i--
+ buf[i] = byte('0' + u&7)
+ u >>= 3
+ }
+ case 2:
+ for u >= 2 {
+ i--
+ buf[i] = byte('0' + u&1)
+ u >>= 1
+ }
+ default:
+ panic("fmt: unknown base; can't happen")
+ }
+ i--
+ buf[i] = digits[u]
+ for i > 0 && prec > len(buf)-i {
+ i--
+ buf[i] = '0'
+ }
+
+ // Various prefixes: 0x, -, etc.
+ if f.sharp {
+ switch base {
+ case 2:
+ // Add a leading 0b.
+ i--
+ buf[i] = 'b'
+ i--
+ buf[i] = '0'
+ case 8:
+ if buf[i] != '0' {
+ i--
+ buf[i] = '0'
+ }
+ case 16:
+ // Add a leading 0x or 0X.
+ i--
+ buf[i] = digits[16]
+ i--
+ buf[i] = '0'
+ }
+ }
+ if verb == 'O' {
+ i--
+ buf[i] = 'o'
+ i--
+ buf[i] = '0'
+ }
+
+ if negative {
+ i--
+ buf[i] = '-'
+ } else if f.plus {
+ i--
+ buf[i] = '+'
+ } else if f.space {
+ i--
+ buf[i] = ' '
+ }
+
+ // Left padding with zeros has already been handled like precision earlier
+ // or the f.zero flag is ignored due to an explicitly set precision.
+ oldZero := f.zero
+ f.zero = false
+ f.pad(buf[i:])
+ f.zero = oldZero
+}
+
+// truncate truncates the string s to the specified precision, if present.
+func (f *formatter) truncateString(s string) string {
+ if f.precPresent {
+ n := f.prec
+ for i := range s {
+ n--
+ if n < 0 {
+ return s[:i]
+ }
+ }
+ }
+ return s
+}
+
+// truncate truncates the byte slice b as a string of the specified precision, if present.
+func (f *formatter) truncate(b []byte) []byte {
+ if f.precPresent {
+ n := f.prec
+ for i := 0; i < len(b); {
+ n--
+ if n < 0 {
+ return b[:i]
+ }
+ wid := 1
+ if b[i] >= utf8.RuneSelf {
+ _, wid = utf8.DecodeRune(b[i:])
+ }
+ i += wid
+ }
+ }
+ return b
+}
+
+// fmtS formats a string.
+func (f *formatter) fmtS(s string) {
+ s = f.truncateString(s)
+ f.padString(s)
+}
+
+// fmtBs formats the byte slice b as if it was formatted as string with fmtS.
+func (f *formatter) fmtBs(b []byte) {
+ b = f.truncate(b)
+ f.pad(b)
+}
+
+// fmtSbx formats a string or byte slice as a hexadecimal encoding of its bytes.
+func (f *formatter) fmtSbx(s string, b []byte, digits string) {
+ length := len(b)
+ if b == nil {
+ // No byte slice present. Assume string s should be encoded.
+ length = len(s)
+ }
+ // Set length to not process more bytes than the precision demands.
+ if f.precPresent && f.prec < length {
+ length = f.prec
+ }
+ // Compute width of the encoding taking into account the f.sharp and f.space flag.
+ width := 2 * length
+ if width > 0 {
+ if f.space {
+ // Each element encoded by two hexadecimals will get a leading 0x or 0X.
+ if f.sharp {
+ width *= 2
+ }
+ // Elements will be separated by a space.
+ width += length - 1
+ } else if f.sharp {
+ // Only a leading 0x or 0X will be added for the whole string.
+ width += 2
+ }
+ } else { // The byte slice or string that should be encoded is empty.
+ if f.widPresent {
+ f.writePadding(f.wid)
+ }
+ return
+ }
+ // Handle padding to the left.
+ if f.widPresent && f.wid > width && !f.minus {
+ f.writePadding(f.wid - width)
+ }
+ // Write the encoding directly into the output buffer.
+ buf := *f.buf
+ if f.sharp {
+ // Add leading 0x or 0X.
+ buf = append(buf, '0', digits[16])
+ }
+ var c byte
+ for i := 0; i < length; i++ {
+ if f.space && i > 0 {
+ // Separate elements with a space.
+ buf = append(buf, ' ')
+ if f.sharp {
+ // Add leading 0x or 0X for each element.
+ buf = append(buf, '0', digits[16])
+ }
+ }
+ if b != nil {
+ c = b[i] // Take a byte from the input byte slice.
+ } else {
+ c = s[i] // Take a byte from the input string.
+ }
+ // Encode each byte as two hexadecimal digits.
+ buf = append(buf, digits[c>>4], digits[c&0xF])
+ }
+ *f.buf = buf
+ // Handle padding to the right.
+ if f.widPresent && f.wid > width && f.minus {
+ f.writePadding(f.wid - width)
+ }
+}
+
+// fmtSx formats a string as a hexadecimal encoding of its bytes.
+func (f *formatter) fmtSx(s, digits string) {
+ f.fmtSbx(s, nil, digits)
+}
+
+// fmtBx formats a byte slice as a hexadecimal encoding of its bytes.
+func (f *formatter) fmtBx(b []byte, digits string) {
+ f.fmtSbx("", b, digits)
+}
+
+// fmtQ formats a string as a double-quoted, escaped Go string constant.
+// If f.sharp is set a raw (backquoted) string may be returned instead
+// if the string does not contain any control characters other than tab.
+func (f *formatter) fmtQ(s string) {
+ s = f.truncateString(s)
+ if f.sharp && strconv.CanBackquote(s) {
+ f.padString("`" + s + "`")
+ return
+ }
+ buf := f.intbuf[:0]
+ if f.plus {
+ f.pad(strconv.AppendQuoteToASCII(buf, s))
+ } else {
+ f.pad(strconv.AppendQuote(buf, s))
+ }
+}
+
+// fmtC formats an integer as a Unicode character.
+// If the character is not valid Unicode, it will print '\ufffd'.
+func (f *formatter) fmtC(c uint64) {
+ r := rune(c)
+ if c > utf8.MaxRune {
+ r = utf8.RuneError
+ }
+ buf := f.intbuf[:0]
+ w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
+ f.pad(buf[:w])
+}
+
+// fmtQc formats an integer as a single-quoted, escaped Go character constant.
+// If the character is not valid Unicode, it will print '\ufffd'.
+func (f *formatter) fmtQc(c uint64) {
+ r := rune(c)
+ if c > utf8.MaxRune {
+ r = utf8.RuneError
+ }
+ buf := f.intbuf[:0]
+ if f.plus {
+ f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
+ } else {
+ f.pad(strconv.AppendQuoteRune(buf, r))
+ }
+}
+
+// fmtFloat formats a float64. It assumes that verb is a valid format specifier
+// for strconv.AppendFloat and therefore fits into a byte.
+func (f *formatter) fmtFloat(v float64, size int, verb rune, prec int) {
+ // Explicit precision in format specifier overrules default precision.
+ if f.precPresent {
+ prec = f.prec
+ }
+ // Format number, reserving space for leading + sign if needed.
+ num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size)
+ if num[1] == '-' || num[1] == '+' {
+ num = num[1:]
+ } else {
+ num[0] = '+'
+ }
+ // f.space means to add a leading space instead of a "+" sign unless
+ // the sign is explicitly asked for by f.plus.
+ if f.space && num[0] == '+' && !f.plus {
+ num[0] = ' '
+ }
+ // Special handling for infinities and NaN,
+ // which don't look like a number so shouldn't be padded with zeros.
+ if num[1] == 'I' || num[1] == 'N' {
+ oldZero := f.zero
+ f.zero = false
+ // Remove sign before NaN if not asked for.
+ if num[1] == 'N' && !f.space && !f.plus {
+ num = num[1:]
+ }
+ f.pad(num)
+ f.zero = oldZero
+ return
+ }
+ // The sharp flag forces printing a decimal point for non-binary formats
+ // and retains trailing zeros, which we may need to restore.
+ if f.sharp && verb != 'b' {
+ digits := 0
+ switch verb {
+ case 'v', 'g', 'G', 'x':
+ digits = prec
+ // If no precision is set explicitly use a precision of 6.
+ if digits == -1 {
+ digits = 6
+ }
+ }
+
+ // Buffer pre-allocated with enough room for
+ // exponent notations of the form "e+123" or "p-1023".
+ var tailBuf [6]byte
+ tail := tailBuf[:0]
+
+ hasDecimalPoint := false
+ // Starting from i = 1 to skip sign at num[0].
+ for i := 1; i < len(num); i++ {
+ switch num[i] {
+ case '.':
+ hasDecimalPoint = true
+ case 'p', 'P':
+ tail = append(tail, num[i:]...)
+ num = num[:i]
+ case 'e', 'E':
+ if verb != 'x' && verb != 'X' {
+ tail = append(tail, num[i:]...)
+ num = num[:i]
+ break
+ }
+ fallthrough
+ default:
+ digits--
+ }
+ }
+ if !hasDecimalPoint {
+ num = append(num, '.')
+ }
+ for digits > 0 {
+ num = append(num, '0')
+ digits--
+ }
+ num = append(num, tail...)
+ }
+ // We want a sign if asked for and if the sign is not positive.
+ if f.plus || num[0] != '+' {
+ // If we're zero padding to the left we want the sign before the leading zeros.
+ // Achieve this by writing the sign out and then padding the unsigned number.
+ if f.zero && f.widPresent && f.wid > len(num) {
+ f.buf.WriteSingleByte(num[0])
+ f.writePadding(f.wid - len(num))
+ f.buf.Write(num[1:])
+ return
+ }
+ f.pad(num)
+ return
+ }
+ // No sign to show and the number is positive; just print the unsigned number.
+ f.pad(num[1:])
+}
+
+// Use simple []byte instead of bytes.Buffer to avoid large dependency.
+type buffer []byte
+
+func (b *buffer) Write(p []byte) {
+ if len(*b)+len(p) > tengo.MaxStringLen {
+ panic(ErrStringLimit)
+ }
+
+ *b = append(*b, p...)
+}
+
+func (b *buffer) WriteString(s string) {
+ if len(*b)+len(s) > tengo.MaxStringLen {
+ panic(ErrStringLimit)
+ }
+
+ *b = append(*b, s...)
+}
+
+func (b *buffer) WriteSingleByte(c byte) {
+ if len(*b) >= tengo.MaxStringLen {
+ panic(ErrStringLimit)
+ }
+
+ *b = append(*b, c)
+}
+
+func (b *buffer) WriteRune(r rune) {
+ if len(*b)+utf8.RuneLen(r) > tengo.MaxStringLen {
+ panic(ErrStringLimit)
+ }
+
+ if r < utf8.RuneSelf {
+ *b = append(*b, byte(r))
+ return
+ }
+
+ b2 := *b
+ n := len(b2)
+ for n+utf8.UTFMax > cap(b2) {
+ b2 = append(b2, 0)
+ }
+ w := utf8.EncodeRune(b2[n:n+utf8.UTFMax], r)
+ *b = b2[:n+w]
+}
+
+// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
+type pp struct {
+ buf buffer
+
+ // arg holds the current item.
+ arg Object
+
+ // fmt is used to format basic items such as integers or strings.
+ fmt formatter
+
+ // reordered records whether the format string used argument reordering.
+ reordered bool
+
+ // goodArgNum records whether the most recent reordering directive was valid.
+ goodArgNum bool
+
+ // erroring is set when printing an error string to guard against calling handleMethods.
+ erroring bool
+}
+
+var ppFree = sync.Pool{
+ New: func() interface{} { return new(pp) },
+}
+
+// newPrinter allocates a new pp struct or grabs a cached one.
+func newPrinter() *pp {
+ p := ppFree.Get().(*pp)
+ p.erroring = false
+ p.fmt.init(&p.buf)
+ return p
+}
+
+// free saves used pp structs in ppFree; avoids an allocation per invocation.
+func (p *pp) free() {
+ // Proper usage of a sync.Pool requires each entry to have approximately
+ // the same memory cost. To obtain this property when the stored type
+ // contains a variably-sized buffer, we add a hard limit on the maximum buffer
+ // to place back in the pool.
+ //
+ // See https://golang.org/issue/23199
+ if cap(p.buf) > 64<<10 {
+ return
+ }
+
+ p.buf = p.buf[:0]
+ p.arg = nil
+ ppFree.Put(p)
+}
+
+func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
+
+func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
+
+func (p *pp) Flag(b int) bool {
+ switch b {
+ case '-':
+ return p.fmt.minus
+ case '+':
+ return p.fmt.plus || p.fmt.plusV
+ case '#':
+ return p.fmt.sharp || p.fmt.sharpV
+ case ' ':
+ return p.fmt.space
+ case '0':
+ return p.fmt.zero
+ }
+ return false
+}
+
+// Implement Write so we can call Fprintf on a pp (through State), for
+// recursive use in custom verbs.
+func (p *pp) Write(b []byte) (ret int, err error) {
+ p.buf.Write(b)
+ return len(b), nil
+}
+
+// Implement WriteString so that we can call io.WriteString
+// on a pp (through state), for efficiency.
+func (p *pp) WriteString(s string) (ret int, err error) {
+ p.buf.WriteString(s)
+ return len(s), nil
+}
+
+func (p *pp) WriteRune(r rune) (ret int, err error) {
+ p.buf.WriteRune(r)
+ return utf8.RuneLen(r), nil
+}
+
+func (p *pp) WriteSingleByte(c byte) (ret int, err error) {
+ p.buf.WriteSingleByte(c)
+ return 1, nil
+}
+
+// tooLarge reports whether the magnitude of the integer is
+// too large to be used as a formatting width or precision.
+func tooLarge(x int) bool {
+ const max int = 1e6
+ return x > max || x < -max
+}
+
+// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
+func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
+ if start >= end {
+ return 0, false, end
+ }
+ for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
+ if tooLarge(num) {
+ return 0, false, end // Overflow; crazy long number most likely.
+ }
+ num = num*10 + int(s[newi]-'0')
+ isnum = true
+ }
+ return
+}
+
+func (p *pp) badVerb(verb rune) {
+ p.erroring = true
+ _, _ = p.WriteString(percentBangString)
+ _, _ = p.WriteRune(verb)
+ _, _ = p.WriteSingleByte('(')
+ switch {
+ case p.arg != nil:
+ _, _ = p.WriteString(p.arg.String())
+ _, _ = p.WriteSingleByte('=')
+ p.printArg(p.arg, 'v')
+ default:
+ _, _ = p.WriteString(UndefinedValue.String())
+ }
+ _, _ = p.WriteSingleByte(')')
+ p.erroring = false
+}
+
+func (p *pp) fmtBool(v bool, verb rune) {
+ switch verb {
+ case 't', 'v':
+ p.fmt.fmtBoolean(v)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
+// not, as requested, by temporarily setting the sharp flag.
+func (p *pp) fmt0x64(v uint64, leading0x bool) {
+ sharp := p.fmt.sharp
+ p.fmt.sharp = leading0x
+ p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
+ p.fmt.sharp = sharp
+}
+
+// fmtInteger formats a signed or unsigned integer.
+func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) {
+ switch verb {
+ case 'v':
+ if p.fmt.sharpV && !isSigned {
+ p.fmt0x64(v, true)
+ } else {
+ p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
+ }
+ case 'd':
+ p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
+ case 'b':
+ p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
+ case 'o', 'O':
+ p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
+ case 'x':
+ p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
+ case 'X':
+ p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
+ case 'c':
+ p.fmt.fmtC(v)
+ case 'q':
+ if v <= utf8.MaxRune {
+ p.fmt.fmtQc(v)
+ } else {
+ p.badVerb(verb)
+ }
+ case 'U':
+ p.fmt.fmtUnicode(v)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+// fmtFloat formats a float. The default precision for each verb
+// is specified as last argument in the call to fmt_float.
+func (p *pp) fmtFloat(v float64, size int, verb rune) {
+ switch verb {
+ case 'v':
+ p.fmt.fmtFloat(v, size, 'g', -1)
+ case 'b', 'g', 'G', 'x', 'X':
+ p.fmt.fmtFloat(v, size, verb, -1)
+ case 'f', 'e', 'E':
+ p.fmt.fmtFloat(v, size, verb, 6)
+ case 'F':
+ p.fmt.fmtFloat(v, size, 'f', 6)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+func (p *pp) fmtString(v string, verb rune) {
+ switch verb {
+ case 'v':
+ if p.fmt.sharpV {
+ p.fmt.fmtQ(v)
+ } else {
+ p.fmt.fmtS(v)
+ }
+ case 's':
+ p.fmt.fmtS(v)
+ case 'x':
+ p.fmt.fmtSx(v, ldigits)
+ case 'X':
+ p.fmt.fmtSx(v, udigits)
+ case 'q':
+ p.fmt.fmtQ(v)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+func (p *pp) fmtBytes(v []byte, verb rune, typeString string) {
+ switch verb {
+ case 'v', 'd':
+ if p.fmt.sharpV {
+ _, _ = p.WriteString(typeString)
+ if v == nil {
+ _, _ = p.WriteString(nilParenString)
+ return
+ }
+ _, _ = p.WriteSingleByte('{')
+ for i, c := range v {
+ if i > 0 {
+ _, _ = p.WriteString(commaSpaceString)
+ }
+ p.fmt0x64(uint64(c), true)
+ }
+ _, _ = p.WriteSingleByte('}')
+ } else {
+ _, _ = p.WriteSingleByte('[')
+ for i, c := range v {
+ if i > 0 {
+ _, _ = p.WriteSingleByte(' ')
+ }
+ p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
+ }
+ _, _ = p.WriteSingleByte(']')
+ }
+ case 's':
+ p.fmt.fmtBs(v)
+ case 'x':
+ p.fmt.fmtBx(v, ldigits)
+ case 'X':
+ p.fmt.fmtBx(v, udigits)
+ case 'q':
+ p.fmt.fmtQ(string(v))
+ }
+}
+
+func (p *pp) printArg(arg Object, verb rune) {
+ p.arg = arg
+
+ if arg == nil {
+ arg = UndefinedValue
+ }
+
+ // Special processing considerations.
+ // %T (the value's type) and %p (its address) are special; we always do them first.
+ switch verb {
+ case 'T':
+ p.fmt.fmtS(arg.TypeName())
+ return
+ case 'v':
+ p.fmt.fmtS(arg.String())
+ return
+ }
+
+ // Some types can be done without reflection.
+ switch f := arg.(type) {
+ case *Bool:
+ p.fmtBool(!f.IsFalsy(), verb)
+ case *Float:
+ p.fmtFloat(f.Value, 64, verb)
+ case *Int:
+ p.fmtInteger(uint64(f.Value), signed, verb)
+ case *String:
+ p.fmtString(f.Value, verb)
+ case *Bytes:
+ p.fmtBytes(f.Value, verb, "[]byte")
+ default:
+ p.fmtString(f.String(), verb)
+ }
+}
+
+// intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
+func intFromArg(a []Object, argNum int) (num int, isInt bool, newArgNum int) {
+ newArgNum = argNum
+ if argNum < len(a) {
+ var num64 int64
+ num64, isInt = ToInt64(a[argNum])
+ num = int(num64)
+ newArgNum = argNum + 1
+ if tooLarge(num) {
+ num = 0
+ isInt = false
+ }
+ }
+ return
+}
+
+// parseArgNumber returns the value of the bracketed number, minus 1
+// (explicit argument numbers are one-indexed but we want zero-indexed).
+// The opening bracket is known to be present at format[0].
+// The returned values are the index, the number of bytes to consume
+// up to the closing paren, if present, and whether the number parsed
+// ok. The bytes to consume will be 1 if no closing paren is present.
+func parseArgNumber(format string) (index int, wid int, ok bool) {
+ // There must be at least 3 bytes: [n].
+ if len(format) < 3 {
+ return 0, 1, false
+ }
+
+ // Find closing bracket.
+ for i := 1; i < len(format); i++ {
+ if format[i] == ']' {
+ width, ok, newi := parsenum(format, 1, i)
+ if !ok || newi != i {
+ return 0, i + 1, false
+ }
+ return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
+ }
+ }
+ return 0, 1, false
+}
+
+// argNumber returns the next argument to evaluate, which is either the value of the passed-in
+// argNum or the value of the bracketed integer that begins format[i:]. It also returns
+// the new value of i, that is, the index of the next byte of the format to process.
+func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
+ if len(format) <= i || format[i] != '[' {
+ return argNum, i, false
+ }
+ p.reordered = true
+ index, wid, ok := parseArgNumber(format[i:])
+ if ok && 0 <= index && index < numArgs {
+ return index, i + wid, true
+ }
+ p.goodArgNum = false
+ return argNum, i + wid, ok
+}
+
+func (p *pp) badArgNum(verb rune) {
+ _, _ = p.WriteString(percentBangString)
+ _, _ = p.WriteRune(verb)
+ _, _ = p.WriteString(badIndexString)
+}
+
+func (p *pp) missingArg(verb rune) {
+ _, _ = p.WriteString(percentBangString)
+ _, _ = p.WriteRune(verb)
+ _, _ = p.WriteString(missingString)
+}
+
+func (p *pp) doFormat(format string, a []Object) (err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ if e, ok := r.(error); ok && e == ErrStringLimit {
+ err = e
+ return
+ }
+ panic(r)
+ }
+ }()
+
+ end := len(format)
+ argNum := 0 // we process one argument per non-trivial format
+ afterIndex := false // previous item in format was an index like [3].
+ p.reordered = false
+formatLoop:
+ for i := 0; i < end; {
+ p.goodArgNum = true
+ lasti := i
+ for i < end && format[i] != '%' {
+ i++
+ }
+ if i > lasti {
+ _, _ = p.WriteString(format[lasti:i])
+ }
+ if i >= end {
+ // done processing format string
+ break
+ }
+
+ // Process one verb
+ i++
+
+ // Do we have flags?
+ p.fmt.clearflags()
+ simpleFormat:
+ for ; i < end; i++ {
+ c := format[i]
+ switch c {
+ case '#':
+ p.fmt.sharp = true
+ case '0':
+ p.fmt.zero = !p.fmt.minus // Only allow zero padding to the left.
+ case '+':
+ p.fmt.plus = true
+ case '-':
+ p.fmt.minus = true
+ p.fmt.zero = false // Do not pad with zeros to the right.
+ case ' ':
+ p.fmt.space = true
+ default:
+ // Fast path for common case of ascii lower case simple verbs
+ // without precision or width or argument indices.
+ if 'a' <= c && c <= 'z' && argNum < len(a) {
+ if c == 'v' {
+ // Go syntax
+ p.fmt.sharpV = p.fmt.sharp
+ p.fmt.sharp = false
+ // Struct-field syntax
+ p.fmt.plusV = p.fmt.plus
+ p.fmt.plus = false
+ }
+ p.printArg(a[argNum], rune(c))
+ argNum++
+ i++
+ continue formatLoop
+ }
+ // Format is more complex than simple flags and a verb or is malformed.
+ break simpleFormat
+ }
+ }
+
+ // Do we have an explicit argument index?
+ argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+
+ // Do we have width?
+ if i < end && format[i] == '*' {
+ i++
+ p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
+
+ if !p.fmt.widPresent {
+ _, _ = p.WriteString(badWidthString)
+ }
+
+ // We have a negative width, so take its value and ensure
+ // that the minus flag is set
+ if p.fmt.wid < 0 {
+ p.fmt.wid = -p.fmt.wid
+ p.fmt.minus = true
+ p.fmt.zero = false // Do not pad with zeros to the right.
+ }
+ afterIndex = false
+ } else {
+ p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
+ if afterIndex && p.fmt.widPresent { // "%[3]2d"
+ p.goodArgNum = false
+ }
+ }
+
+ // Do we have precision?
+ if i+1 < end && format[i] == '.' {
+ i++
+ if afterIndex { // "%[3].2d"
+ p.goodArgNum = false
+ }
+ argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+ if i < end && format[i] == '*' {
+ i++
+ p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
+ // Negative precision arguments don't make sense
+ if p.fmt.prec < 0 {
+ p.fmt.prec = 0
+ p.fmt.precPresent = false
+ }
+ if !p.fmt.precPresent {
+ _, _ = p.WriteString(badPrecString)
+ }
+ afterIndex = false
+ } else {
+ p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
+ if !p.fmt.precPresent {
+ p.fmt.prec = 0
+ p.fmt.precPresent = true
+ }
+ }
+ }
+
+ if !afterIndex {
+ argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+ }
+
+ if i >= end {
+ _, _ = p.WriteString(noVerbString)
+ break
+ }
+
+ verb, size := rune(format[i]), 1
+ if verb >= utf8.RuneSelf {
+ verb, size = utf8.DecodeRuneInString(format[i:])
+ }
+ i += size
+
+ switch {
+ case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
+ _, _ = p.WriteSingleByte('%')
+ case !p.goodArgNum:
+ p.badArgNum(verb)
+ case argNum >= len(a): // No argument left over to print for the current verb.
+ p.missingArg(verb)
+ case verb == 'v':
+ // Go syntax
+ p.fmt.sharpV = p.fmt.sharp
+ p.fmt.sharp = false
+ // Struct-field syntax
+ p.fmt.plusV = p.fmt.plus
+ p.fmt.plus = false
+ fallthrough
+ default:
+ p.printArg(a[argNum], verb)
+ argNum++
+ }
+ }
+
+ // Check for extra arguments unless the call accessed the arguments
+ // out of order, in which case it's too expensive to detect if they've all
+ // been used and arguably OK if they're not.
+ if !p.reordered && argNum < len(a) {
+ p.fmt.clearflags()
+ _, _ = p.WriteString(extraString)
+ for i, arg := range a[argNum:] {
+ if i > 0 {
+ _, _ = p.WriteString(commaSpaceString)
+ }
+ if arg == nil {
+ _, _ = p.WriteString(UndefinedValue.String())
+ } else {
+ _, _ = p.WriteString(arg.TypeName())
+ _, _ = p.WriteSingleByte('=')
+ p.printArg(arg, 'v')
+ }
+ }
+ _, _ = p.WriteSingleByte(')')
+ }
+
+ return nil
+}
+
+// Format formats according to a format specifier and returns the resulting string.
+func Format(format string, a ...Object) (string, error) {
+ p := newPrinter()
+ err := p.doFormat(format, a)
+ s := string(p.buf)
+ p.free()
+
+ return s, err
+}
diff --git a/vendor/github.com/d5/tengo/objects/map.go b/vendor/github.com/d5/tengo/objects/map.go
index c42ffe93..9208872c 100644
--- a/vendor/github.com/d5/tengo/objects/map.go
+++ b/vendor/github.com/d5/tengo/objects/map.go
@@ -76,13 +76,13 @@ func (o *Map) Equals(x Object) bool {
// IndexGet returns the value for the given key.
func (o *Map) IndexGet(index Object) (res Object, err error) {
- strIdx, ok := index.(*String)
+ strIdx, ok := ToString(index)
if !ok {
err = ErrInvalidIndexType
return
}
- val, ok := o.Value[strIdx.Value]
+ val, ok := o.Value[strIdx]
if !ok {
val = UndefinedValue
}
diff --git a/vendor/github.com/d5/tengo/objects/undefined.go b/vendor/github.com/d5/tengo/objects/undefined.go
index 79a380f5..0fdbc084 100644
--- a/vendor/github.com/d5/tengo/objects/undefined.go
+++ b/vendor/github.com/d5/tengo/objects/undefined.go
@@ -40,3 +40,23 @@ func (o *Undefined) Equals(x Object) bool {
func (o *Undefined) IndexGet(index Object) (Object, error) {
return UndefinedValue, nil
}
+
+// Iterate creates a map iterator.
+func (o *Undefined) Iterate() Iterator {
+ return o
+}
+
+// Next returns true if there are more elements to iterate.
+func (o *Undefined) Next() bool {
+ return false
+}
+
+// Key returns the key or index value of the current element.
+func (o *Undefined) Key() Object {
+ return o
+}
+
+// Value returns the value of the current element.
+func (o *Undefined) Value() Object {
+ return o
+}
diff --git a/vendor/github.com/d5/tengo/runtime/vm.go b/vendor/github.com/d5/tengo/runtime/vm.go
index dde52db5..07f6e530 100644
--- a/vendor/github.com/d5/tengo/runtime/vm.go
+++ b/vendor/github.com/d5/tengo/runtime/vm.go
@@ -642,9 +642,31 @@ func (v *VM) run() {
switch callee := value.(type) {
case *objects.Closure:
+ if callee.Fn.VarArgs {
+ // if the closure is variadic,
+ // roll up all variadic parameters into an array
+ realArgs := callee.Fn.NumParameters - 1
+ varArgs := numArgs - realArgs
+ if varArgs >= 0 {
+ numArgs = realArgs + 1
+ args := make([]objects.Object, varArgs)
+ spStart := v.sp - varArgs
+ for i := spStart; i < v.sp; i++ {
+ args[i-spStart] = v.stack[i]
+ }
+ v.stack[spStart] = &objects.Array{Value: args}
+ v.sp = spStart + 1
+ }
+ }
+
if numArgs != callee.Fn.NumParameters {
- v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
- callee.Fn.NumParameters, numArgs)
+ if callee.Fn.VarArgs {
+ v.err = fmt.Errorf("wrong number of arguments: want>=%d, got=%d",
+ callee.Fn.NumParameters-1, numArgs)
+ } else {
+ v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
+ callee.Fn.NumParameters, numArgs)
+ }
return
}
@@ -674,9 +696,31 @@ func (v *VM) run() {
v.sp = v.sp - numArgs + callee.Fn.NumLocals
case *objects.CompiledFunction:
+ if callee.VarArgs {
+ // if the closure is variadic,
+ // roll up all variadic parameters into an array
+ realArgs := callee.NumParameters - 1
+ varArgs := numArgs - realArgs
+ if varArgs >= 0 {
+ numArgs = realArgs + 1
+ args := make([]objects.Object, varArgs)
+ spStart := v.sp - varArgs
+ for i := spStart; i < v.sp; i++ {
+ args[i-spStart] = v.stack[i]
+ }
+ v.stack[spStart] = &objects.Array{Value: args}
+ v.sp = spStart + 1
+ }
+ }
+
if numArgs != callee.NumParameters {
- v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
- callee.NumParameters, numArgs)
+ if callee.VarArgs {
+ v.err = fmt.Errorf("wrong number of arguments: want>=%d, got=%d",
+ callee.NumParameters-1, numArgs)
+ } else {
+ v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
+ callee.NumParameters, numArgs)
+ }
return
}
@@ -707,9 +751,7 @@ func (v *VM) run() {
case objects.Callable:
var args []objects.Object
- for _, arg := range v.stack[v.sp-numArgs : v.sp] {
- args = append(args, arg)
- }
+ args = append(args, v.stack[v.sp-numArgs:v.sp]...)
ret, e := callee.Call(args...)
v.sp -= numArgs + 1
@@ -817,9 +859,12 @@ func (v *VM) run() {
val := v.stack[v.sp-numSelectors-1]
v.sp -= numSelectors + 1
- sp := v.curFrame.basePointer + localIndex
+ dst := v.stack[v.curFrame.basePointer+localIndex]
+ if obj, ok := dst.(*objects.ObjectPtr); ok {
+ dst = *obj.Value
+ }
- if e := indexAssign(v.stack[sp], val, selectors); e != nil {
+ if e := indexAssign(dst, val, selectors); e != nil {
v.err = e
return
}
diff --git a/vendor/github.com/d5/tengo/script/script.go b/vendor/github.com/d5/tengo/script/script.go
index cdf36713..2ee67b61 100644
--- a/vendor/github.com/d5/tengo/script/script.go
+++ b/vendor/github.com/d5/tengo/script/script.go
@@ -183,12 +183,3 @@ func (s *Script) prepCompile() (symbolTable *compiler.SymbolTable, globals []obj
return
}
-
-func (s *Script) copyVariables() map[string]*Variable {
- vars := make(map[string]*Variable)
- for n, v := range s.variables {
- vars[n] = v
- }
-
- return vars
-}
diff --git a/vendor/github.com/d5/tengo/stdlib/fmt.go b/vendor/github.com/d5/tengo/stdlib/fmt.go
index 9c75fc33..b8f64278 100644
--- a/vendor/github.com/d5/tengo/stdlib/fmt.go
+++ b/vendor/github.com/d5/tengo/stdlib/fmt.go
@@ -44,12 +44,12 @@ func fmtPrintf(args ...objects.Object) (ret objects.Object, err error) {
return nil, nil
}
- formatArgs := make([]interface{}, numArgs-1, numArgs-1)
- for idx, arg := range args[1:] {
- formatArgs[idx] = objects.ToInterface(arg)
+ s, err := objects.Format(format.Value, args[1:]...)
+ if err != nil {
+ return nil, err
}
- fmt.Printf(format.Value, formatArgs...)
+ fmt.Print(s)
return nil, nil
}
@@ -84,15 +84,9 @@ func fmtSprintf(args ...objects.Object) (ret objects.Object, err error) {
return format, nil // okay to return 'format' directly as String is immutable
}
- formatArgs := make([]interface{}, numArgs-1, numArgs-1)
- for idx, arg := range args[1:] {
- formatArgs[idx] = objects.ToInterface(arg)
- }
-
- s := fmt.Sprintf(format.Value, formatArgs...)
-
- if len(s) > tengo.MaxStringLen {
- return nil, objects.ErrStringLimit
+ s, err := objects.Format(format.Value, args[1:]...)
+ if err != nil {
+ return nil, err
}
return &objects.String{Value: s}, nil
diff --git a/vendor/github.com/d5/tengo/stdlib/text.go b/vendor/github.com/d5/tengo/stdlib/text.go
index 9f9770b8..4b5729ec 100644
--- a/vendor/github.com/d5/tengo/stdlib/text.go
+++ b/vendor/github.com/d5/tengo/stdlib/text.go
@@ -32,6 +32,7 @@ var textModule = map[string]objects.Object{
"last_index_any": &objects.UserFunction{Name: "last_index_any", Value: FuncASSRI(strings.LastIndexAny)}, // last_index_any(s, chars) => int
"repeat": &objects.UserFunction{Name: "repeat", Value: textRepeat}, // repeat(s, count) => string
"replace": &objects.UserFunction{Name: "replace", Value: textReplace}, // replace(s, old, new, n) => string
+ "substr": &objects.UserFunction{Name: "substr", Value: textSubstring}, // substr(s, lower, upper) => string
"split": &objects.UserFunction{Name: "split", Value: FuncASSRSs(strings.Split)}, // split(s, sep) => [string]
"split_after": &objects.UserFunction{Name: "split_after", Value: FuncASSRSs(strings.SplitAfter)}, // split_after(s, sep) => [string]
"split_after_n": &objects.UserFunction{Name: "split_after_n", Value: FuncASSIRSs(strings.SplitAfterN)}, // split_after_n(s, sep, n) => [string]
@@ -40,6 +41,9 @@ var textModule = map[string]objects.Object{
"to_lower": &objects.UserFunction{Name: "to_lower", Value: FuncASRS(strings.ToLower)}, // to_lower(s) => string
"to_title": &objects.UserFunction{Name: "to_title", Value: FuncASRS(strings.ToTitle)}, // to_title(s) => string
"to_upper": &objects.UserFunction{Name: "to_upper", Value: FuncASRS(strings.ToUpper)}, // to_upper(s) => string
+ "pad_left": &objects.UserFunction{Name: "pad_left", Value: textPadLeft}, // pad_left(s, pad_len, pad_with) => string
+ "pad_right": &objects.UserFunction{Name: "pad_right", Value: textPadRight}, // pad_right(s, pad_len, pad_with) => string
+ "trim": &objects.UserFunction{Name: "trim", Value: FuncASSRS(strings.Trim)}, // trim(s, cutset) => string
"trim_left": &objects.UserFunction{Name: "trim_left", Value: FuncASSRS(strings.TrimLeft)}, // trim_left(s, cutset) => string
"trim_prefix": &objects.UserFunction{Name: "trim_prefix", Value: FuncASSRS(strings.TrimPrefix)}, // trim_prefix(s, prefix) => string
"trim_right": &objects.UserFunction{Name: "trim_right", Value: FuncASSRS(strings.TrimRight)}, // trim_right(s, cutset) => string
@@ -376,6 +380,195 @@ func textReplace(args ...objects.Object) (ret objects.Object, err error) {
return
}
+func textSubstring(args ...objects.Object) (ret objects.Object, err error) {
+ argslen := len(args)
+ if argslen != 2 && argslen != 3 {
+ err = objects.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := objects.ToString(args[0])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := objects.ToInt(args[1])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ strlen := len(s1)
+ i3 := strlen
+ if argslen == 3 {
+ i3, ok = objects.ToInt(args[2])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ if i2 > i3 {
+ err = objects.ErrInvalidIndexType
+ return
+ }
+
+ if i2 < 0 {
+ i2 = 0
+ } else if i2 > strlen {
+ i2 = strlen
+ }
+
+ if i3 < 0 {
+ i3 = 0
+ } else if i3 > strlen {
+ i3 = strlen
+ }
+
+ ret = &objects.String{Value: s1[i2:i3]}
+
+ return
+}
+
+func textPadLeft(args ...objects.Object) (ret objects.Object, err error) {
+ argslen := len(args)
+ if argslen != 2 && argslen != 3 {
+ err = objects.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := objects.ToString(args[0])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := objects.ToInt(args[1])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ if i2 > tengo.MaxStringLen {
+ return nil, objects.ErrStringLimit
+ }
+
+ sLen := len(s1)
+ if sLen >= i2 {
+ ret = &objects.String{Value: s1}
+ return
+ }
+
+ s3 := " "
+ if argslen == 3 {
+ s3, ok = objects.ToString(args[2])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ padStrLen := len(s3)
+ if padStrLen == 0 {
+ ret = &objects.String{Value: s1}
+ return
+ }
+
+ padCount := ((i2 - padStrLen) / padStrLen) + 1
+ retStr := strings.Repeat(s3, int(padCount)) + s1
+ ret = &objects.String{Value: retStr[len(retStr)-i2:]}
+
+ return
+}
+
+func textPadRight(args ...objects.Object) (ret objects.Object, err error) {
+ argslen := len(args)
+ if argslen != 2 && argslen != 3 {
+ err = objects.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := objects.ToString(args[0])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := objects.ToInt(args[1])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ if i2 > tengo.MaxStringLen {
+ return nil, objects.ErrStringLimit
+ }
+
+ sLen := len(s1)
+ if sLen >= i2 {
+ ret = &objects.String{Value: s1}
+ return
+ }
+
+ s3 := " "
+ if argslen == 3 {
+ s3, ok = objects.ToString(args[2])
+ if !ok {
+ err = objects.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ padStrLen := len(s3)
+ if padStrLen == 0 {
+ ret = &objects.String{Value: s1}
+ return
+ }
+
+ padCount := ((i2 - padStrLen) / padStrLen) + 1
+ retStr := s1 + strings.Repeat(s3, int(padCount))
+ ret = &objects.String{Value: retStr[:i2]}
+
+ return
+}
+
func textRepeat(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 2 {
return nil, objects.ErrWrongNumArguments
diff --git a/vendor/github.com/gorilla/schema/README.md b/vendor/github.com/gorilla/schema/README.md
index 2c3ecd8e..aefdd669 100644
--- a/vendor/github.com/gorilla/schema/README.md
+++ b/vendor/github.com/gorilla/schema/README.md
@@ -11,7 +11,7 @@ Package gorilla/schema converts structs to and from form values.
Here's a quick example: we parse POST form values and then decode them into a struct:
```go
-// Set a Decoder instance as a package global, because it caches
+// Set a Decoder instance as a package global, because it caches
// meta-data about structs, and an instance can be shared safely.
var decoder = schema.NewDecoder()
@@ -27,9 +27,9 @@ func MyHandler(w http.ResponseWriter, r *http.Request) {
}
var person Person
-
+
// r.PostForm is a map of our POST form values
- err := decoder.Decode(&person, r.PostForm)
+ err = decoder.Decode(&person, r.PostForm)
if err != nil {
// Handle error
}
@@ -64,9 +64,9 @@ To define custom names for fields, use a struct tag "schema". To not populate ce
```go
type Person struct {
- Name string `schema:"name"` // custom name
- Phone string `schema:"phone"` // custom name
- Admin bool `schema:"-"` // this field is never set
+ Name string `schema:"name,required"` // custom name, must be supplied
+ Phone string `schema:"phone"` // custom name
+ Admin bool `schema:"-"` // this field is never set
}
```
@@ -83,8 +83,8 @@ The supported field types in the struct are:
Unsupported types are simply ignored, however custom types can be registered to be converted.
-More examples are available on the Gorilla website: http://www.gorillatoolkit.org/pkg/schema
+More examples are available on the Gorilla website: https://www.gorillatoolkit.org/pkg/schema
-## License
+## License
BSD licensed. See the LICENSE file for details.
diff --git a/vendor/github.com/gorilla/schema/cache.go b/vendor/github.com/gorilla/schema/cache.go
index 73b75f48..0746c120 100644
--- a/vendor/github.com/gorilla/schema/cache.go
+++ b/vendor/github.com/gorilla/schema/cache.go
@@ -117,7 +117,7 @@ func (c *cache) get(t reflect.Type) *structInfo {
info := c.m[t]
c.l.RUnlock()
if info == nil {
- info = c.create(t, nil)
+ info = c.create(t, "")
c.l.Lock()
c.m[t] = info
c.l.Unlock()
@@ -126,37 +126,40 @@ func (c *cache) get(t reflect.Type) *structInfo {
}
// create creates a structInfo with meta-data about a struct.
-func (c *cache) create(t reflect.Type, info *structInfo) *structInfo {
- if info == nil {
- info = &structInfo{fields: []*fieldInfo{}}
- }
+func (c *cache) create(t reflect.Type, parentAlias string) *structInfo {
+ info := &structInfo{}
+ var anonymousInfos []*structInfo
for i := 0; i < t.NumField(); i++ {
- field := t.Field(i)
- if field.Anonymous {
- ft := field.Type
- if ft.Kind() == reflect.Ptr {
- ft = ft.Elem()
+ if f := c.createField(t.Field(i), parentAlias); f != nil {
+ info.fields = append(info.fields, f)
+ if ft := indirectType(f.typ); ft.Kind() == reflect.Struct && f.isAnonymous {
+ anonymousInfos = append(anonymousInfos, c.create(ft, f.canonicalAlias))
}
- if ft.Kind() == reflect.Struct {
- bef := len(info.fields)
- c.create(ft, info)
- for _, fi := range info.fields[bef:len(info.fields)] {
- // exclude required check because duplicated to embedded field
- fi.isRequired = false
- }
+ }
+ }
+ for i, a := range anonymousInfos {
+ others := []*structInfo{info}
+ others = append(others, anonymousInfos[:i]...)
+ others = append(others, anonymousInfos[i+1:]...)
+ for _, f := range a.fields {
+ if !containsAlias(others, f.alias) {
+ info.fields = append(info.fields, f)
}
}
- c.createField(field, info)
}
return info
}
// createField creates a fieldInfo for the given field.
-func (c *cache) createField(field reflect.StructField, info *structInfo) {
+func (c *cache) createField(field reflect.StructField, parentAlias string) *fieldInfo {
alias, options := fieldAlias(field, c.tag)
if alias == "-" {
// Ignore this field.
- return
+ return nil
+ }
+ canonicalAlias := alias
+ if parentAlias != "" {
+ canonicalAlias = parentAlias + "." + alias
}
// Check if the type is supported and don't cache it if not.
// First let's get the basic type.
@@ -181,19 +184,20 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) {
if isStruct = ft.Kind() == reflect.Struct; !isStruct {
if c.converter(ft) == nil && builtinConverters[ft.Kind()] == nil {
// Type is not supported.
- return
+ return nil
}
}
- info.fields = append(info.fields, &fieldInfo{
+ return &fieldInfo{
typ: field.Type,
name: field.Name,
alias: alias,
+ canonicalAlias: canonicalAlias,
unmarshalerInfo: m,
isSliceOfStructs: isSlice && isStruct,
isAnonymous: field.Anonymous,
isRequired: options.Contains("required"),
- })
+ }
}
// converter returns the converter for a type.
@@ -216,11 +220,26 @@ func (i *structInfo) get(alias string) *fieldInfo {
return nil
}
+func containsAlias(infos []*structInfo, alias string) bool {
+ for _, info := range infos {
+ if info.get(alias) != nil {
+ return true
+ }
+ }
+ return false
+}
+
type fieldInfo struct {
typ reflect.Type
// name is the field name in the struct.
name string
alias string
+ // canonicalAlias is almost the same as the alias, but is prefixed with
+ // an embedded struct field alias in dotted notation if this field is
+ // promoted from the struct.
+ // For instance, if the alias is "N" and this field is an embedded field
+ // in a struct "X", canonicalAlias will be "X.N".
+ canonicalAlias string
// unmarshalerInfo contains information regarding the
// encoding.TextUnmarshaler implementation of the field type.
unmarshalerInfo unmarshaler
@@ -231,6 +250,13 @@ type fieldInfo struct {
isRequired bool
}
+func (f *fieldInfo) paths(prefix string) []string {
+ if f.alias == f.canonicalAlias {
+ return []string{prefix + f.alias}
+ }
+ return []string{prefix + f.alias, prefix + f.canonicalAlias}
+}
+
type pathPart struct {
field *fieldInfo
path []string // path to the field: walks structs using field names.
@@ -239,6 +265,13 @@ type pathPart struct {
// ----------------------------------------------------------------------------
+func indirectType(typ reflect.Type) reflect.Type {
+ if typ.Kind() == reflect.Ptr {
+ return typ.Elem()
+ }
+ return typ
+}
+
// fieldAlias parses a field tag to get a field alias.
func fieldAlias(field reflect.StructField, tagName string) (alias string, options tagOptions) {
if tag := field.Tag.Get(tagName); tag != "" {
diff --git a/vendor/github.com/gorilla/schema/decoder.go b/vendor/github.com/gorilla/schema/decoder.go
index 5352a908..5afbd921 100644
--- a/vendor/github.com/gorilla/schema/decoder.go
+++ b/vendor/github.com/gorilla/schema/decoder.go
@@ -81,52 +81,83 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string) error {
errors[path] = err
}
} else if !d.ignoreUnknownKeys {
- errors[path] = fmt.Errorf("schema: invalid path %q", path)
+ errors[path] = UnknownKeyError{Key: path}
}
}
+ errors.merge(d.checkRequired(t, src))
if len(errors) > 0 {
return errors
}
- return d.checkRequired(t, src, "")
+ return nil
}
// checkRequired checks whether required fields are empty
//
-// check type t recursively if t has struct fields, and prefix is same as parsePath: in dotted notation
+// check type t recursively if t has struct fields.
//
// src is the source map for decoding, we use it here to see if those required fields are included in src
-func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix string) error {
+func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string) MultiError {
+ m, errs := d.findRequiredFields(t, "", "")
+ for key, fields := range m {
+ if isEmptyFields(fields, src) {
+ errs[key] = EmptyFieldError{Key: key}
+ }
+ }
+ return errs
+}
+
+// findRequiredFields recursively searches the struct type t for required fields.
+//
+// canonicalPrefix and searchPrefix are used to resolve full paths in dotted notation
+// for nested struct fields. canonicalPrefix is a complete path which never omits
+// any embedded struct fields. searchPrefix is a user-friendly path which may omit
+// some embedded struct fields to point promoted fields.
+func (d *Decoder) findRequiredFields(t reflect.Type, canonicalPrefix, searchPrefix string) (map[string][]fieldWithPrefix, MultiError) {
struc := d.cache.get(t)
if struc == nil {
// unexpect, cache.get never return nil
- return errors.New("cache fail")
+ return nil, MultiError{canonicalPrefix + "*": errors.New("cache fail")}
}
+ m := map[string][]fieldWithPrefix{}
+ errs := MultiError{}
for _, f := range struc.fields {
if f.typ.Kind() == reflect.Struct {
- err := d.checkRequired(f.typ, src, prefix+f.alias+".")
- if err != nil {
- if !f.isAnonymous {
- return err
- }
- // check embedded parent field.
- err2 := d.checkRequired(f.typ, src, prefix)
- if err2 != nil {
- return err
+ fcprefix := canonicalPrefix + f.canonicalAlias + "."
+ for _, fspath := range f.paths(searchPrefix) {
+ fm, ferrs := d.findRequiredFields(f.typ, fcprefix, fspath+".")
+ for key, fields := range fm {
+ m[key] = append(m[key], fields...)
}
+ errs.merge(ferrs)
}
}
if f.isRequired {
- key := f.alias
- if prefix != "" {
- key = prefix + key
- }
- if isEmpty(f.typ, src[key]) {
- return fmt.Errorf("%v is empty", key)
+ key := canonicalPrefix + f.canonicalAlias
+ m[key] = append(m[key], fieldWithPrefix{
+ fieldInfo: f,
+ prefix: searchPrefix,
+ })
+ }
+ }
+ return m, errs
+}
+
+type fieldWithPrefix struct {
+ *fieldInfo
+ prefix string
+}
+
+// isEmptyFields returns true if all of specified fields are empty.
+func isEmptyFields(fields []fieldWithPrefix, src map[string][]string) bool {
+ for _, f := range fields {
+ for _, path := range f.paths(f.prefix) {
+ if !isEmpty(f.typ, src[path]) {
+ return false
}
}
}
- return nil
+ return true
}
// isEmpty returns true if value is empty for specific type
@@ -424,6 +455,24 @@ func (e ConversionError) Error() string {
return output
}
+// UnknownKeyError stores information about an unknown key in the source map.
+type UnknownKeyError struct {
+ Key string // key from the source map.
+}
+
+func (e UnknownKeyError) Error() string {
+ return fmt.Sprintf("schema: invalid path %q", e.Key)
+}
+
+// EmptyFieldError stores information about an empty required field.
+type EmptyFieldError struct {
+ Key string // required key in the source map.
+}
+
+func (e EmptyFieldError) Error() string {
+ return fmt.Sprintf("%v is empty", e.Key)
+}
+
// MultiError stores multiple decoding errors.
//
// Borrowed from the App Engine SDK.
@@ -445,3 +494,11 @@ func (e MultiError) Error() string {
}
return fmt.Sprintf("%s (and %d other errors)", s, len(e)-1)
}
+
+func (e MultiError) merge(errors MultiError) {
+ for key, err := range errors {
+ if e[key] == nil {
+ e[key] = err
+ }
+ }
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go
index c8d9b0a2..1cbe04b7 100644
--- a/vendor/github.com/hashicorp/golang-lru/lru.go
+++ b/vendor/github.com/hashicorp/golang-lru/lru.go
@@ -40,31 +40,35 @@ func (c *Cache) Purge() {
// Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) {
c.lock.Lock()
- defer c.lock.Unlock()
- return c.lru.Add(key, value)
+ evicted = c.lru.Add(key, value)
+ c.lock.Unlock()
+ return evicted
}
// Get looks up a key's value from the cache.
func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
c.lock.Lock()
- defer c.lock.Unlock()
- return c.lru.Get(key)
+ value, ok = c.lru.Get(key)
+ c.lock.Unlock()
+ return value, ok
}
// Contains checks if a key is in the cache, without updating the
// recent-ness or deleting it for being stale.
func (c *Cache) Contains(key interface{}) bool {
c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Contains(key)
+ containKey := c.lru.Contains(key)
+ c.lock.RUnlock()
+ return containKey
}
// Peek returns the key value (or undefined if not found) without updating
// the "recently used"-ness of the key.
func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Peek(key)
+ value, ok = c.lru.Peek(key)
+ c.lock.RUnlock()
+ return value, ok
}
// ContainsOrAdd checks if a key is in the cache without updating the
@@ -98,13 +102,15 @@ func (c *Cache) RemoveOldest() {
// Keys returns a slice of the keys in the cache, from oldest to newest.
func (c *Cache) Keys() []interface{} {
c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Keys()
+ keys := c.lru.Keys()
+ c.lock.RUnlock()
+ return keys
}
// Len returns the number of items in the cache.
func (c *Cache) Len() int {
c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Len()
+ length := c.lru.Len()
+ c.lock.RUnlock()
+ return length
}
diff --git a/vendor/github.com/labstack/echo/v4/.travis.yml b/vendor/github.com/labstack/echo/v4/.travis.yml
index 30346d7f..3897356d 100644
--- a/vendor/github.com/labstack/echo/v4/.travis.yml
+++ b/vendor/github.com/labstack/echo/v4/.travis.yml
@@ -1,6 +1,7 @@
language: go
go:
- 1.11.x
+ - 1.12.x
- tip
env:
- GO111MODULE=on
diff --git a/vendor/github.com/labstack/echo/v4/README.md b/vendor/github.com/labstack/echo/v4/README.md
index 1db5e356..0da03122 100644
--- a/vendor/github.com/labstack/echo/v4/README.md
+++ b/vendor/github.com/labstack/echo/v4/README.md
@@ -56,30 +56,29 @@ Lower is better!
package main
import (
- "net/http"
-
- "github.com/labstack/echo/v4"
- "github.com/labstack/echo/v4/middleware"
+ "net/http"
+ "github.com/labstack/echo/v4"
+ "github.com/labstack/echo/v4/middleware"
)
func main() {
- // Echo instance
- e := echo.New()
+ // Echo instance
+ e := echo.New()
- // Middleware
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
+ // Middleware
+ e.Use(middleware.Logger())
+ e.Use(middleware.Recover())
- // Routes
- e.GET("/", hello)
+ // Routes
+ e.GET("/", hello)
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
+ // Start server
+ e.Logger.Fatal(e.Start(":1323"))
}
// Handler
func hello(c echo.Context) error {
- return c.String(http.StatusOK, "Hello, World!")
+ return c.String(http.StatusOK, "Hello, World!")
}
```
diff --git a/vendor/github.com/labstack/echo/v4/bind.go b/vendor/github.com/labstack/echo/v4/bind.go
index cb65ed2d..07d8034c 100644
--- a/vendor/github.com/labstack/echo/v4/bind.go
+++ b/vendor/github.com/labstack/echo/v4/bind.go
@@ -1,6 +1,7 @@
package echo
import (
+ "encoding"
"encoding/json"
"encoding/xml"
"errors"
@@ -21,6 +22,8 @@ type (
DefaultBinder struct{}
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
+ // Types that don't implement this, but do implement encoding.TextUnmarshaler
+ // will use that interface instead.
BindUnmarshaler interface {
// UnmarshalParam decodes and assigns a value from an form or query param.
UnmarshalParam(param string) error
@@ -211,12 +214,30 @@ func bindUnmarshaler(field reflect.Value) (BindUnmarshaler, bool) {
return nil, false
}
+// textUnmarshaler attempts to unmarshal a reflect.Value into a TextUnmarshaler
+func textUnmarshaler(field reflect.Value) (encoding.TextUnmarshaler, bool) {
+ ptr := reflect.New(field.Type())
+ if ptr.CanInterface() {
+ iface := ptr.Interface()
+ if unmarshaler, ok := iface.(encoding.TextUnmarshaler); ok {
+ return unmarshaler, ok
+ }
+ }
+ return nil, false
+}
+
func unmarshalFieldNonPtr(value string, field reflect.Value) (bool, error) {
if unmarshaler, ok := bindUnmarshaler(field); ok {
err := unmarshaler.UnmarshalParam(value)
field.Set(reflect.ValueOf(unmarshaler).Elem())
return true, err
}
+ if unmarshaler, ok := textUnmarshaler(field); ok {
+ err := unmarshaler.UnmarshalText([]byte(value))
+ field.Set(reflect.ValueOf(unmarshaler).Elem())
+ return true, err
+ }
+
return false, nil
}
diff --git a/vendor/github.com/labstack/echo/v4/context.go b/vendor/github.com/labstack/echo/v4/context.go
index d4722700..065f5815 100644
--- a/vendor/github.com/labstack/echo/v4/context.go
+++ b/vendor/github.com/labstack/echo/v4/context.go
@@ -13,6 +13,7 @@ import (
"os"
"path/filepath"
"strings"
+ "sync"
)
type (
@@ -198,6 +199,7 @@ type (
handler HandlerFunc
store Map
echo *Echo
+ lock sync.RWMutex
}
)
@@ -232,7 +234,7 @@ func (c *context) IsTLS() bool {
func (c *context) IsWebSocket() bool {
upgrade := c.request.Header.Get(HeaderUpgrade)
- return upgrade == "websocket" || upgrade == "Websocket"
+ return strings.ToLower(upgrade) == "websocket"
}
func (c *context) Scheme() string {
@@ -360,10 +362,15 @@ func (c *context) Cookies() []*http.Cookie {
}
func (c *context) Get(key string) interface{} {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
return c.store[key]
}
func (c *context) Set(key string, val interface{}) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
if c.store == nil {
c.store = make(Map)
}
@@ -430,7 +437,7 @@ func (c *context) json(code int, i interface{}, indent string) error {
enc.SetIndent("", indent)
}
c.writeContentType(MIMEApplicationJSONCharsetUTF8)
- c.response.WriteHeader(code)
+ c.response.Status = code
return enc.Encode(i)
}
@@ -597,4 +604,3 @@ func (c *context) Reset(r *http.Request, w http.ResponseWriter) {
// NOTE: Don't reset because it has to have length c.echo.maxParam at all times
// c.pvalues = nil
}
-
diff --git a/vendor/github.com/labstack/echo/v4/echo.go b/vendor/github.com/labstack/echo/v4/echo.go
index 0fe6880f..56b2cf8c 100644
--- a/vendor/github.com/labstack/echo/v4/echo.go
+++ b/vendor/github.com/labstack/echo/v4/echo.go
@@ -43,6 +43,7 @@ import (
"errors"
"fmt"
"io"
+ "io/ioutil"
stdLog "log"
"net"
"net/http"
@@ -56,18 +57,21 @@ import (
"github.com/labstack/gommon/color"
"github.com/labstack/gommon/log"
+ "golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
)
type (
// Echo is the top-level framework instance.
Echo struct {
+ common
StdLogger *stdLog.Logger
colorer *color.Color
premiddleware []MiddlewareFunc
middleware []MiddlewareFunc
maxParam *int
router *Router
+ routers map[string]*Router
notFoundHandler HandlerFunc
pool sync.Pool
Server *http.Server
@@ -122,10 +126,8 @@ type (
// Map defines a generic map of type `map[string]interface{}`.
Map map[string]interface{}
- // i is the interface for Echo and Group.
- i interface {
- GET(string, HandlerFunc, ...MiddlewareFunc) *Route
- }
+ // Common struct for Echo & Group.
+ common struct{}
)
// HTTP methods
@@ -168,6 +170,8 @@ const (
charsetUTF8 = "charset=UTF-8"
// PROPFIND Method can be used on collection and property resources.
PROPFIND = "PROPFIND"
+ // REPORT Method can be used to get information about a resource, see rfc 3253
+ REPORT = "REPORT"
)
// Headers
@@ -211,17 +215,18 @@ const (
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
// Security
- HeaderStrictTransportSecurity = "Strict-Transport-Security"
- HeaderXContentTypeOptions = "X-Content-Type-Options"
- HeaderXXSSProtection = "X-XSS-Protection"
- HeaderXFrameOptions = "X-Frame-Options"
- HeaderContentSecurityPolicy = "Content-Security-Policy"
- HeaderXCSRFToken = "X-CSRF-Token"
+ HeaderStrictTransportSecurity = "Strict-Transport-Security"
+ HeaderXContentTypeOptions = "X-Content-Type-Options"
+ HeaderXXSSProtection = "X-XSS-Protection"
+ HeaderXFrameOptions = "X-Frame-Options"
+ HeaderContentSecurityPolicy = "Content-Security-Policy"
+ HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
+ HeaderXCSRFToken = "X-CSRF-Token"
)
const (
// Version of Echo
- Version = "4.0.0"
+ Version = "4.1.5"
website = "https://echo.labstack.com"
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
banner = `
@@ -248,6 +253,7 @@ var (
PROPFIND,
http.MethodPut,
http.MethodTrace,
+ REPORT,
}
)
@@ -269,6 +275,7 @@ var (
ErrRendererNotRegistered = errors.New("renderer not registered")
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
ErrCookieNotFound = errors.New("cookie not found")
+ ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte")
)
// Error handlers
@@ -304,6 +311,7 @@ func New() (e *Echo) {
return e.NewContext(nil, nil)
}
e.router = NewRouter(e)
+ e.routers = map[string]*Router{}
return
}
@@ -319,11 +327,16 @@ func (e *Echo) NewContext(r *http.Request, w http.ResponseWriter) Context {
}
}
-// Router returns router.
+// Router returns the default router.
func (e *Echo) Router() *Router {
return e.router
}
+// Routers returns the map of host => router.
+func (e *Echo) Routers() map[string]*Router {
+ return e.routers
+}
+
// DefaultHTTPErrorHandler is the default HTTP error handler. It sends a JSON response
// with status code.
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
@@ -450,10 +463,10 @@ func (e *Echo) Static(prefix, root string) *Route {
if root == "" {
root = "." // For security we want to restrict to CWD.
}
- return static(e, prefix, root)
+ return e.static(prefix, root, e.GET)
}
-func static(i i, prefix, root string) *Route {
+func (common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route {
h := func(c Context) error {
p, err := url.PathUnescape(c.Param("*"))
if err != nil {
@@ -462,26 +475,28 @@ func static(i i, prefix, root string) *Route {
name := filepath.Join(root, path.Clean("/"+p)) // "/"+ for security
return c.File(name)
}
- i.GET(prefix, h)
if prefix == "/" {
- return i.GET(prefix+"*", h)
+ return get(prefix+"*", h)
}
+ return get(prefix+"/*", h)
+}
- return i.GET(prefix+"/*", h)
+func (common) file(path, file string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route,
+ m ...MiddlewareFunc) *Route {
+ return get(path, func(c Context) error {
+ return c.File(file)
+ }, m...)
}
// File registers a new route with path to serve a static file with optional route-level middleware.
func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
- return e.GET(path, func(c Context) error {
- return c.File(file)
- }, m...)
+ return e.file(path, file, e.GET, m...)
}
-// Add registers a new route for an HTTP method and path with matching handler
-// in the router with optional route-level middleware.
-func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
+func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
name := handlerName(handler)
- e.router.Add(method, path, func(c Context) error {
+ router := e.findRouter(host)
+ router.Add(method, path, func(c Context) error {
h := handler
// Chain middleware
for i := len(middleware) - 1; i >= 0; i-- {
@@ -498,6 +513,20 @@ func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...Middl
return r
}
+// Add registers a new route for an HTTP method and path with matching handler
+// in the router with optional route-level middleware.
+func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
+ return e.add("", method, path, handler, middleware...)
+}
+
+// Host creates a new router group for the provided host and optional host-level middleware.
+func (e *Echo) Host(name string, m ...MiddlewareFunc) (g *Group) {
+ e.routers[name] = NewRouter(e)
+ g = &Group{host: name, echo: e}
+ g.Use(m...)
+ return
+}
+
// Group creates a new router group with prefix and optional group-level middleware.
func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
g = &Group{prefix: prefix, echo: e}
@@ -570,23 +599,17 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h := NotFoundHandler
if e.premiddleware == nil {
- e.router.Find(r.Method, getPath(r), c)
+ e.findRouter(r.Host).Find(r.Method, getPath(r), c)
h = c.Handler()
- for i := len(e.middleware) - 1; i >= 0; i-- {
- h = e.middleware[i](h)
- }
+ h = applyMiddleware(h, e.middleware...)
} else {
h = func(c Context) error {
- e.router.Find(r.Method, getPath(r), c)
+ e.findRouter(r.Host).Find(r.Method, getPath(r), c)
h := c.Handler()
- for i := len(e.middleware) - 1; i >= 0; i-- {
- h = e.middleware[i](h)
- }
+ h = applyMiddleware(h, e.middleware...)
return h(c)
}
- for i := len(e.premiddleware) - 1; i >= 0; i-- {
- h = e.premiddleware[i](h)
- }
+ h = applyMiddleware(h, e.premiddleware...)
}
// Execute chain
@@ -605,25 +628,46 @@ func (e *Echo) Start(address string) error {
}
// StartTLS starts an HTTPS server.
-func (e *Echo) StartTLS(address string, certFile, keyFile string) (err error) {
- if certFile == "" || keyFile == "" {
- return errors.New("invalid tls configuration")
+// If `certFile` or `keyFile` is `string` the values are treated as file paths.
+// If `certFile` or `keyFile` is `[]byte` the values are treated as the certificate or key as-is.
+func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err error) {
+ var cert []byte
+ if cert, err = filepathOrContent(certFile); err != nil {
+ return
+ }
+
+ var key []byte
+ if key, err = filepathOrContent(keyFile); err != nil {
+ return
}
+
s := e.TLSServer
s.TLSConfig = new(tls.Config)
s.TLSConfig.Certificates = make([]tls.Certificate, 1)
- s.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
+ if s.TLSConfig.Certificates[0], err = tls.X509KeyPair(cert, key); err != nil {
return
}
+
return e.startTLS(address)
}
+func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
+ switch v := fileOrContent.(type) {
+ case string:
+ return ioutil.ReadFile(v)
+ case []byte:
+ return v, nil
+ default:
+ return nil, ErrInvalidCertOrKeyType
+ }
+}
+
// StartAutoTLS starts an HTTPS server using certificates automatically installed from https://letsencrypt.org.
func (e *Echo) StartAutoTLS(address string) error {
s := e.TLSServer
s.TLSConfig = new(tls.Config)
s.TLSConfig.GetCertificate = e.AutoTLSManager.GetCertificate
+ s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, acme.ALPNProto)
return e.startTLS(address)
}
@@ -742,6 +786,15 @@ func getPath(r *http.Request) string {
return path
}
+func (e *Echo) findRouter(host string) *Router {
+ if len(e.routers) > 0 {
+ if r, ok := e.routers[host]; ok {
+ return r
+ }
+ }
+ return e.router
+}
+
func handlerName(h HandlerFunc) string {
t := reflect.ValueOf(h).Type()
if t.Kind() == reflect.Func {
@@ -764,13 +817,14 @@ type tcpKeepAliveListener struct {
}
func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
- tc, err := ln.AcceptTCP()
- if err != nil {
+ if c, err = ln.AcceptTCP(); err != nil {
+ return
+ } else if err = c.(*net.TCPConn).SetKeepAlive(true); err != nil {
+ return
+ } else if err = c.(*net.TCPConn).SetKeepAlivePeriod(3 * time.Minute); err != nil {
return
}
- tc.SetKeepAlive(true)
- tc.SetKeepAlivePeriod(3 * time.Minute)
- return tc, nil
+ return
}
func newListener(address string) (*tcpKeepAliveListener, error) {
@@ -780,3 +834,10 @@ func newListener(address string) (*tcpKeepAliveListener, error) {
}
return &tcpKeepAliveListener{l.(*net.TCPListener)}, nil
}
+
+func applyMiddleware(h HandlerFunc, middleware ...MiddlewareFunc) HandlerFunc {
+ for i := len(middleware) - 1; i >= 0; i-- {
+ h = middleware[i](h)
+ }
+ return h
+}
diff --git a/vendor/github.com/labstack/echo/v4/go.mod b/vendor/github.com/labstack/echo/v4/go.mod
index 2853cba5..d76b9843 100644
--- a/vendor/github.com/labstack/echo/v4/go.mod
+++ b/vendor/github.com/labstack/echo/v4/go.mod
@@ -1,13 +1,15 @@
module github.com/labstack/echo/v4
+go 1.12
+
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
- github.com/labstack/gommon v0.2.8
- github.com/mattn/go-colorable v0.0.9 // indirect
- github.com/mattn/go-isatty v0.0.4 // indirect
+ github.com/labstack/gommon v0.2.9
github.com/stretchr/testify v1.3.0
- github.com/valyala/bytebufferpool v1.0.0 // indirect
- github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
- golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664
- golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc // indirect
+ github.com/valyala/fasttemplate v1.0.1
+ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
+ golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect
+ golang.org/x/sys v0.0.0-20190609082536-301114b31cce // indirect
+ golang.org/x/text v0.3.2 // indirect
+ golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 // indirect
)
diff --git a/vendor/github.com/labstack/echo/v4/go.sum b/vendor/github.com/labstack/echo/v4/go.sum
index e6981931..48c5b8f1 100644
--- a/vendor/github.com/labstack/echo/v4/go.sum
+++ b/vendor/github.com/labstack/echo/v4/go.sum
@@ -1,23 +1,53 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
-github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
+github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
+github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 h1:gKMu1Bf6QINDnvyZuTaACm9ofY+PRh+5vFz4oxBZeF8=
-github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw=
-golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664 h1:YbZJ76lQ1BqNhVe7dKTSB67wDrc2VPRR75IyGyyPDX8=
-golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc h1:WiYx1rIFmx8c0mXAFtv5D/mHyKe1+jmuP7PViuwqwuQ=
-golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
+golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
diff --git a/vendor/github.com/labstack/echo/v4/group.go b/vendor/github.com/labstack/echo/v4/group.go
index 3e3732b6..5d958253 100644
--- a/vendor/github.com/labstack/echo/v4/group.go
+++ b/vendor/github.com/labstack/echo/v4/group.go
@@ -2,7 +2,6 @@ package echo
import (
"net/http"
- "path"
)
type (
@@ -10,6 +9,8 @@ type (
// routes that share a common middleware or functionality that should be separate
// from the parent echo instance while still inheriting from it.
Group struct {
+ common
+ host string
prefix string
middleware []MiddlewareFunc
echo *Echo
@@ -19,13 +20,13 @@ type (
// Use implements `Echo#Use()` for sub-routes within the Group.
func (g *Group) Use(middleware ...MiddlewareFunc) {
g.middleware = append(g.middleware, middleware...)
+ if len(g.middleware) == 0 {
+ return
+ }
// Allow all requests to reach the group as they might get dropped if router
// doesn't find a match, making none of the group middleware process.
- for _, p := range []string{"", "/*"} {
- g.echo.Any(path.Clean(g.prefix+p), func(c Context) error {
- return NotFoundHandler(c)
- }, g.middleware...)
- }
+ g.Any("", NotFoundHandler)
+ g.Any("/*", NotFoundHandler)
}
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
@@ -92,21 +93,23 @@ func (g *Group) Match(methods []string, path string, handler HandlerFunc, middle
}
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
-func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) *Group {
+func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) (sg *Group) {
m := make([]MiddlewareFunc, 0, len(g.middleware)+len(middleware))
m = append(m, g.middleware...)
m = append(m, middleware...)
- return g.echo.Group(g.prefix+prefix, m...)
+ sg = g.echo.Group(g.prefix+prefix, m...)
+ sg.host = g.host
+ return
}
// Static implements `Echo#Static()` for sub-routes within the Group.
func (g *Group) Static(prefix, root string) {
- static(g, prefix, root)
+ g.static(prefix, root, g.GET)
}
// File implements `Echo#File()` for sub-routes within the Group.
func (g *Group) File(path, file string) {
- g.echo.File(g.prefix+path, file)
+ g.file(g.prefix+path, file, g.GET)
}
// Add implements `Echo#Add()` for sub-routes within the Group.
@@ -117,5 +120,5 @@ func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...Midd
m := make([]MiddlewareFunc, 0, len(g.middleware)+len(middleware))
m = append(m, g.middleware...)
m = append(m, middleware...)
- return g.echo.Add(method, g.prefix+path, handler, m...)
+ return g.echo.add(g.host, method, g.prefix+path, handler, m...)
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/compress.go b/vendor/github.com/labstack/echo/v4/middleware/compress.go
index 19052064..89da16ef 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/compress.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/compress.go
@@ -111,6 +111,9 @@ func (w *gzipResponseWriter) Write(b []byte) (int, error) {
func (w *gzipResponseWriter) Flush() {
w.Writer.(*gzip.Writer).Flush()
+ if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
+ flusher.Flush()
+ }
}
func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/cors.go b/vendor/github.com/labstack/echo/v4/middleware/cors.go
index c61c7125..5dfe31f9 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/cors.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/cors.go
@@ -102,6 +102,10 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
allowOrigin = o
break
}
+ if matchSubdomain(origin, o) {
+ allowOrigin = origin
+ break
+ }
}
// Simple request
diff --git a/vendor/github.com/labstack/echo/v4/middleware/jwt.go b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
index 861d3142..d4420246 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/jwt.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/jwt.go
@@ -26,10 +26,14 @@ type (
// It may be used to define a custom JWT error.
ErrorHandler JWTErrorHandler
- // Signing key to validate token.
- // Required.
+ // Signing key to validate token. Used as fallback if SigningKeys has length 0.
+ // Required. This or SigningKeys.
SigningKey interface{}
+ // Map of signing keys to validate token with kid field usage.
+ // Required. This or SigningKey.
+ SigningKeys map[string]interface{}
+
// Signing method, used to check token signing method.
// Optional. Default value HS256.
SigningMethod string
@@ -48,6 +52,7 @@ type (
// Possible values:
// - "header:<name>"
// - "query:<name>"
+ // - "param:<name>"
// - "cookie:<name>"
TokenLookup string
@@ -110,7 +115,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.Skipper == nil {
config.Skipper = DefaultJWTConfig.Skipper
}
- if config.SigningKey == nil {
+ if config.SigningKey == nil && len(config.SigningKeys) == 0 {
panic("echo: jwt middleware requires signing key")
}
if config.SigningMethod == "" {
@@ -133,6 +138,15 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if t.Method.Alg() != config.SigningMethod {
return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"])
}
+ if len(config.SigningKeys) > 0 {
+ if kid, ok := t.Header["kid"].(string); ok {
+ if key, ok := config.SigningKeys[kid]; ok {
+ return key, nil
+ }
+ }
+ return nil, fmt.Errorf("unexpected jwt key id=%v", t.Header["kid"])
+ }
+
return config.SigningKey, nil
}
@@ -142,6 +156,8 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
switch parts[0] {
case "query":
extractor = jwtFromQuery(parts[1])
+ case "param":
+ extractor = jwtFromParam(parts[1])
case "cookie":
extractor = jwtFromCookie(parts[1])
}
@@ -215,6 +231,17 @@ func jwtFromQuery(param string) jwtExtractor {
}
}
+// jwtFromParam returns a `jwtExtractor` that extracts token from the url param string.
+func jwtFromParam(param string) jwtExtractor {
+ return func(c echo.Context) (string, error) {
+ token := c.Param(param)
+ if token == "" {
+ return "", ErrJWTMissing
+ }
+ return token, nil
+ }
+}
+
// jwtFromCookie returns a `jwtExtractor` that extracts token from the named cookie.
func jwtFromCookie(name string) jwtExtractor {
return func(c echo.Context) (string, error) {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/key_auth.go b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go
index fe01e23e..94cfd142 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/key_auth.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go
@@ -99,11 +99,14 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc {
}
valid, err := config.Validator(key, c)
if err != nil {
- return err
+ return &echo.HTTPError{
+ Code: http.StatusUnauthorized,
+ Message: "invalid key",
+ Internal: err,
+ }
} else if valid {
return next(c)
}
-
return echo.ErrUnauthorized
}
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/logger.go b/vendor/github.com/labstack/echo/v4/middleware/logger.go
index b2e48347..6fd59efb 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/logger.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/logger.go
@@ -2,6 +2,7 @@ package middleware
import (
"bytes"
+ "encoding/json"
"io"
"os"
"strconv"
@@ -20,7 +21,7 @@ type (
// Skipper defines a function to skip middleware.
Skipper Skipper
- // Tags to constructed the logger format.
+ // Tags to construct the logger format.
//
// - time_unix
// - time_unix_nano
@@ -175,7 +176,10 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
return buf.WriteString(s)
case "error":
if err != nil {
- return buf.WriteString(err.Error())
+ // Error may contain invalid JSON e.g. `"`
+ b, _ := json.Marshal(err.Error())
+ b = b[1 : len(b)-1]
+ return buf.Write(b)
}
case "latency":
l := stop.Sub(start)
diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy.go b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
index 9d67f445..532346d5 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/proxy.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/proxy.go
@@ -200,7 +200,7 @@ func Proxy(balancer ProxyBalancer) echo.MiddlewareFunc {
func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
// Defaults
if config.Skipper == nil {
- config.Skipper = DefaultLoggerConfig.Skipper
+ config.Skipper = DefaultProxyConfig.Skipper
}
if config.Balancer == nil {
panic("echo: proxy middleware requires balancer")
diff --git a/vendor/github.com/labstack/echo/v4/middleware/redirect.go b/vendor/github.com/labstack/echo/v4/middleware/redirect.go
index 30a2e403..813e5b85 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/redirect.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/redirect.go
@@ -21,7 +21,7 @@ type RedirectConfig struct {
// 2) return the appropriate redirect url.
type redirectLogic func(scheme, host, uri string) (ok bool, url string)
-const www = "www"
+const www = "www."
// DefaultRedirectConfig is the default Redirect middleware config.
var DefaultRedirectConfig = RedirectConfig{
@@ -60,7 +60,7 @@ func HTTPSWWWRedirect() echo.MiddlewareFunc {
// See `HTTPSWWWRedirect()`.
func HTTPSWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
return redirect(config, func(scheme, host, uri string) (ok bool, url string) {
- if ok = scheme != "https" && host[:3] != www; ok {
+ if ok = scheme != "https" && host[:4] != www; ok {
url = "https://www." + host + uri
}
return
@@ -80,7 +80,7 @@ func HTTPSNonWWWRedirect() echo.MiddlewareFunc {
func HTTPSNonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
return redirect(config, func(scheme, host, uri string) (ok bool, url string) {
if ok = scheme != "https"; ok {
- if host[:3] == www {
+ if host[:4] == www {
host = host[4:]
}
url = "https://" + host + uri
@@ -101,7 +101,7 @@ func WWWRedirect() echo.MiddlewareFunc {
// See `WWWRedirect()`.
func WWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
return redirect(config, func(scheme, host, uri string) (ok bool, url string) {
- if ok = host[:3] != www; ok {
+ if ok = host[:4] != www; ok {
url = scheme + "://www." + host + uri
}
return
@@ -120,7 +120,7 @@ func NonWWWRedirect() echo.MiddlewareFunc {
// See `NonWWWRedirect()`.
func NonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
return redirect(config, func(scheme, host, uri string) (ok bool, url string) {
- if ok = host[:3] == www; ok {
+ if ok = host[:4] == www; ok {
url = scheme + "://" + host[4:] + uri
}
return
diff --git a/vendor/github.com/labstack/echo/v4/middleware/secure.go b/vendor/github.com/labstack/echo/v4/middleware/secure.go
index 8839c879..77a1487f 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/secure.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/secure.go
@@ -53,6 +53,19 @@ type (
// trusted web page context.
// Optional. Default value "".
ContentSecurityPolicy string `yaml:"content_security_policy"`
+
+ // CSPReportOnly would use the `Content-Security-Policy-Report-Only` header instead
+ // of the `Content-Security-Policy` header. This allows iterative updates of the
+ // content security policy by only reporting the violations that would
+ // have occurred instead of blocking the resource.
+ // Optional. Default value false.
+ CSPReportOnly bool `yaml:"csp_report_only"`
+
+ // HSTSPreloadEnabled will add the preload tag in the `Strict Transport Security`
+ // header, which enables the domain to be included in the HSTS preload list
+ // maintained by Chrome (and used by Firefox and Safari): https://hstspreload.org/
+ // Optional. Default value false.
+ HSTSPreloadEnabled bool `yaml:"hsts_preload_enabled"`
}
)
@@ -63,6 +76,7 @@ var (
XSSProtection: "1; mode=block",
ContentTypeNosniff: "nosniff",
XFrameOptions: "SAMEORIGIN",
+ HSTSPreloadEnabled: false,
}
)
@@ -105,10 +119,17 @@ func SecureWithConfig(config SecureConfig) echo.MiddlewareFunc {
if !config.HSTSExcludeSubdomains {
subdomains = "; includeSubdomains"
}
+ if config.HSTSPreloadEnabled {
+ subdomains = fmt.Sprintf("%s; preload", subdomains)
+ }
res.Header().Set(echo.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", config.HSTSMaxAge, subdomains))
}
if config.ContentSecurityPolicy != "" {
- res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy)
+ if config.CSPReportOnly {
+ res.Header().Set(echo.HeaderContentSecurityPolicyReportOnly, config.ContentSecurityPolicy)
+ } else {
+ res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy)
+ }
}
return next(c)
}
diff --git a/vendor/github.com/labstack/echo/v4/middleware/slash.go b/vendor/github.com/labstack/echo/v4/middleware/slash.go
index 61d6e30b..0492b334 100644
--- a/vendor/github.com/labstack/echo/v4/middleware/slash.go
+++ b/vendor/github.com/labstack/echo/v4/middleware/slash.go
@@ -1,6 +1,8 @@
package middleware
import (
+ "strings"
+
"github.com/labstack/echo/v4"
)
@@ -49,7 +51,7 @@ func AddTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFunc
url := req.URL
path := url.Path
qs := c.QueryString()
- if path != "/" && path[len(path)-1] != '/' {
+ if !strings.HasSuffix(path, "/") {
path += "/"
uri := path
if qs != "" {
@@ -97,7 +99,7 @@ func RemoveTrailingSlashWithConfig(config TrailingSlashConfig) echo.MiddlewareFu
path := url.Path
qs := c.QueryString()
l := len(path) - 1
- if l >= 0 && path != "/" && path[l] == '/' {
+ if l > 0 && strings.HasSuffix(path, "/") {
path = path[:l]
uri := path
if qs != "" {
diff --git a/vendor/github.com/labstack/echo/v4/middleware/util.go b/vendor/github.com/labstack/echo/v4/middleware/util.go
new file mode 100644
index 00000000..ab951a0e
--- /dev/null
+++ b/vendor/github.com/labstack/echo/v4/middleware/util.go
@@ -0,0 +1,54 @@
+package middleware
+
+import (
+ "strings"
+)
+
+func matchScheme(domain, pattern string) bool {
+ didx := strings.Index(domain, ":")
+ pidx := strings.Index(pattern, ":")
+ return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx]
+}
+
+// matchSubdomain compares authority with wildcard
+func matchSubdomain(domain, pattern string) bool {
+ if !matchScheme(domain, pattern) {
+ return false
+ }
+ didx := strings.Index(domain, "://")
+ pidx := strings.Index(pattern, "://")
+ if didx == -1 || pidx == -1 {
+ return false
+ }
+ domAuth := domain[didx+3:]
+ // to avoid long loop by invalid long domain
+ if len(domAuth) > 253 {
+ return false
+ }
+ patAuth := pattern[pidx+3:]
+
+ domComp := strings.Split(domAuth, ".")
+ patComp := strings.Split(patAuth, ".")
+ for i := len(domComp)/2 - 1; i >= 0; i-- {
+ opp := len(domComp) - 1 - i
+ domComp[i], domComp[opp] = domComp[opp], domComp[i]
+ }
+ for i := len(patComp)/2 - 1; i >= 0; i-- {
+ opp := len(patComp) - 1 - i
+ patComp[i], patComp[opp] = patComp[opp], patComp[i]
+ }
+
+ for i, v := range domComp {
+ if len(patComp) <= i {
+ return false
+ }
+ p := patComp[i]
+ if p == "*" {
+ return true
+ }
+ if p != v {
+ return false
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/labstack/echo/v4/response.go b/vendor/github.com/labstack/echo/v4/response.go
index eb2d988d..ca7405c5 100644
--- a/vendor/github.com/labstack/echo/v4/response.go
+++ b/vendor/github.com/labstack/echo/v4/response.go
@@ -67,7 +67,10 @@ func (r *Response) WriteHeader(code int) {
// Write writes the data to the connection as part of an HTTP reply.
func (r *Response) Write(b []byte) (n int, err error) {
if !r.Committed {
- r.WriteHeader(http.StatusOK)
+ if r.Status == 0 {
+ r.Status = http.StatusOK
+ }
+ r.WriteHeader(r.Status)
}
n, err = r.Writer.Write(b)
r.Size += int64(n)
diff --git a/vendor/github.com/labstack/echo/v4/router.go b/vendor/github.com/labstack/echo/v4/router.go
index 73f0b68b..8d3a0180 100644
--- a/vendor/github.com/labstack/echo/v4/router.go
+++ b/vendor/github.com/labstack/echo/v4/router.go
@@ -33,6 +33,7 @@ type (
propfind HandlerFunc
put HandlerFunc
trace HandlerFunc
+ report HandlerFunc
}
)
@@ -57,7 +58,7 @@ func NewRouter(e *Echo) *Router {
func (r *Router) Add(method, path string, h HandlerFunc) {
// Validate path
if path == "" {
- panic("echo: path cannot be empty")
+ path = "/"
}
if path[0] != '/' {
path = "/" + path
@@ -79,14 +80,13 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
if i == l {
r.insert(method, path[:i], h, pkind, ppath, pnames)
- return
+ } else {
+ r.insert(method, path[:i], nil, pkind, "", nil)
}
- r.insert(method, path[:i], nil, pkind, "", nil)
} else if path[i] == '*' {
r.insert(method, path[:i], nil, skind, "", nil)
pnames = append(pnames, "*")
r.insert(method, path[:i+1], h, akind, ppath, pnames)
- return
}
}
@@ -248,6 +248,8 @@ func (n *node) addHandler(method string, h HandlerFunc) {
n.methodHandler.put = h
case http.MethodTrace:
n.methodHandler.trace = h
+ case REPORT:
+ n.methodHandler.report = h
}
}
@@ -273,6 +275,8 @@ func (n *node) findHandler(method string) HandlerFunc {
return n.methodHandler.put
case http.MethodTrace:
return n.methodHandler.trace
+ case REPORT:
+ return n.methodHandler.report
default:
return nil
}
diff --git a/vendor/github.com/labstack/gommon/bytes/bytes.go b/vendor/github.com/labstack/gommon/bytes/bytes.go
index 746436cb..232c8d25 100644
--- a/vendor/github.com/labstack/gommon/bytes/bytes.go
+++ b/vendor/github.com/labstack/gommon/bytes/bytes.go
@@ -22,7 +22,7 @@ const (
)
var (
- pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)([KMGTPE]B?|B?)$`)
+ pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
global = New()
)
diff --git a/vendor/github.com/labstack/gommon/log/log.go b/vendor/github.com/labstack/gommon/log/log.go
index 132411db..06fa37e0 100644
--- a/vendor/github.com/labstack/gommon/log/log.go
+++ b/vendor/github.com/labstack/gommon/log/log.go
@@ -10,6 +10,7 @@ import (
"runtime"
"strconv"
"sync"
+ "sync/atomic"
"time"
"github.com/mattn/go-isatty"
@@ -21,7 +22,7 @@ import (
type (
Logger struct {
prefix string
- level Lvl
+ level uint32
skip int
output io.Writer
template *fasttemplate.Template
@@ -58,7 +59,7 @@ func init() {
func New(prefix string) (l *Logger) {
l = &Logger{
- level: INFO,
+ level: uint32(INFO),
skip: 2,
prefix: prefix,
template: l.newTemplate(defaultHeader),
@@ -110,11 +111,11 @@ func (l *Logger) SetPrefix(p string) {
}
func (l *Logger) Level() Lvl {
- return l.level
+ return Lvl(atomic.LoadUint32(&l.level))
}
-func (l *Logger) SetLevel(v Lvl) {
- l.level = v
+func (l *Logger) SetLevel(level Lvl) {
+ atomic.StoreUint32(&l.level, uint32(level))
}
func (l *Logger) Output() io.Writer {
@@ -247,8 +248,8 @@ func Level() Lvl {
return global.Level()
}
-func SetLevel(v Lvl) {
- global.SetLevel(v)
+func SetLevel(level Lvl) {
+ global.SetLevel(level)
}
func Output() io.Writer {
@@ -347,16 +348,14 @@ func Panicj(j JSON) {
global.Panicj(j)
}
-func (l *Logger) log(v Lvl, format string, args ...interface{}) {
- l.mutex.Lock()
- defer l.mutex.Unlock()
- buf := l.bufferPool.Get().(*bytes.Buffer)
- buf.Reset()
- defer l.bufferPool.Put(buf)
- _, file, line, _ := runtime.Caller(l.skip)
-
- if v >= l.level || v == 0 {
+func (l *Logger) log(level Lvl, format string, args ...interface{}) {
+ if level >= l.Level() || level == 0 {
+ buf := l.bufferPool.Get().(*bytes.Buffer)
+ buf.Reset()
+ defer l.bufferPool.Put(buf)
+ _, file, line, _ := runtime.Caller(l.skip)
message := ""
+
if format == "" {
message = fmt.Sprint(args...)
} else if format == "json" {
@@ -376,7 +375,7 @@ func (l *Logger) log(v Lvl, format string, args ...interface{}) {
case "time_rfc3339_nano":
return w.Write([]byte(time.Now().Format(time.RFC3339Nano)))
case "level":
- return w.Write([]byte(l.levels[v]))
+ return w.Write([]byte(l.levels[level]))
case "prefix":
return w.Write([]byte(l.prefix))
case "long_file":
@@ -409,6 +408,8 @@ func (l *Logger) log(v Lvl, format string, args ...interface{}) {
buf.WriteString(message)
}
buf.WriteByte('\n')
+ l.mutex.Lock()
+ defer l.mutex.Unlock()
l.output.Write(buf.Bytes())
}
}
diff --git a/vendor/github.com/mattn/go-colorable/go.mod b/vendor/github.com/mattn/go-colorable/go.mod
index 9d9f4248..ef3ca9d4 100644
--- a/vendor/github.com/mattn/go-colorable/go.mod
+++ b/vendor/github.com/mattn/go-colorable/go.mod
@@ -1,3 +1,3 @@
module github.com/mattn/go-colorable
-require github.com/mattn/go-isatty v0.0.5
+require github.com/mattn/go-isatty v0.0.8
diff --git a/vendor/github.com/mattn/go-isatty/isatty_android.go b/vendor/github.com/mattn/go-isatty/isatty_android.go
new file mode 100644
index 00000000..d3567cb5
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_android.go
@@ -0,0 +1,23 @@
+// +build android
+
+package isatty
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const ioctlReadTermios = syscall.TCGETS
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ var termios syscall.Termios
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+ return err == 0
+}
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go
index f02849c5..ff714a37 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_others.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_others.go
@@ -1,4 +1,4 @@
-// +build appengine js
+// +build appengine js nacl
package isatty
diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
index e004038e..453b025d 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_linux.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
@@ -1,5 +1,6 @@
-// +build linux
+// +build linux aix
// +build !appengine
+// +build !android
package isatty
diff --git a/vendor/github.com/paulrosania/go-charset/charset/ascii.go b/vendor/github.com/paulrosania/go-charset/charset/ascii.go
index ccf3a35b..0e73d066 100644
--- a/vendor/github.com/paulrosania/go-charset/charset/ascii.go
+++ b/vendor/github.com/paulrosania/go-charset/charset/ascii.go
@@ -21,7 +21,7 @@ type codePointError struct {
}
func (e *codePointError) Error() string {
- return fmt.Sprintf("Parse error at index %n: Code point %n is undefined in %s", e.i, e.cp, e.charset)
+ return fmt.Sprintf("Parse error at index %d: Code point %d is undefined in %s", e.i, e.cp, e.charset)
}
func (strict translateFromASCII) Translate(data []byte, eof bool) (int, []byte, error) {
diff --git a/vendor/github.com/paulrosania/go-charset/charset/charset.go b/vendor/github.com/paulrosania/go-charset/charset/charset.go
index 6ab6cf89..ea441adf 100644
--- a/vendor/github.com/paulrosania/go-charset/charset/charset.go
+++ b/vendor/github.com/paulrosania/go-charset/charset/charset.go
@@ -6,7 +6,7 @@
//
// import _ "github.com/paulrosania/go-charset/data"
//
-// It can also made available in a data directory (by settting CharsetDir).
+// It can also made available in a data directory (by setting CharsetDir).
package charset
import (
diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml
index a8f15451..848938a6 100644
--- a/vendor/github.com/sirupsen/logrus/.travis.yml
+++ b/vendor/github.com/sirupsen/logrus/.travis.yml
@@ -1,52 +1,25 @@
language: go
go_import_path: github.com/sirupsen/logrus
+git:
+ depth: 1
env:
- - GOMAXPROCS=4 GORACE=halt_on_error=1
+ - GO111MODULE=on
+ - GO111MODULE=off
+go: [ 1.11.x, 1.12.x ]
+os: [ linux, osx ]
matrix:
- include:
- - go: 1.10.x
- install:
- - go get github.com/stretchr/testify/assert
- - go get golang.org/x/crypto/ssh/terminal
- - go get golang.org/x/sys/unix
- - go get golang.org/x/sys/windows
- script:
- - go test -race -v ./...
- - go: 1.11.x
- env: GO111MODULE=on
- install:
- - go mod download
- script:
- - go test -race -v ./...
- - go: 1.11.x
+ exclude:
+ - go: 1.12.x
env: GO111MODULE=off
- install:
- - go get github.com/stretchr/testify/assert
- - go get golang.org/x/crypto/ssh/terminal
- - go get golang.org/x/sys/unix
- - go get golang.org/x/sys/windows
- script:
- - go test -race -v ./...
- - go: 1.10.x
- install:
- - go get github.com/stretchr/testify/assert
- - go get golang.org/x/crypto/ssh/terminal
- - go get golang.org/x/sys/unix
- - go get golang.org/x/sys/windows
- script:
- - go test -race -v -tags appengine ./...
- go: 1.11.x
- env: GO111MODULE=on
- install:
- - go mod download
- script:
- - go test -race -v -tags appengine ./...
- - go: 1.11.x
- env: GO111MODULE=off
- install:
- - go get github.com/stretchr/testify/assert
- - go get golang.org/x/crypto/ssh/terminal
- - go get golang.org/x/sys/unix
- - go get golang.org/x/sys/windows
- script:
- - go test -race -v -tags appengine ./...
+ os: osx
+install:
+ - ./travis/install.sh
+ - if [[ "$GO111MODULE" == "on" ]]; then go mod download; fi
+ - if [[ "$GO111MODULE" == "off" ]]; then go get github.com/stretchr/testify/assert golang.org/x/sys/unix github.com/konsorten/go-windows-terminal-sequences; fi
+script:
+ - ./travis/cross_build.sh
+ - export GOMAXPROCS=4
+ - export GORACE=halt_on_error=1
+ - go test -race -v ./...
+ - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then go test -race -v -tags appengine ./... ; fi
diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
index cb85d9f9..51a7ab0c 100644
--- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md
+++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
@@ -1,3 +1,38 @@
+# 1.4.2
+ * Fixes build break for plan9, nacl, solaris
+# 1.4.1
+This new release introduces:
+ * Enhance TextFormatter to not print caller information when they are empty (#944)
+ * Remove dependency on golang.org/x/crypto (#932, #943)
+
+Fixes:
+ * Fix Entry.WithContext method to return a copy of the initial entry (#941)
+
+# 1.4.0
+This new release introduces:
+ * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848).
+ * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter (#909, #911)
+ * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919).
+
+Fixes:
+ * Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893).
+ * Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903)
+ * Fix infinite recursion on unknown `Level.String()` (#907)
+ * Fix race condition in `getCaller` (#916).
+
+
+# 1.3.0
+This new release introduces:
+ * Log, Logf, Logln functions for Logger and Entry that take a Level
+
+Fixes:
+ * Building prometheus node_exporter on AIX (#840)
+ * Race condition in TextFormatter (#468)
+ * Travis CI import path (#868)
+ * Remove coloured output on Windows (#862)
+ * Pointer to func as field in JSONFormatter (#870)
+ * Properly marshal Levels (#873)
+
# 1.2.0
This new release introduces:
* A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md
index 39873105..a4796eb0 100644
--- a/vendor/github.com/sirupsen/logrus/README.md
+++ b/vendor/github.com/sirupsen/logrus/README.md
@@ -365,6 +365,7 @@ Third party logging formatters:
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
+* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
You can define your formatter by implementing the `Formatter` interface,
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go
index 8af90637..8fd189e1 100644
--- a/vendor/github.com/sirupsen/logrus/alt_exit.go
+++ b/vendor/github.com/sirupsen/logrus/alt_exit.go
@@ -51,9 +51,9 @@ func Exit(code int) {
os.Exit(code)
}
-// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
-// all handlers. The handlers will also be invoked when any Fatal log entry is
-// made.
+// RegisterExitHandler appends a Logrus Exit handler to the list of handlers,
+// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
+// any Fatal log entry is made.
//
// This method is useful when a caller wishes to use logrus to log a fatal
// message but also needs to gracefully shutdown. An example usecase could be
@@ -62,3 +62,15 @@ func Exit(code int) {
func RegisterExitHandler(handler func()) {
handlers = append(handlers, handler)
}
+
+// DeferExitHandler prepends a Logrus Exit handler to the list of handlers,
+// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
+// any Fatal log entry is made.
+//
+// This method is useful when a caller wishes to use logrus to log a fatal
+// message but also needs to gracefully shutdown. An example usecase could be
+// closing database connections, or sending a alert that the application is
+// closing.
+func DeferExitHandler(handler func()) {
+ handlers = append([]func(){handler}, handlers...)
+}
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
index df6d188d..63e25583 100644
--- a/vendor/github.com/sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -2,6 +2,7 @@ package logrus
import (
"bytes"
+ "context"
"fmt"
"os"
"reflect"
@@ -69,6 +70,9 @@ type Entry struct {
// When formatter is called in entry.log(), a Buffer may be set to entry
Buffer *bytes.Buffer
+ // Contains the context set by the user. Useful for hook processing etc.
+ Context context.Context
+
// err may contain a field formatting error
err string
}
@@ -97,6 +101,11 @@ func (entry *Entry) WithError(err error) *Entry {
return entry.WithField(ErrorKey, err)
}
+// Add a context to the Entry.
+func (entry *Entry) WithContext(ctx context.Context) *Entry {
+ return &Entry{Logger: entry.Logger, Data: entry.Data, Time: entry.Time, err: entry.err, Context: ctx}
+}
+
// Add a single field to the Entry.
func (entry *Entry) WithField(key string, value interface{}) *Entry {
return entry.WithFields(Fields{key: value})
@@ -130,12 +139,12 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
data[k] = v
}
}
- return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr}
+ return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
}
// Overrides the time of the Entry.
func (entry *Entry) WithTime(t time.Time) *Entry {
- return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err}
+ return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err, Context: entry.Context}
}
// getPackageName reduces a fully qualified function name to the package name
@@ -156,20 +165,23 @@ func getPackageName(f string) string {
// getCaller retrieves the name of the first non-logrus calling function
func getCaller() *runtime.Frame {
- // Restrict the lookback frames to avoid runaway lookups
- pcs := make([]uintptr, maximumCallerDepth)
- depth := runtime.Callers(minimumCallerDepth, pcs)
- frames := runtime.CallersFrames(pcs[:depth])
// cache this package's fully-qualified name
callerInitOnce.Do(func() {
- logrusPackage = getPackageName(runtime.FuncForPC(pcs[0]).Name())
+ pcs := make([]uintptr, 2)
+ _ = runtime.Callers(0, pcs)
+ logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name())
// now that we have the cache, we can skip a minimum count of known-logrus functions
- // XXX this is dubious, the number of frames may vary store an entry in a logger interface
+ // XXX this is dubious, the number of frames may vary
minimumCallerDepth = knownLogrusFrames
})
+ // Restrict the lookback frames to avoid runaway lookups
+ pcs := make([]uintptr, maximumCallerDepth)
+ depth := runtime.Callers(minimumCallerDepth, pcs)
+ frames := runtime.CallersFrames(pcs[:depth])
+
for f, again := frames.Next(); again; f, again = frames.Next() {
pkg := getPackageName(f.Function)
@@ -298,7 +310,9 @@ func (entry *Entry) Panic(args ...interface{}) {
// Entry Printf family functions
func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
- entry.Log(level, fmt.Sprintf(format, args...))
+ if entry.Logger.IsLevelEnabled(level) {
+ entry.Log(level, fmt.Sprintf(format, args...))
+ }
}
func (entry *Entry) Tracef(format string, args ...interface{}) {
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
index 7342613c..62fc2f21 100644
--- a/vendor/github.com/sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -1,6 +1,7 @@
package logrus
import (
+ "context"
"io"
"time"
)
@@ -55,6 +56,11 @@ func WithError(err error) *Entry {
return std.WithField(ErrorKey, err)
}
+// WithContext creates an entry from the standard logger and adds a context to it.
+func WithContext(ctx context.Context) *Entry {
+ return std.WithContext(ctx)
+}
+
// WithField creates an entry from the standard logger and adds a field to
// it. If you want multiple fields, use `WithFields`.
//
diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod
index 94574cc6..12fdf989 100644
--- a/vendor/github.com/sirupsen/logrus/go.mod
+++ b/vendor/github.com/sirupsen/logrus/go.mod
@@ -6,6 +6,5 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.1.1 // indirect
github.com/stretchr/testify v1.2.2
- golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
- golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33
+ golang.org/x/sys v0.0.0-20190422165155-953cdadca894
)
diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum
index 133d34ae..596c318b 100644
--- a/vendor/github.com/sirupsen/logrus/go.sum
+++ b/vendor/github.com/sirupsen/logrus/go.sum
@@ -2,6 +2,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs=
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -9,7 +10,7 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
index 26057535..098a21a0 100644
--- a/vendor/github.com/sirupsen/logrus/json_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
+ "runtime"
)
type fieldKey string
@@ -42,6 +43,12 @@ type JSONFormatter struct {
// }
FieldMap FieldMap
+ // CallerPrettyfier can be set by the user to modify the content
+ // of the function and file keys in the json data when ReportCaller is
+ // activated. If any of the returned value is the empty string the
+ // corresponding key will be removed from json fields.
+ CallerPrettyfier func(*runtime.Frame) (function string, file string)
+
// PrettyPrint will indent all json logs
PrettyPrint bool
}
@@ -82,8 +89,17 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
if entry.HasCaller() {
- data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
- data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+ funcVal := entry.Caller.Function
+ fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+ if f.CallerPrettyfier != nil {
+ funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
+ }
+ if funcVal != "" {
+ data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
+ }
+ if fileVal != "" {
+ data[f.FieldMap.resolve(FieldKeyFile)] = fileVal
+ }
}
var b *bytes.Buffer
@@ -98,7 +114,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
encoder.SetIndent("", " ")
}
if err := encoder.Encode(data); err != nil {
- return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+ return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err)
}
return b.Bytes(), nil
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
index 9bf64e22..c0c0b1e5 100644
--- a/vendor/github.com/sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -1,6 +1,7 @@
package logrus
import (
+ "context"
"io"
"os"
"sync"
@@ -124,6 +125,13 @@ func (logger *Logger) WithError(err error) *Entry {
return entry.WithError(err)
}
+// Add a context to the log entry.
+func (logger *Logger) WithContext(ctx context.Context) *Entry {
+ entry := logger.newEntry()
+ defer logger.releaseEntry(entry)
+ return entry.WithContext(ctx)
+}
+
// Overrides the time of the log entry.
func (logger *Logger) WithTime(t time.Time) *Entry {
entry := logger.newEntry()
@@ -200,7 +208,7 @@ func (logger *Logger) Info(args ...interface{}) {
func (logger *Logger) Print(args ...interface{}) {
entry := logger.newEntry()
- entry.Info(args...)
+ entry.Print(args...)
logger.releaseEntry(entry)
}
@@ -256,7 +264,7 @@ func (logger *Logger) Warnln(args ...interface{}) {
}
func (logger *Logger) Warningln(args ...interface{}) {
- logger.Warn(args...)
+ logger.Warnln(args...)
}
func (logger *Logger) Errorln(args ...interface{}) {
diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
index c1ca8899..8644761f 100644
--- a/vendor/github.com/sirupsen/logrus/logrus.go
+++ b/vendor/github.com/sirupsen/logrus/logrus.go
@@ -74,7 +74,7 @@ func (level Level) MarshalText() ([]byte, error) {
return []byte("panic"), nil
}
- return nil, fmt.Errorf("not a valid lorus level %q", level)
+ return nil, fmt.Errorf("not a valid logrus level %d", level)
}
// A constant exposing all logging levels
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_aix.go b/vendor/github.com/sirupsen/logrus/terminal_check_aix.go
deleted file mode 100644
index 04fdb7ba..00000000
--- a/vendor/github.com/sirupsen/logrus/terminal_check_aix.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !appengine,!js,!windows,aix
-
-package logrus
-
-import "io"
-
-func checkIfTerminal(w io.Writer) bool {
- return false
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
new file mode 100644
index 00000000..3c4f43f9
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
@@ -0,0 +1,13 @@
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package logrus
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
+
+func isTerminal(fd int) bool {
+ _, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+ return err == nil
+}
+
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_js.go b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
index 0c209750..97af92c6 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_js.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
@@ -1,4 +1,4 @@
-// +build js
+// +build js nacl plan9
package logrus
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
index d4655650..3293fb3c 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
@@ -1,18 +1,16 @@
-// +build !appengine,!js,!windows,!aix
+// +build !appengine,!js,!windows,!nacl,!plan9
package logrus
import (
"io"
"os"
-
- "golang.org/x/crypto/ssh/terminal"
)
func checkIfTerminal(w io.Writer) bool {
switch v := w.(type) {
case *os.File:
- return terminal.IsTerminal(int(v.Fd()))
+ return isTerminal(int(v.Fd()))
default:
return false
}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
new file mode 100644
index 00000000..f6710b3b
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
@@ -0,0 +1,11 @@
+package logrus
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func isTerminal(fd int) bool {
+ _, err := unix.IoctlGetTermio(fd, unix.TCGETA)
+ return err == nil
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
new file mode 100644
index 00000000..355dc966
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
@@ -0,0 +1,13 @@
+// +build linux aix
+
+package logrus
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
+
+func isTerminal(fd int) bool {
+ _, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+ return err == nil
+}
+
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
index 3b9d2864..572889db 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
@@ -6,15 +6,29 @@ import (
"io"
"os"
"syscall"
+
+ sequences "github.com/konsorten/go-windows-terminal-sequences"
)
+func initTerminal(w io.Writer) {
+ switch v := w.(type) {
+ case *os.File:
+ sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
+ }
+}
+
func checkIfTerminal(w io.Writer) bool {
+ var ret bool
switch v := w.(type) {
case *os.File:
var mode uint32
err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode)
- return err == nil
+ ret = (err == nil)
default:
- return false
+ ret = false
+ }
+ if ret {
+ initTerminal(w)
}
+ return ret
}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
deleted file mode 100644
index 3dbd2372..00000000
--- a/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// +build !windows
-
-package logrus
-
-import "io"
-
-func initTerminal(w io.Writer) {
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_windows.go b/vendor/github.com/sirupsen/logrus/terminal_windows.go
deleted file mode 100644
index b4ef5286..00000000
--- a/vendor/github.com/sirupsen/logrus/terminal_windows.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// +build !appengine,!js,windows
-
-package logrus
-
-import (
- "io"
- "os"
- "syscall"
-
- sequences "github.com/konsorten/go-windows-terminal-sequences"
-)
-
-func initTerminal(w io.Writer) {
- switch v := w.(type) {
- case *os.File:
- sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
- }
-}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
index fb21649c..e01587c4 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -12,18 +12,13 @@ import (
)
const (
- nocolor = 0
- red = 31
- green = 32
- yellow = 33
- blue = 36
- gray = 37
+ red = 31
+ yellow = 33
+ blue = 36
+ gray = 37
)
-var (
- baseTimestamp time.Time
- emptyFieldMap FieldMap
-)
+var baseTimestamp time.Time
func init() {
baseTimestamp = time.Now()
@@ -77,16 +72,18 @@ type TextFormatter struct {
// FieldKeyMsg: "@message"}}
FieldMap FieldMap
+ // CallerPrettyfier can be set by the user to modify the content
+ // of the function and file keys in the data when ReportCaller is
+ // activated. If any of the returned value is the empty string the
+ // corresponding key will be removed from fields.
+ CallerPrettyfier func(*runtime.Frame) (function string, file string)
+
terminalInitOnce sync.Once
}
func (f *TextFormatter) init(entry *Entry) {
if entry.Logger != nil {
f.isTerminal = checkIfTerminal(entry.Logger.Out)
-
- if f.isTerminal {
- initTerminal(entry.Logger.Out)
- }
}
}
@@ -118,6 +115,8 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
keys = append(keys, k)
}
+ var funcVal, fileVal string
+
fixedKeys := make([]string, 0, 4+len(data))
if !f.DisableTimestamp {
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
@@ -130,8 +129,19 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
}
if entry.HasCaller() {
- fixedKeys = append(fixedKeys,
- f.FieldMap.resolve(FieldKeyFunc), f.FieldMap.resolve(FieldKeyFile))
+ if f.CallerPrettyfier != nil {
+ funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
+ } else {
+ funcVal = entry.Caller.Function
+ fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+ }
+
+ if funcVal != "" {
+ fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFunc))
+ }
+ if fileVal != "" {
+ fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFile))
+ }
}
if !f.DisableSorting {
@@ -166,6 +176,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
if f.isColored() {
f.printColored(b, entry, keys, data, timestampFormat)
} else {
+
for _, key := range fixedKeys {
var value interface{}
switch {
@@ -178,9 +189,9 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
case key == f.FieldMap.resolve(FieldKeyLogrusError):
value = entry.err
case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
- value = entry.Caller.Function
+ value = funcVal
case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
- value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+ value = fileVal
default:
value = data[key]
}
@@ -215,10 +226,21 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
entry.Message = strings.TrimSuffix(entry.Message, "\n")
caller := ""
-
if entry.HasCaller() {
- caller = fmt.Sprintf("%s:%d %s()",
- entry.Caller.File, entry.Caller.Line, entry.Caller.Function)
+ funcVal := fmt.Sprintf("%s()", entry.Caller.Function)
+ fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+
+ if f.CallerPrettyfier != nil {
+ funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
+ }
+
+ if fileVal == "" {
+ caller = funcVal
+ } else if funcVal == "" {
+ caller = fileVal
+ } else {
+ caller = fileVal + " " + funcVal
+ }
}
if f.DisableTimestamp {
diff --git a/vendor/github.com/spf13/viper/go.mod b/vendor/github.com/spf13/viper/go.mod
index 86e801c1..27943005 100644
--- a/vendor/github.com/spf13/viper/go.mod
+++ b/vendor/github.com/spf13/viper/go.mod
@@ -2,23 +2,42 @@ module github.com/spf13/viper
require (
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect
+ github.com/coreos/bbolt v1.3.2 // indirect
github.com/coreos/etcd v3.3.10+incompatible // indirect
- github.com/coreos/go-etcd v2.0.0+incompatible // indirect
github.com/coreos/go-semver v0.2.0 // indirect
+ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
+ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/fsnotify/fsnotify v1.4.7
+ github.com/gogo/protobuf v1.2.1 // indirect
+ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
+ github.com/google/btree v1.0.0 // indirect
+ github.com/gorilla/websocket v1.4.0 // indirect
+ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
+ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
+ github.com/grpc-ecosystem/grpc-gateway v1.9.0 // indirect
github.com/hashicorp/hcl v1.0.0
+ github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/magiconair/properties v1.8.0
github.com/mitchellh/mapstructure v1.1.2
github.com/pelletier/go-toml v1.2.0
+ github.com/prometheus/client_golang v0.9.3 // indirect
+ github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spf13/afero v1.1.2
github.com/spf13/cast v1.3.0
github.com/spf13/jwalterweatherman v1.0.0
github.com/spf13/pflag v1.0.3
github.com/stretchr/testify v1.2.2
- github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 // indirect
+ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
+ github.com/ugorji/go v1.1.4 // indirect
+ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77
- golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect
- golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a // indirect
- golang.org/x/text v0.3.0 // indirect
+ go.etcd.io/bbolt v1.3.2 // indirect
+ go.uber.org/atomic v1.4.0 // indirect
+ go.uber.org/multierr v1.1.0 // indirect
+ go.uber.org/zap v1.10.0 // indirect
+ golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect
+ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
+ google.golang.org/grpc v1.21.0 // indirect
gopkg.in/yaml.v2 v2.2.2
)
diff --git a/vendor/github.com/spf13/viper/go.sum b/vendor/github.com/spf13/viper/go.sum
index 22d60745..97afaffe 100644
--- a/vendor/github.com/spf13/viper/go.sum
+++ b/vendor/github.com/spf13/viper/go.sum
@@ -1,25 +1,109 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
-github.com/coreos/etcd v3.3.10+incompatible h1:KjVWqrZ5U0wa3CxY2AxlH6/UcB+PK2td1DcsYhA+HRs=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
@@ -28,24 +112,67 @@ github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.2.3-0.20181014000028-04af85275a5c h1:03OmljzZYsezlgAfa+f/cY8E8XXPiFh5bgANMhUlDI4=
-github.com/stretchr/testify v1.2.3-0.20181014000028-04af85275a5c/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.2.3-0.20181115233458-8019298d9fa5 h1:ixuBiBNIIQ3RKRSZy9B0DgaqreXG6NDHrbwAFGg8Mwk=
-github.com/stretchr/testify v1.2.3-0.20181115233458-8019298d9fa5/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/xordataexchange/crypt v0.0.2 h1:VBfFXTpEwLq2hzs42qCHOyKw5AqEm9DYGqBuINmzUZY=
-github.com/xordataexchange/crypt v0.0.2/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go
index cee37b21..a3d37f8c 100644
--- a/vendor/github.com/spf13/viper/viper.go
+++ b/vendor/github.com/spf13/viper/viper.go
@@ -180,10 +180,11 @@ type Viper struct {
remoteProviders []*defaultRemoteProvider
// Name of file to look for inside the path
- configName string
- configFile string
- configType string
- envPrefix string
+ configName string
+ configFile string
+ configType string
+ configPermissions os.FileMode
+ envPrefix string
automaticEnvApplied bool
envKeyReplacer *strings.Replacer
@@ -210,6 +211,7 @@ func New() *Viper {
v := new(Viper)
v.keyDelim = "."
v.configName = "config"
+ v.configPermissions = os.FileMode(0644)
v.fs = afero.NewOsFs()
v.config = make(map[string]interface{})
v.override = make(map[string]interface{})
@@ -687,6 +689,12 @@ func (v *Viper) Get(key string) interface{} {
return cast.ToString(val)
case int32, int16, int8, int:
return cast.ToInt(val)
+ case uint:
+ return cast.ToUint(val)
+ case uint32:
+ return cast.ToUint32(val)
+ case uint64:
+ return cast.ToUint64(val)
case int64:
return cast.ToInt64(val)
case float64, float32:
@@ -750,6 +758,24 @@ func (v *Viper) GetInt64(key string) int64 {
return cast.ToInt64(v.Get(key))
}
+// GetUint returns the value associated with the key as an unsigned integer.
+func GetUint(key string) uint { return v.GetUint(key) }
+func (v *Viper) GetUint(key string) uint {
+ return cast.ToUint(v.Get(key))
+}
+
+// GetUint32 returns the value associated with the key as an unsigned integer.
+func GetUint32(key string) uint32 { return v.GetUint32(key) }
+func (v *Viper) GetUint32(key string) uint32 {
+ return cast.ToUint32(v.Get(key))
+}
+
+// GetUint64 returns the value associated with the key as an unsigned integer.
+func GetUint64(key string) uint64 { return v.GetUint64(key) }
+func (v *Viper) GetUint64(key string) uint64 {
+ return cast.ToUint64(v.Get(key))
+}
+
// GetFloat64 returns the value associated with the key as a float64.
func GetFloat64(key string) float64 { return v.GetFloat64(key) }
func (v *Viper) GetFloat64(key string) float64 {
@@ -811,8 +837,6 @@ func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConf
return err
}
- v.insensitiviseMaps()
-
return nil
}
@@ -828,8 +852,6 @@ func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error
return err
}
- v.insensitiviseMaps()
-
return nil
}
@@ -872,8 +894,6 @@ func (v *Viper) UnmarshalExact(rawVal interface{}) error {
return err
}
- v.insensitiviseMaps()
-
return nil
}
@@ -1334,7 +1354,7 @@ func (v *Viper) writeConfig(filename string, force bool) error {
return fmt.Errorf("File: %s exists. Use WriteConfig to overwrite.", filename)
}
}
- f, err := v.fs.OpenFile(filename, flags, os.FileMode(0644))
+ f, err := v.fs.OpenFile(filename, flags, v.configPermissions)
if err != nil {
return err
}
@@ -1579,13 +1599,6 @@ func (v *Viper) WatchRemoteConfigOnChannel() error {
return v.watchKeyValueConfigOnChannel()
}
-func (v *Viper) insensitiviseMaps() {
- insensitiviseMap(v.config)
- insensitiviseMap(v.defaults)
- insensitiviseMap(v.override)
- insensitiviseMap(v.kvstore)
-}
-
// Retrieve the first found remote configuration.
func (v *Viper) getKeyValueConfig() error {
if RemoteConfig == nil {
@@ -1778,6 +1791,12 @@ func (v *Viper) SetConfigType(in string) {
}
}
+// SetConfigPermissions sets the permissions for the config file.
+func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) }
+func (v *Viper) SetConfigPermissions(perm os.FileMode) {
+ v.configPermissions = perm.Perm()
+}
+
func (v *Viper) getConfigType() string {
if v.configType != "" {
return v.configType
diff --git a/vendor/github.com/valyala/fasttemplate/go.mod b/vendor/github.com/valyala/fasttemplate/go.mod
new file mode 100644
index 00000000..6015c4b5
--- /dev/null
+++ b/vendor/github.com/valyala/fasttemplate/go.mod
@@ -0,0 +1,3 @@
+module github.com/valyala/fasttemplate
+
+require github.com/valyala/bytebufferpool v1.0.0
diff --git a/vendor/github.com/valyala/fasttemplate/go.sum b/vendor/github.com/valyala/fasttemplate/go.sum
new file mode 100644
index 00000000..c10c48c2
--- /dev/null
+++ b/vendor/github.com/valyala/fasttemplate/go.sum
@@ -0,0 +1,2 @@
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
diff --git a/vendor/github.com/zfjagann/golang-ring/ring.go b/vendor/github.com/zfjagann/golang-ring/ring.go
index 6d2a7e24..345ee8cd 100644
--- a/vendor/github.com/zfjagann/golang-ring/ring.go
+++ b/vendor/github.com/zfjagann/golang-ring/ring.go
@@ -56,7 +56,7 @@ func (r *Ring) ContentSize() int {
} else {
difference := (r.head - r.tail)
if difference < 0 {
- difference = -difference
+ difference += r.capacity()
}
return difference + 1
}