diff options
Diffstat (limited to 'vendor/github.com')
104 files changed, 1450 insertions, 935 deletions
diff --git a/vendor/github.com/dgrijalva/jwt-go/README.md b/vendor/github.com/dgrijalva/jwt-go/README.md index 70bae69e..d358d881 100644 --- a/vendor/github.com/dgrijalva/jwt-go/README.md +++ b/vendor/github.com/dgrijalva/jwt-go/README.md @@ -1,11 +1,15 @@ -A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) +# jwt-go [![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go) +[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go) + +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) -**BREAKING CHANGES:*** Version 3.0.0 is here. It includes _a lot_ of changes including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code. +**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. -**NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. +**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail. +**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. ## What the heck is a JWT? @@ -37,7 +41,7 @@ Here's an example of an extension that integrates with the Google App Engine sig ## Compliance -This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences: +This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences: * In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. @@ -47,7 +51,10 @@ This library is considered production ready. Feedback and feature requests are This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `master`. Periodically, versions will be tagged from `master`. You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases). -While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v2`. It will do the right thing WRT semantic versioning. +While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`. It will do the right thing WRT semantic versioning. + +**BREAKING CHANGES:*** +* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code. ## Usage Tips @@ -68,18 +75,26 @@ Symmetric signing methods, such as HSA, use only a single secret. This is probab Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification. +### Signing Methods and Key Types + +Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones: + +* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation +* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation +* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation + ### JWT and OAuth It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication. Without going too far down the rabbit hole, here's a description of the interaction of these technologies: -* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth. +* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth. * OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token. * Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL. - + ## More Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go). -The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in to documentation. +The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation. diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md index b605b450..63702983 100644 --- a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md +++ b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md @@ -1,5 +1,18 @@ ## `jwt-go` Version History +#### 3.2.0 + +* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation +* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate +* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. +* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. + +#### 3.1.0 + +* Improvements to `jwt` command line tool +* Added `SkipClaimsValidation` option to `Parser` +* Documentation updates + #### 3.0.0 * **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go index 2f59a222..f9773812 100644 --- a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go @@ -14,6 +14,7 @@ var ( ) // Implements the ECDSA family of signing methods signing methods +// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification type SigningMethodECDSA struct { Name string Hash crypto.Hash diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/dgrijalva/jwt-go/hmac.go index c2299192..addbe5d4 100644 --- a/vendor/github.com/dgrijalva/jwt-go/hmac.go +++ b/vendor/github.com/dgrijalva/jwt-go/hmac.go @@ -7,6 +7,7 @@ import ( ) // Implements the HMAC-SHA family of signing methods signing methods +// Expects key type of []byte for both signing and validation type SigningMethodHMAC struct { Name string Hash crypto.Hash @@ -90,5 +91,5 @@ func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, return EncodeSegment(hasher.Sum(nil)), nil } - return "", ErrInvalidKey + return "", ErrInvalidKeyType } diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go index 7bf1c4ea..d6901d9a 100644 --- a/vendor/github.com/dgrijalva/jwt-go/parser.go +++ b/vendor/github.com/dgrijalva/jwt-go/parser.go @@ -21,55 +21,9 @@ func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { } func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { - parts := strings.Split(tokenString, ".") - if len(parts) != 3 { - return nil, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) - } - - var err error - token := &Token{Raw: tokenString} - - // parse Header - var headerBytes []byte - if headerBytes, err = DecodeSegment(parts[0]); err != nil { - if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { - return token, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) - } - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - if err = json.Unmarshal(headerBytes, &token.Header); err != nil { - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - - // parse Claims - var claimBytes []byte - token.Claims = claims - - if claimBytes, err = DecodeSegment(parts[1]); err != nil { - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) - if p.UseJSONNumber { - dec.UseNumber() - } - // JSON Decode. Special case for map type to avoid weird pointer behavior - if c, ok := token.Claims.(MapClaims); ok { - err = dec.Decode(&c) - } else { - err = dec.Decode(&claims) - } - // Handle decode error + token, parts, err := p.ParseUnverified(tokenString, claims) if err != nil { - return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - - // Lookup signature method - if method, ok := token.Header["alg"].(string); ok { - if token.Method = GetSigningMethod(method); token.Method == nil { - return token, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) - } - } else { - return token, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + return token, err } // Verify signing method is in the required set @@ -96,6 +50,9 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf } if key, err = keyFunc(token); err != nil { // keyFunc returned an error + if ve, ok := err.(*ValidationError); ok { + return token, ve + } return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable} } @@ -129,3 +86,63 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf return token, vErr } + +// WARNING: Don't use this method unless you know what you're doing +// +// This method parses the token but doesn't validate the signature. It's only +// ever useful in cases where you know the signature is valid (because it has +// been checked previously in the stack) and you want to extract values from +// it. +func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { + parts = strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) + } + + token = &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = DecodeSegment(parts[0]); err != nil { + if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { + return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) + } + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // parse Claims + var claimBytes []byte + token.Claims = claims + + if claimBytes, err = DecodeSegment(parts[1]); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + if p.UseJSONNumber { + dec.UseNumber() + } + // JSON Decode. Special case for map type to avoid weird pointer behavior + if c, ok := token.Claims.(MapClaims); ok { + err = dec.Decode(&c) + } else { + err = dec.Decode(&claims) + } + // Handle decode error + if err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) + } + } else { + return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + } + + return token, parts, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/dgrijalva/jwt-go/rsa.go index 0ae0b198..e4caf1ca 100644 --- a/vendor/github.com/dgrijalva/jwt-go/rsa.go +++ b/vendor/github.com/dgrijalva/jwt-go/rsa.go @@ -7,6 +7,7 @@ import ( ) // Implements the RSA family of signing methods signing methods +// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation type SigningMethodRSA struct { Name string Hash crypto.Hash @@ -44,7 +45,7 @@ func (m *SigningMethodRSA) Alg() string { } // Implements the Verify method from SigningMethod -// For this signing method, must be an rsa.PublicKey structure. +// For this signing method, must be an *rsa.PublicKey structure. func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { var err error @@ -73,7 +74,7 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface } // Implements the Sign method from SigningMethod -// For this signing method, must be an rsa.PrivateKey structure. +// For this signing method, must be an *rsa.PrivateKey structure. func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { var rsaKey *rsa.PrivateKey var ok bool diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go index 213a90db..a5ababf9 100644 --- a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go @@ -39,6 +39,38 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { return pkey, nil } +// Parse PEM encoded PKCS1 or PKCS8 private key protected with password +func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + + var blockDecrypted []byte + if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { + return nil, err + } + + if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + // Parse PEM encoded PKCS1 or PKCS8 public key func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { var err error diff --git a/vendor/github.com/kardianos/osext/osext_go18.go b/vendor/github.com/kardianos/osext/osext_go18.go index 7065a5ff..009d8a92 100644 --- a/vendor/github.com/kardianos/osext/osext_go18.go +++ b/vendor/github.com/kardianos/osext/osext_go18.go @@ -1,4 +1,4 @@ -//+build go1.8 +//+build go1.8,!openbsd package osext diff --git a/vendor/github.com/kardianos/osext/osext_procfs.go b/vendor/github.com/kardianos/osext/osext_procfs.go index 7b0debbb..e1f16f88 100644 --- a/vendor/github.com/kardianos/osext/osext_procfs.go +++ b/vendor/github.com/kardianos/osext/osext_procfs.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !go1.8,linux !go1.8,netbsd !go1.8,solaris !go1.8,dragonfly +// +build !go1.8,android !go1.8,linux !go1.8,netbsd !go1.8,solaris !go1.8,dragonfly package osext @@ -16,7 +16,7 @@ import ( func executable() (string, error) { switch runtime.GOOS { - case "linux": + case "linux", "android": const deletedTag = " (deleted)" execpath, err := os.Readlink("/proc/self/exe") if err != nil { diff --git a/vendor/github.com/kardianos/osext/osext_sysctl.go b/vendor/github.com/kardianos/osext/osext_sysctl.go index 579f224a..33cee252 100644 --- a/vendor/github.com/kardianos/osext/osext_sysctl.go +++ b/vendor/github.com/kardianos/osext/osext_sysctl.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !go1.8,darwin !go1.8,freebsd !go1.8,openbsd +// +build !go1.8,darwin !go1.8,freebsd openbsd package osext diff --git a/vendor/github.com/labstack/echo/.travis.yml b/vendor/github.com/labstack/echo/.travis.yml deleted file mode 100644 index 05e53b16..00000000 --- a/vendor/github.com/labstack/echo/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -go: - - 1.9.x - - 1.10.x - - tip -install: - - make dependency -script: - - make test -after_success: - - bash <(curl -s https://codecov.io/bash) -matrix: - allow_failures: - - go: tip diff --git a/vendor/github.com/labstack/echo/Gopkg.lock b/vendor/github.com/labstack/echo/Gopkg.lock deleted file mode 100644 index f3c3b8d2..00000000 --- a/vendor/github.com/labstack/echo/Gopkg.lock +++ /dev/null @@ -1,75 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/davecgh/go-spew" - packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" - -[[projects]] - name = "github.com/dgrijalva/jwt-go" - packages = ["."] - revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" - version = "v3.2.0" - -[[projects]] - name = "github.com/labstack/gommon" - packages = ["bytes","color","log","random"] - revision = "6fe1405d73ec4bd4cd8a4ac8e2a2b2bf95d03954" - version = "0.2.4" - -[[projects]] - name = "github.com/mattn/go-colorable" - packages = ["."] - revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" - version = "v0.0.9" - -[[projects]] - name = "github.com/mattn/go-isatty" - packages = ["."] - revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" - version = "v0.0.3" - -[[projects]] - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - name = "github.com/stretchr/testify" - packages = ["assert"] - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" - -[[projects]] - branch = "master" - name = "github.com/valyala/bytebufferpool" - packages = ["."] - revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7" - -[[projects]] - branch = "master" - name = "github.com/valyala/fasttemplate" - packages = ["."] - revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0" - -[[projects]] - branch = "master" - name = "golang.org/x/crypto" - packages = ["acme","acme/autocert"] - revision = "182114d582623c1caa54f73de9c7224e23a48487" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "c28acc882ebcbfbe8ce9f0f14b9ac26ee138dd51" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "9c7b45e80fe353405800cf01f429b3a203cfb8d4468a04c64a908e11a98ea764" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/labstack/echo/Gopkg.toml b/vendor/github.com/labstack/echo/Gopkg.toml deleted file mode 100644 index 61de60cb..00000000 --- a/vendor/github.com/labstack/echo/Gopkg.toml +++ /dev/null @@ -1,42 +0,0 @@ - -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - - -[[constraint]] - name = "github.com/dgrijalva/jwt-go" - version = "3.2.0" - -[[constraint]] - name = "github.com/labstack/gommon" - version = "0.2.4" - -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.2.1" - -[[constraint]] - branch = "master" - name = "github.com/valyala/fasttemplate" - -[[constraint]] - branch = "master" - name = "golang.org/x/crypto"
\ No newline at end of file diff --git a/vendor/github.com/labstack/echo/Makefile b/vendor/github.com/labstack/echo/Makefile deleted file mode 100644 index 494667d8..00000000 --- a/vendor/github.com/labstack/echo/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -DEP_VERSION=0.4.1 - -dependency: - curl -fsSL -o ${GOPATH}/bin/dep https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 - chmod +x ${GOPATH}/bin/dep - dep ensure - -test: - echo "" > coverage.txt - for d in $(shell go list ./... | grep -v vendor); do \ - go test -race -coverprofile=profile.out -covermode=atomic $$d || exit 1; \ - [ -f profile.out ] && cat profile.out >> coverage.txt && rm profile.out; \ - done - -tag: - @git tag `grep -P '^\tversion = ' echo.go|cut -f2 -d'"'` - @git tag|grep -v ^v diff --git a/vendor/github.com/labstack/echo/.editorconfig b/vendor/github.com/labstack/echo/v4/.editorconfig index 17ae50dd..17ae50dd 100644 --- a/vendor/github.com/labstack/echo/.editorconfig +++ b/vendor/github.com/labstack/echo/v4/.editorconfig diff --git a/vendor/github.com/labstack/echo/.gitattributes b/vendor/github.com/labstack/echo/v4/.gitattributes index 49b63e52..49b63e52 100644 --- a/vendor/github.com/labstack/echo/.gitattributes +++ b/vendor/github.com/labstack/echo/v4/.gitattributes diff --git a/vendor/github.com/labstack/echo/.gitignore b/vendor/github.com/labstack/echo/v4/.gitignore index dd74acca..dd74acca 100644 --- a/vendor/github.com/labstack/echo/.gitignore +++ b/vendor/github.com/labstack/echo/v4/.gitignore diff --git a/vendor/github.com/labstack/echo/v4/.travis.yml b/vendor/github.com/labstack/echo/v4/.travis.yml new file mode 100644 index 00000000..30346d7f --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/.travis.yml @@ -0,0 +1,16 @@ +language: go +go: + - 1.11.x + - tip +env: + - GO111MODULE=on +install: + - go get -v golang.org/x/lint/golint +script: + - golint -set_exit_status ./... + - go test -race -coverprofile=coverage.txt -covermode=atomic ./... +after_success: + - bash <(curl -s https://codecov.io/bash) +matrix: + allow_failures: + - go: tip diff --git a/vendor/github.com/labstack/echo/LICENSE b/vendor/github.com/labstack/echo/v4/LICENSE index b5b006b4..b5b006b4 100644 --- a/vendor/github.com/labstack/echo/LICENSE +++ b/vendor/github.com/labstack/echo/v4/LICENSE diff --git a/vendor/github.com/labstack/echo/v4/Makefile b/vendor/github.com/labstack/echo/v4/Makefile new file mode 100644 index 00000000..dfcb6c02 --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/Makefile @@ -0,0 +1,3 @@ +tag: + @git tag `grep -P '^\tversion = ' echo.go|cut -f2 -d'"'` + @git tag|grep -v ^v diff --git a/vendor/github.com/labstack/echo/README.md b/vendor/github.com/labstack/echo/v4/README.md index 0f609df4..1db5e356 100644 --- a/vendor/github.com/labstack/echo/README.md +++ b/vendor/github.com/labstack/echo/v4/README.md @@ -4,12 +4,26 @@ [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/labstack/echo) [![Go Report Card](https://goreportcard.com/badge/github.com/labstack/echo?style=flat-square)](https://goreportcard.com/report/github.com/labstack/echo) [![Build Status](http://img.shields.io/travis/labstack/echo.svg?style=flat-square)](https://travis-ci.org/labstack/echo) -[![Codecov](https://img.shields.io/codecov/c/github/labstack/echo.svg?style=flat-square)](https://codecov.io/gh/labstack/echo) +[![Codecov](https://img.shields.io/codecov/c/github/labstack/echo.svg?style=flat-square)](https://codecov.io/gh/labstack/echo) [![Join the chat at https://gitter.im/labstack/echo](https://img.shields.io/badge/gitter-join%20chat-brightgreen.svg?style=flat-square)](https://gitter.im/labstack/echo) [![Forum](https://img.shields.io/badge/community-forum-00afd1.svg?style=flat-square)](https://forum.labstack.com) [![Twitter](https://img.shields.io/badge/twitter-@labstack-55acee.svg?style=flat-square)](https://twitter.com/labstack) [![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/labstack/echo/master/LICENSE) +## Supported Go versions + +As of version 4.0.0, Echo is available as a [Go module](https://github.com/golang/go/wiki/Modules). +Therefore a Go version capable of understanding /vN suffixed imports is required: + +- 1.9.7+ +- 1.10.3+ +- 1.11+ + +Any of these versions will allow you to import Echo as `github.com/labstack/echo/v4` which is the recommended +way of using Echo going forward. + +For older versions, please use the latest v3 tag. + ## Feature Overview - Optimized HTTP router which smartly prioritize routes @@ -32,7 +46,7 @@ Date: 2018/03/15<br> Source: https://github.com/vishr/web-framework-benchmark<br> Lower is better! -<img src="https://api.labstack.com/chart/bar?values=37223,55382,2985,5265|42013,59865,3350,6424&labels=Static,GitHub%20API,Parse%20API,Gplus%20API&titles=Echo,Gin&colors=lightseagreen,goldenrod&x_title=Routes&y_title=ns/op"> +<img src="https://i.imgur.com/I32VdMJ.png"> ## [Guide](https://echo.labstack.com/guide) @@ -44,8 +58,8 @@ package main import ( "net/http" - "github.com/labstack/echo" - "github.com/labstack/echo/middleware" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" ) func main() { @@ -90,6 +104,7 @@ func hello(c echo.Context) error { - Improve/fix documentation ## Credits + - [Vishal Rana](https://github.com/vishr) - Author - [Nitin Rana](https://github.com/nr17) - Consultant - [Contributors](https://github.com/labstack/echo/graphs/contributors) diff --git a/vendor/github.com/labstack/echo/bind.go b/vendor/github.com/labstack/echo/v4/bind.go index 38e07150..cb65ed2d 100644 --- a/vendor/github.com/labstack/echo/bind.go +++ b/vendor/github.com/labstack/echo/v4/bind.go @@ -31,9 +31,9 @@ type ( func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) { req := c.Request() if req.ContentLength == 0 { - if req.Method == GET || req.Method == DELETE { + if req.Method == http.MethodGet || req.Method == http.MethodDelete { if err = b.bindData(i, c.QueryParams(), "query"); err != nil { - return NewHTTPError(http.StatusBadRequest, err.Error()) + return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) } return } @@ -44,30 +44,28 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) { case strings.HasPrefix(ctype, MIMEApplicationJSON): if err = json.NewDecoder(req.Body).Decode(i); err != nil { if ute, ok := err.(*json.UnmarshalTypeError); ok { - return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, offset=%v", ute.Type, ute.Value, ute.Offset)) + return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset)).SetInternal(err) } else if se, ok := err.(*json.SyntaxError); ok { - return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error())) - } else { - return NewHTTPError(http.StatusBadRequest, err.Error()) + return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error())).SetInternal(err) } + return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) } case strings.HasPrefix(ctype, MIMEApplicationXML), strings.HasPrefix(ctype, MIMETextXML): if err = xml.NewDecoder(req.Body).Decode(i); err != nil { if ute, ok := err.(*xml.UnsupportedTypeError); ok { - return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error())) + return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error())).SetInternal(err) } else if se, ok := err.(*xml.SyntaxError); ok { - return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: line=%v, error=%v", se.Line, se.Error())) - } else { - return NewHTTPError(http.StatusBadRequest, err.Error()) + return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: line=%v, error=%v", se.Line, se.Error())).SetInternal(err) } + return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) } case strings.HasPrefix(ctype, MIMEApplicationForm), strings.HasPrefix(ctype, MIMEMultipartForm): params, err := c.FormParams() if err != nil { - return NewHTTPError(http.StatusBadRequest, err.Error()) + return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) } if err = b.bindData(i, params, "form"); err != nil { - return NewHTTPError(http.StatusBadRequest, err.Error()) + return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) } default: return ErrUnsupportedMediaType @@ -96,15 +94,30 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag inputFieldName = typeField.Name // If tag is nil, we inspect if the field is a struct. if _, ok := bindUnmarshaler(structField); !ok && structFieldKind == reflect.Struct { - err := b.bindData(structField.Addr().Interface(), data, tag) - if err != nil { + if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil { return err } continue } } + inputValue, exists := data[inputFieldName] if !exists { + // Go json.Unmarshal supports case insensitive binding. However the + // url params are bound case sensitive which is inconsistent. To + // fix this we must check all of the map values in a + // case-insensitive search. + inputFieldName = strings.ToLower(inputFieldName) + for k, v := range data { + if strings.ToLower(k) == inputFieldName { + inputValue = v + exists = true + break + } + } + } + + if !exists { continue } @@ -126,10 +139,9 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag } } val.Field(i).Set(slice) - } else { - if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil { - return err - } + } else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil { + return err + } } return nil diff --git a/vendor/github.com/labstack/echo/context.go b/vendor/github.com/labstack/echo/v4/context.go index cf780c51..d4722700 100644 --- a/vendor/github.com/labstack/echo/context.go +++ b/vendor/github.com/labstack/echo/v4/context.go @@ -204,6 +204,7 @@ type ( const ( defaultMemory = 32 << 20 // 32 MB indexPage = "index.html" + defaultIndent = " " ) func (c *context) writeContentType(value string) { @@ -256,14 +257,13 @@ func (c *context) Scheme() string { } func (c *context) RealIP() string { - ra := c.request.RemoteAddr if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" { - ra = strings.Split(ip, ", ")[0] - } else if ip := c.request.Header.Get(HeaderXRealIP); ip != "" { - ra = ip - } else { - ra, _, _ = net.SplitHostPort(ra) + return strings.Split(ip, ", ")[0] + } + if ip := c.request.Header.Get(HeaderXRealIP); ip != "" { + return ip } + ra, _, _ := net.SplitHostPort(c.request.RemoteAddr) return ra } @@ -404,24 +404,46 @@ func (c *context) String(code int, s string) (err error) { return c.Blob(code, MIMETextPlainCharsetUTF8, []byte(s)) } -func (c *context) JSON(code int, i interface{}) (err error) { +func (c *context) jsonPBlob(code int, callback string, i interface{}) (err error) { + enc := json.NewEncoder(c.response) _, pretty := c.QueryParams()["pretty"] if c.echo.Debug || pretty { - return c.JSONPretty(code, i, " ") + enc.SetIndent("", " ") } - b, err := json.Marshal(i) - if err != nil { + c.writeContentType(MIMEApplicationJavaScriptCharsetUTF8) + c.response.WriteHeader(code) + if _, err = c.response.Write([]byte(callback + "(")); err != nil { + return + } + if err = enc.Encode(i); err != nil { + return + } + if _, err = c.response.Write([]byte(");")); err != nil { return } - return c.JSONBlob(code, b) + return } -func (c *context) JSONPretty(code int, i interface{}, indent string) (err error) { - b, err := json.MarshalIndent(i, "", indent) - if err != nil { - return +func (c *context) json(code int, i interface{}, indent string) error { + enc := json.NewEncoder(c.response) + if indent != "" { + enc.SetIndent("", indent) + } + c.writeContentType(MIMEApplicationJSONCharsetUTF8) + c.response.WriteHeader(code) + return enc.Encode(i) +} + +func (c *context) JSON(code int, i interface{}) (err error) { + indent := "" + if _, pretty := c.QueryParams()["pretty"]; c.echo.Debug || pretty { + indent = defaultIndent } - return c.JSONBlob(code, b) + return c.json(code, i, indent) +} + +func (c *context) JSONPretty(code int, i interface{}, indent string) (err error) { + return c.json(code, i, indent) } func (c *context) JSONBlob(code int, b []byte) (err error) { @@ -429,11 +451,7 @@ func (c *context) JSONBlob(code int, b []byte) (err error) { } func (c *context) JSONP(code int, callback string, i interface{}) (err error) { - b, err := json.Marshal(i) - if err != nil { - return - } - return c.JSONPBlob(code, callback, b) + return c.jsonPBlob(code, callback, i) } func (c *context) JSONPBlob(code int, callback string, b []byte) (err error) { @@ -449,24 +467,29 @@ func (c *context) JSONPBlob(code int, callback string, b []byte) (err error) { return } -func (c *context) XML(code int, i interface{}) (err error) { - _, pretty := c.QueryParams()["pretty"] - if c.echo.Debug || pretty { - return c.XMLPretty(code, i, " ") +func (c *context) xml(code int, i interface{}, indent string) (err error) { + c.writeContentType(MIMEApplicationXMLCharsetUTF8) + c.response.WriteHeader(code) + enc := xml.NewEncoder(c.response) + if indent != "" { + enc.Indent("", indent) } - b, err := xml.Marshal(i) - if err != nil { + if _, err = c.response.Write([]byte(xml.Header)); err != nil { return } - return c.XMLBlob(code, b) + return enc.Encode(i) } -func (c *context) XMLPretty(code int, i interface{}, indent string) (err error) { - b, err := xml.MarshalIndent(i, "", indent) - if err != nil { - return +func (c *context) XML(code int, i interface{}) (err error) { + indent := "" + if _, pretty := c.QueryParams()["pretty"]; c.echo.Debug || pretty { + indent = defaultIndent } - return c.XMLBlob(code, b) + return c.xml(code, i, indent) +} + +func (c *context) XMLPretty(code int, i interface{}, indent string) (err error) { + return c.xml(code, i, indent) } func (c *context) XMLBlob(code int, b []byte) (err error) { @@ -574,3 +597,4 @@ 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/echo.go b/vendor/github.com/labstack/echo/v4/echo.go index 41ac6b5e..0fe6880f 100644 --- a/vendor/github.com/labstack/echo/echo.go +++ b/vendor/github.com/labstack/echo/v4/echo.go @@ -8,8 +8,8 @@ Example: import ( "net/http" - "github.com/labstack/echo" - "github.com/labstack/echo/middleware" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" ) // Handler @@ -62,7 +62,7 @@ import ( type ( // Echo is the top-level framework instance. Echo struct { - stdLogger *stdLog.Logger + StdLogger *stdLog.Logger colorer *color.Color premiddleware []MiddlewareFunc middleware []MiddlewareFunc @@ -103,7 +103,7 @@ type ( // MiddlewareFunc defines a function to process middleware. MiddlewareFunc func(HandlerFunc) HandlerFunc - // HandlerFunc defines a function to server HTTP requests. + // HandlerFunc defines a function to serve HTTP requests. HandlerFunc func(Context) error // HTTPErrorHandler is a centralized HTTP error handler. @@ -129,17 +129,18 @@ type ( ) // HTTP methods +// NOTE: Deprecated, please use the stdlib constants directly instead. const ( - CONNECT = "CONNECT" - DELETE = "DELETE" - GET = "GET" - HEAD = "HEAD" - OPTIONS = "OPTIONS" - PATCH = "PATCH" - POST = "POST" - PROPFIND = "PROPFIND" - PUT = "PUT" - TRACE = "TRACE" + CONNECT = http.MethodConnect + DELETE = http.MethodDelete + GET = http.MethodGet + HEAD = http.MethodHead + OPTIONS = http.MethodOptions + PATCH = http.MethodPatch + POST = http.MethodPost + // PROPFIND = "PROPFIND" + PUT = http.MethodPut + TRACE = http.MethodTrace ) // MIME types @@ -165,6 +166,8 @@ const ( const ( charsetUTF8 = "charset=UTF-8" + // PROPFIND Method can be used on collection and property resources. + PROPFIND = "PROPFIND" ) // Headers @@ -217,7 +220,8 @@ const ( ) const ( - Version = "3.3.5" + // Version of Echo + Version = "4.0.0" website = "https://echo.labstack.com" // http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo banner = ` @@ -234,16 +238,16 @@ ____________________________________O/_______ var ( methods = [...]string{ - CONNECT, - DELETE, - GET, - HEAD, - OPTIONS, - PATCH, - POST, + http.MethodConnect, + http.MethodDelete, + http.MethodGet, + http.MethodHead, + http.MethodOptions, + http.MethodPatch, + http.MethodPost, PROPFIND, - PUT, - TRACE, + http.MethodPut, + http.MethodTrace, } ) @@ -255,6 +259,12 @@ var ( ErrForbidden = NewHTTPError(http.StatusForbidden) ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed) ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge) + ErrTooManyRequests = NewHTTPError(http.StatusTooManyRequests) + ErrBadRequest = NewHTTPError(http.StatusBadRequest) + ErrBadGateway = NewHTTPError(http.StatusBadGateway) + ErrInternalServerError = NewHTTPError(http.StatusInternalServerError) + ErrRequestTimeout = NewHTTPError(http.StatusRequestTimeout) + ErrServiceUnavailable = NewHTTPError(http.StatusServiceUnavailable) ErrValidatorNotRegistered = errors.New("validator not registered") ErrRendererNotRegistered = errors.New("renderer not registered") ErrInvalidRedirectCode = errors.New("invalid redirect status code") @@ -289,7 +299,7 @@ func New() (e *Echo) { e.HTTPErrorHandler = e.DefaultHTTPErrorHandler e.Binder = &DefaultBinder{} e.Logger.SetLevel(log.ERROR) - e.stdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0) + e.StdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0) e.pool.New = func() interface{} { return e.NewContext(nil, nil) } @@ -326,7 +336,7 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) { code = he.Code msg = he.Message if he.Internal != nil { - msg = fmt.Sprintf("%v, %v", err, he.Internal) + err = fmt.Errorf("%v, %v", err, he.Internal) } } else if e.Debug { msg = err.Error() @@ -337,11 +347,9 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) { msg = Map{"message": msg} } - e.Logger.Error(err) - // Send response if !c.Response().Committed { - if c.Request().Method == HEAD { // Issue #608 + if c.Request().Method == http.MethodHead { // Issue #608 err = c.NoContent(code) } else { err = c.JSON(code, msg) @@ -365,55 +373,55 @@ func (e *Echo) Use(middleware ...MiddlewareFunc) { // CONNECT registers a new CONNECT route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(CONNECT, path, h, m...) + return e.Add(http.MethodConnect, path, h, m...) } // DELETE registers a new DELETE route for a path with matching handler in the router // with optional route-level middleware. func (e *Echo) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(DELETE, path, h, m...) + return e.Add(http.MethodDelete, path, h, m...) } // GET registers a new GET route for a path with matching handler in the router // with optional route-level middleware. func (e *Echo) GET(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(GET, path, h, m...) + return e.Add(http.MethodGet, path, h, m...) } // HEAD registers a new HEAD route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(HEAD, path, h, m...) + return e.Add(http.MethodHead, path, h, m...) } // OPTIONS registers a new OPTIONS route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(OPTIONS, path, h, m...) + return e.Add(http.MethodOptions, path, h, m...) } // PATCH registers a new PATCH route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(PATCH, path, h, m...) + return e.Add(http.MethodPatch, path, h, m...) } // POST registers a new POST route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) POST(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(POST, path, h, m...) + return e.Add(http.MethodPost, path, h, m...) } // PUT registers a new PUT route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(PUT, path, h, m...) + return e.Add(http.MethodPut, path, h, m...) } // TRACE registers a new TRACE route for a path with matching handler in the // router with optional route-level middleware. func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return e.Add(TRACE, path, h, m...) + return e.Add(http.MethodTrace, path, h, m...) } // Any registers a new route for all HTTP methods and path with matching handler @@ -462,11 +470,11 @@ func static(i i, prefix, root string) *Route { return i.GET(prefix+"/*", h) } -// File registers a new route with path to serve a static file. -func (e *Echo) File(path, file string) *Route { +// 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...) } // Add registers a new route for an HTTP method and path with matching handler @@ -559,26 +567,17 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) { c := e.pool.Get().(*context) c.Reset(r, w) - m := r.Method h := NotFoundHandler if e.premiddleware == nil { - path := r.URL.RawPath - if path == "" { - path = r.URL.Path - } - e.router.Find(m, getPath(r), c) + e.router.Find(r.Method, getPath(r), c) h = c.Handler() for i := len(e.middleware) - 1; i >= 0; i-- { h = e.middleware[i](h) } } else { h = func(c Context) error { - path := r.URL.RawPath - if path == "" { - path = r.URL.Path - } - e.router.Find(m, getPath(r), c) + e.router.Find(r.Method, getPath(r), c) h := c.Handler() for i := len(e.middleware) - 1; i >= 0; i-- { h = e.middleware[i](h) @@ -622,10 +621,6 @@ func (e *Echo) StartTLS(address string, certFile, keyFile string) (err error) { // StartAutoTLS starts an HTTPS server using certificates automatically installed from https://letsencrypt.org. func (e *Echo) StartAutoTLS(address string) error { - if e.Listener == nil { - go http.ListenAndServe(":http", e.AutoTLSManager.HTTPHandler(nil)) - } - s := e.TLSServer s.TLSConfig = new(tls.Config) s.TLSConfig.GetCertificate = e.AutoTLSManager.GetCertificate @@ -645,7 +640,7 @@ func (e *Echo) startTLS(address string) error { func (e *Echo) StartServer(s *http.Server) (err error) { // Setup e.colorer.SetOutput(e.Logger.Output()) - s.ErrorLog = e.stdLogger + s.ErrorLog = e.StdLogger s.Handler = e if e.Debug { e.Logger.SetLevel(log.DEBUG) @@ -689,7 +684,7 @@ func (e *Echo) Close() error { return e.Server.Close() } -// Shutdown stops server the gracefully. +// Shutdown stops the server gracefully. // It internally calls `http.Server#Shutdown()`. func (e *Echo) Shutdown(ctx stdContext.Context) error { if err := e.TLSServer.Shutdown(ctx); err != nil { @@ -712,6 +707,12 @@ func (he *HTTPError) Error() string { return fmt.Sprintf("code=%d, message=%v", he.Code, he.Message) } +// SetInternal sets error to HTTPError.Internal +func (he *HTTPError) SetInternal(err error) *HTTPError { + he.Internal = err + return he +} + // WrapHandler wraps `http.Handler` into `echo.HandlerFunc`. func WrapHandler(h http.Handler) HandlerFunc { return func(c Context) error { diff --git a/vendor/github.com/labstack/echo/v4/go.mod b/vendor/github.com/labstack/echo/v4/go.mod new file mode 100644 index 00000000..2853cba5 --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/go.mod @@ -0,0 +1,13 @@ +module github.com/labstack/echo/v4 + +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/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 +) diff --git a/vendor/github.com/labstack/echo/v4/go.sum b/vendor/github.com/labstack/echo/v4/go.sum new file mode 100644 index 00000000..e6981931 --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/go.sum @@ -0,0 +1,23 @@ +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/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/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/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= diff --git a/vendor/github.com/labstack/echo/group.go b/vendor/github.com/labstack/echo/v4/group.go index 5257e83c..3e3732b6 100644 --- a/vendor/github.com/labstack/echo/group.go +++ b/vendor/github.com/labstack/echo/v4/group.go @@ -1,6 +1,7 @@ package echo import ( + "net/http" "path" ) @@ -29,47 +30,47 @@ func (g *Group) Use(middleware ...MiddlewareFunc) { // CONNECT implements `Echo#CONNECT()` for sub-routes within the Group. func (g *Group) CONNECT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(CONNECT, path, h, m...) + return g.Add(http.MethodConnect, path, h, m...) } // DELETE implements `Echo#DELETE()` for sub-routes within the Group. func (g *Group) DELETE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(DELETE, path, h, m...) + return g.Add(http.MethodDelete, path, h, m...) } // GET implements `Echo#GET()` for sub-routes within the Group. func (g *Group) GET(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(GET, path, h, m...) + return g.Add(http.MethodGet, path, h, m...) } // HEAD implements `Echo#HEAD()` for sub-routes within the Group. func (g *Group) HEAD(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(HEAD, path, h, m...) + return g.Add(http.MethodHead, path, h, m...) } // OPTIONS implements `Echo#OPTIONS()` for sub-routes within the Group. func (g *Group) OPTIONS(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(OPTIONS, path, h, m...) + return g.Add(http.MethodOptions, path, h, m...) } // PATCH implements `Echo#PATCH()` for sub-routes within the Group. func (g *Group) PATCH(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(PATCH, path, h, m...) + return g.Add(http.MethodPatch, path, h, m...) } // POST implements `Echo#POST()` for sub-routes within the Group. func (g *Group) POST(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(POST, path, h, m...) + return g.Add(http.MethodPost, path, h, m...) } // PUT implements `Echo#PUT()` for sub-routes within the Group. func (g *Group) PUT(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(PUT, path, h, m...) + return g.Add(http.MethodPut, path, h, m...) } // TRACE implements `Echo#TRACE()` for sub-routes within the Group. func (g *Group) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route { - return g.Add(TRACE, path, h, m...) + return g.Add(http.MethodTrace, path, h, m...) } // Any implements `Echo#Any()` for sub-routes within the Group. diff --git a/vendor/github.com/labstack/echo/log.go b/vendor/github.com/labstack/echo/v4/log.go index b194c39c..3f8de590 100644 --- a/vendor/github.com/labstack/echo/log.go +++ b/vendor/github.com/labstack/echo/v4/log.go @@ -15,6 +15,7 @@ type ( SetPrefix(p string) Level() log.Lvl SetLevel(v log.Lvl) + SetHeader(h string) Print(i ...interface{}) Printf(format string, args ...interface{}) Printj(j log.JSON) diff --git a/vendor/github.com/labstack/echo/middleware/basic_auth.go b/vendor/github.com/labstack/echo/v4/middleware/basic_auth.go index e6c96324..76ba2420 100644 --- a/vendor/github.com/labstack/echo/middleware/basic_auth.go +++ b/vendor/github.com/labstack/echo/v4/middleware/basic_auth.go @@ -5,7 +5,7 @@ import ( "strconv" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( diff --git a/vendor/github.com/labstack/echo/middleware/body_dump.go b/vendor/github.com/labstack/echo/v4/middleware/body_dump.go index e64e5e11..418d279d 100644 --- a/vendor/github.com/labstack/echo/middleware/body_dump.go +++ b/vendor/github.com/labstack/echo/v4/middleware/body_dump.go @@ -8,7 +8,7 @@ import ( "net" "net/http" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( @@ -105,7 +105,3 @@ func (w *bodyDumpResponseWriter) Flush() { func (w *bodyDumpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { return w.ResponseWriter.(http.Hijacker).Hijack() } - -func (w *bodyDumpResponseWriter) CloseNotify() <-chan bool { - return w.ResponseWriter.(http.CloseNotifier).CloseNotify() -} diff --git a/vendor/github.com/labstack/echo/middleware/body_limit.go b/vendor/github.com/labstack/echo/v4/middleware/body_limit.go index c83f57e1..b436bd59 100644 --- a/vendor/github.com/labstack/echo/middleware/body_limit.go +++ b/vendor/github.com/labstack/echo/v4/middleware/body_limit.go @@ -5,7 +5,7 @@ import ( "io" "sync" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" "github.com/labstack/gommon/bytes" ) diff --git a/vendor/github.com/labstack/echo/middleware/compress.go b/vendor/github.com/labstack/echo/v4/middleware/compress.go index b876009c..19052064 100644 --- a/vendor/github.com/labstack/echo/middleware/compress.go +++ b/vendor/github.com/labstack/echo/v4/middleware/compress.go @@ -9,7 +9,7 @@ import ( "net/http" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( @@ -116,7 +116,3 @@ func (w *gzipResponseWriter) Flush() { func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { return w.ResponseWriter.(http.Hijacker).Hijack() } - -func (w *gzipResponseWriter) CloseNotify() <-chan bool { - return w.ResponseWriter.(http.CloseNotifier).CloseNotify() -} diff --git a/vendor/github.com/labstack/echo/middleware/cors.go b/vendor/github.com/labstack/echo/v4/middleware/cors.go index 771000a5..c61c7125 100644 --- a/vendor/github.com/labstack/echo/middleware/cors.go +++ b/vendor/github.com/labstack/echo/v4/middleware/cors.go @@ -5,7 +5,7 @@ import ( "strconv" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( @@ -24,7 +24,7 @@ type ( AllowMethods []string `yaml:"allow_methods"` // AllowHeaders defines a list of request headers that can be used when - // making the actual request. This in response to a preflight request. + // making the actual request. This is in response to a preflight request. // Optional. Default value []string{}. AllowHeaders []string `yaml:"allow_headers"` @@ -52,7 +52,7 @@ var ( DefaultCORSConfig = CORSConfig{ Skipper: DefaultSkipper, AllowOrigins: []string{"*"}, - AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE}, + AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete}, } ) @@ -94,6 +94,10 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc { // Check allowed origins for _, o := range config.AllowOrigins { + if o == "*" && config.AllowCredentials { + allowOrigin = origin + break + } if o == "*" || o == origin { allowOrigin = o break @@ -101,7 +105,7 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc { } // Simple request - if req.Method != echo.OPTIONS { + if req.Method != http.MethodOptions { res.Header().Add(echo.HeaderVary, echo.HeaderOrigin) res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowOrigin) if config.AllowCredentials { diff --git a/vendor/github.com/labstack/echo/middleware/csrf.go b/vendor/github.com/labstack/echo/v4/middleware/csrf.go index 5d1f4671..09a66bb6 100644 --- a/vendor/github.com/labstack/echo/middleware/csrf.go +++ b/vendor/github.com/labstack/echo/v4/middleware/csrf.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" "github.com/labstack/gommon/random" ) @@ -135,7 +135,7 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc { } switch req.Method { - case echo.GET, echo.HEAD, echo.OPTIONS, echo.TRACE: + case http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodTrace: default: // Validate token only for requests which are not defined as 'safe' by RFC7231 clientToken, err := extractor(c) diff --git a/vendor/github.com/labstack/echo/middleware/jwt.go b/vendor/github.com/labstack/echo/v4/middleware/jwt.go index e98040ae..861d3142 100644 --- a/vendor/github.com/labstack/echo/middleware/jwt.go +++ b/vendor/github.com/labstack/echo/v4/middleware/jwt.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/dgrijalva/jwt-go" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( @@ -16,6 +16,16 @@ type ( // Skipper defines a function to skip middleware. Skipper Skipper + // BeforeFunc defines a function which is executed just before the middleware. + BeforeFunc BeforeFunc + + // SuccessHandler defines a function which is executed for a valid token. + SuccessHandler JWTSuccessHandler + + // ErrorHandler defines a function which is executed for an invalid token. + // It may be used to define a custom JWT error. + ErrorHandler JWTErrorHandler + // Signing key to validate token. // Required. SigningKey interface{} @@ -48,6 +58,12 @@ type ( keyFunc jwt.Keyfunc } + // JWTSuccessHandler defines a function which is executed for a valid token. + JWTSuccessHandler func(echo.Context) + + // JWTErrorHandler defines a function which is executed for an invalid token. + JWTErrorHandler func(error) error + jwtExtractor func(echo.Context) (string, error) ) @@ -59,7 +75,6 @@ const ( // Errors var ( ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt") - ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt") ) var ( @@ -137,8 +152,15 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { return next(c) } + if config.BeforeFunc != nil { + config.BeforeFunc(c) + } + auth, err := extractor(c) if err != nil { + if config.ErrorHandler != nil { + return config.ErrorHandler(err) + } return err } token := new(jwt.Token) @@ -153,11 +175,17 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { if err == nil && token.Valid { // Store user information from token into context. c.Set(config.ContextKey, token) + if config.SuccessHandler != nil { + config.SuccessHandler(c) + } return next(c) } + if config.ErrorHandler != nil { + return config.ErrorHandler(err) + } return &echo.HTTPError{ - Code: ErrJWTInvalid.Code, - Message: ErrJWTInvalid.Message, + Code: http.StatusUnauthorized, + Message: "invalid or expired jwt", Internal: err, } } diff --git a/vendor/github.com/labstack/echo/middleware/key_auth.go b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go index c12f4ca9..fe01e23e 100644 --- a/vendor/github.com/labstack/echo/middleware/key_auth.go +++ b/vendor/github.com/labstack/echo/v4/middleware/key_auth.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( diff --git a/vendor/github.com/labstack/echo/middleware/logger.go b/vendor/github.com/labstack/echo/v4/middleware/logger.go index 87af575f..b2e48347 100644 --- a/vendor/github.com/labstack/echo/middleware/logger.go +++ b/vendor/github.com/labstack/echo/v4/middleware/logger.go @@ -9,7 +9,7 @@ import ( "sync" "time" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" "github.com/labstack/gommon/color" "github.com/valyala/fasttemplate" ) @@ -33,9 +33,11 @@ type ( // - host // - method // - path + // - protocol // - referer // - user_agent // - status + // - error // - latency (In nanoseconds) // - latency_human (Human readable) // - bytes_in (Bytes received) @@ -66,10 +68,10 @@ var ( // DefaultLoggerConfig is the default Logger middleware config. DefaultLoggerConfig = LoggerConfig{ Skipper: DefaultSkipper, - Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` + - `"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` + - `"latency_human":"${latency_human}","bytes_in":${bytes_in},` + - `"bytes_out":${bytes_out}}` + "\n", + Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}",` + + `"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` + + `"status":${status},"error":"${error}","latency":${latency},"latency_human":"${latency_human}"` + + `,"bytes_in":${bytes_in},"bytes_out":${bytes_out}}` + "\n", CustomTimeFormat: "2006-01-02 15:04:05.00000", Output: os.Stdout, colorer: color.New(), @@ -153,6 +155,8 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc { p = "/" } return buf.WriteString(p) + case "protocol": + return buf.WriteString(req.Proto) case "referer": return buf.WriteString(req.Referer()) case "user_agent": @@ -169,6 +173,10 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc { s = config.colorer.Cyan(n) } return buf.WriteString(s) + case "error": + if err != nil { + return buf.WriteString(err.Error()) + } case "latency": l := stop.Sub(start) return buf.WriteString(strconv.FormatInt(int64(l), 10)) diff --git a/vendor/github.com/labstack/echo/middleware/method_override.go b/vendor/github.com/labstack/echo/v4/middleware/method_override.go index 955fd11e..92b14d2e 100644 --- a/vendor/github.com/labstack/echo/middleware/method_override.go +++ b/vendor/github.com/labstack/echo/v4/middleware/method_override.go @@ -1,6 +1,10 @@ package middleware -import "github.com/labstack/echo" +import ( + "net/http" + + "github.com/labstack/echo/v4" +) type ( // MethodOverrideConfig defines the config for MethodOverride middleware. @@ -52,7 +56,7 @@ func MethodOverrideWithConfig(config MethodOverrideConfig) echo.MiddlewareFunc { } req := c.Request() - if req.Method == echo.POST { + if req.Method == http.MethodPost { m := config.Getter(c) if m != "" { req.Method = m diff --git a/vendor/github.com/labstack/echo/middleware/middleware.go b/vendor/github.com/labstack/echo/v4/middleware/middleware.go index 71f95db7..d0b7153c 100644 --- a/vendor/github.com/labstack/echo/middleware/middleware.go +++ b/vendor/github.com/labstack/echo/v4/middleware/middleware.go @@ -5,13 +5,16 @@ import ( "strconv" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( // Skipper defines a function to skip middleware. Returning true skips processing // the middleware. - Skipper func(c echo.Context) bool + Skipper func(echo.Context) bool + + // BeforeFunc defines a function which is executed just before the middleware. + BeforeFunc func(echo.Context) ) func captureTokens(pattern *regexp.Regexp, input string) *strings.Replacer { diff --git a/vendor/github.com/labstack/echo/middleware/proxy.go b/vendor/github.com/labstack/echo/v4/middleware/proxy.go index f6147737..9d67f445 100644 --- a/vendor/github.com/labstack/echo/middleware/proxy.go +++ b/vendor/github.com/labstack/echo/v4/middleware/proxy.go @@ -6,7 +6,6 @@ import ( "math/rand" "net" "net/http" - "net/http/httputil" "net/url" "regexp" "strings" @@ -14,7 +13,7 @@ import ( "sync/atomic" "time" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) // TODO: Handle TLS proxy @@ -38,6 +37,14 @@ type ( // "/users/*/orders/*": "/user/$1/order/$2", Rewrite map[string]string + // Context key to store selected ProxyTarget into context. + // Optional. Default value "target". + ContextKey string + + // To customize the transport to remote. + // Examples: If custom TLS certificates are required. + Transport http.RoundTripper + rewriteRegex map[*regexp.Regexp]string } @@ -45,13 +52,14 @@ type ( ProxyTarget struct { Name string URL *url.URL + Meta echo.Map } // ProxyBalancer defines an interface to implement a load balancing technique. ProxyBalancer interface { AddTarget(*ProxyTarget) bool RemoveTarget(string) bool - Next() *ProxyTarget + Next(echo.Context) *ProxyTarget } commonBalancer struct { @@ -75,14 +83,11 @@ type ( var ( // DefaultProxyConfig is the default Proxy middleware config. DefaultProxyConfig = ProxyConfig{ - Skipper: DefaultSkipper, + Skipper: DefaultSkipper, + ContextKey: "target", } ) -func proxyHTTP(t *ProxyTarget) http.Handler { - return httputil.NewSingleHostReverseProxy(t.URL) -} - func proxyRaw(t *ProxyTarget, c echo.Context) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { in, _, err := c.Response().Hijack() @@ -164,7 +169,7 @@ func (b *commonBalancer) RemoveTarget(name string) bool { } // Next randomly returns an upstream target. -func (b *randomBalancer) Next() *ProxyTarget { +func (b *randomBalancer) Next(c echo.Context) *ProxyTarget { if b.random == nil { b.random = rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) } @@ -174,7 +179,7 @@ func (b *randomBalancer) Next() *ProxyTarget { } // Next returns an upstream target using round-robin technique. -func (b *roundRobinBalancer) Next() *ProxyTarget { +func (b *roundRobinBalancer) Next(c echo.Context) *ProxyTarget { b.i = b.i % uint32(len(b.targets)) t := b.targets[b.i] atomic.AddUint32(&b.i, 1) @@ -216,7 +221,8 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc { req := c.Request() res := c.Response() - tgt := config.Balancer.Next() + tgt := config.Balancer.Next(c) + c.Set(config.ContextKey, tgt) // Rewrite for k, v := range config.rewriteRegex { @@ -243,7 +249,7 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc { proxyRaw(tgt, c).ServeHTTP(res, req) case req.Header.Get(echo.HeaderAccept) == "text/event-stream": default: - proxyHTTP(tgt).ServeHTTP(res, req) + proxyHTTP(tgt, c, config).ServeHTTP(res, req) } return diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go b/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go new file mode 100644 index 00000000..7784f9c6 --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11.go @@ -0,0 +1,25 @@ +// +build go1.11 + +package middleware + +import ( + "fmt" + "net/http" + "net/http/httputil" + + "github.com/labstack/echo/v4" +) + +func proxyHTTP(tgt *ProxyTarget, c echo.Context, config ProxyConfig) http.Handler { + proxy := httputil.NewSingleHostReverseProxy(tgt.URL) + proxy.ErrorHandler = func(resp http.ResponseWriter, req *http.Request, err error) { + desc := tgt.URL.String() + if tgt.Name != "" { + desc = fmt.Sprintf("%s(%s)", tgt.Name, tgt.URL.String()) + } + c.Logger().Errorf("remote %s unreachable, could not forward: %v", desc, err) + c.Error(echo.NewHTTPError(http.StatusServiceUnavailable)) + } + proxy.Transport = config.Transport + return proxy +} diff --git a/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go b/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go new file mode 100644 index 00000000..9a78929f --- /dev/null +++ b/vendor/github.com/labstack/echo/v4/middleware/proxy_1_11_n.go @@ -0,0 +1,14 @@ +// +build !go1.11 + +package middleware + +import ( + "net/http" + "net/http/httputil" + + "github.com/labstack/echo/v4" +) + +func proxyHTTP(t *ProxyTarget, c echo.Context, config ProxyConfig) http.Handler { + return httputil.NewSingleHostReverseProxy(t.URL) +} diff --git a/vendor/github.com/labstack/echo/middleware/recover.go b/vendor/github.com/labstack/echo/v4/middleware/recover.go index 2a42c5b1..e87aaf32 100644 --- a/vendor/github.com/labstack/echo/middleware/recover.go +++ b/vendor/github.com/labstack/echo/v4/middleware/recover.go @@ -4,7 +4,7 @@ import ( "fmt" "runtime" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( diff --git a/vendor/github.com/labstack/echo/middleware/redirect.go b/vendor/github.com/labstack/echo/v4/middleware/redirect.go index 422263de..30a2e403 100644 --- a/vendor/github.com/labstack/echo/middleware/redirect.go +++ b/vendor/github.com/labstack/echo/v4/middleware/redirect.go @@ -3,7 +3,7 @@ package middleware import ( "net/http" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) // RedirectConfig defines the config for Redirect middleware. diff --git a/vendor/github.com/labstack/echo/middleware/request_id.go b/vendor/github.com/labstack/echo/v4/middleware/request_id.go index f376c296..21f801f3 100644 --- a/vendor/github.com/labstack/echo/middleware/request_id.go +++ b/vendor/github.com/labstack/echo/v4/middleware/request_id.go @@ -1,7 +1,7 @@ package middleware import ( - "github.com/labstack/echo" + "github.com/labstack/echo/v4" "github.com/labstack/gommon/random" ) diff --git a/vendor/github.com/labstack/echo/middleware/rewrite.go b/vendor/github.com/labstack/echo/v4/middleware/rewrite.go index 60a59bec..a64e10bb 100644 --- a/vendor/github.com/labstack/echo/middleware/rewrite.go +++ b/vendor/github.com/labstack/echo/v4/middleware/rewrite.go @@ -4,7 +4,7 @@ import ( "regexp" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( @@ -57,7 +57,8 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc { // Initialize for k, v := range config.Rules { - k = strings.Replace(k, "*", "(\\S*)", -1) + k = strings.Replace(k, "*", "(.*)", -1) + k = k + "$" config.rulesRegex[regexp.MustCompile(k)] = v } @@ -74,9 +75,9 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc { replacer := captureTokens(k, req.URL.Path) if replacer != nil { req.URL.Path = replacer.Replace(v) + break } } - return next(c) } } diff --git a/vendor/github.com/labstack/echo/middleware/secure.go b/vendor/github.com/labstack/echo/v4/middleware/secure.go index 188c0c40..8839c879 100644 --- a/vendor/github.com/labstack/echo/middleware/secure.go +++ b/vendor/github.com/labstack/echo/v4/middleware/secure.go @@ -3,7 +3,7 @@ package middleware import ( "fmt" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( diff --git a/vendor/github.com/labstack/echo/middleware/slash.go b/vendor/github.com/labstack/echo/v4/middleware/slash.go index 9af56caf..61d6e30b 100644 --- a/vendor/github.com/labstack/echo/middleware/slash.go +++ b/vendor/github.com/labstack/echo/v4/middleware/slash.go @@ -1,7 +1,7 @@ package middleware import ( - "github.com/labstack/echo" + "github.com/labstack/echo/v4" ) type ( diff --git a/vendor/github.com/labstack/echo/middleware/static.go b/vendor/github.com/labstack/echo/v4/middleware/static.go index 55485f34..bc2087a7 100644 --- a/vendor/github.com/labstack/echo/middleware/static.go +++ b/vendor/github.com/labstack/echo/v4/middleware/static.go @@ -10,7 +10,7 @@ import ( "path/filepath" "strings" - "github.com/labstack/echo" + "github.com/labstack/echo/v4" "github.com/labstack/gommon/bytes" ) @@ -76,7 +76,7 @@ const html = ` transition: opacity 0.25s; } li span { - color: #707070; + color: #707070; font-size: 12px; } li a:hover { diff --git a/vendor/github.com/labstack/echo/response.go b/vendor/github.com/labstack/echo/v4/response.go index 6244783b..eb2d988d 100644 --- a/vendor/github.com/labstack/echo/response.go +++ b/vendor/github.com/labstack/echo/v4/response.go @@ -91,15 +91,6 @@ func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { return r.Writer.(http.Hijacker).Hijack() } -// CloseNotify implements the http.CloseNotifier interface to allow detecting -// when the underlying connection has gone away. -// This mechanism can be used to cancel long operations on the server if the -// client has disconnected before the response is ready. -// See [http.CloseNotifier](https://golang.org/pkg/net/http/#CloseNotifier) -func (r *Response) CloseNotify() <-chan bool { - return r.Writer.(http.CloseNotifier).CloseNotify() -} - func (r *Response) reset(w http.ResponseWriter) { r.beforeFuncs = nil r.afterFuncs = nil diff --git a/vendor/github.com/labstack/echo/router.go b/vendor/github.com/labstack/echo/v4/router.go index ff53da87..73f0b68b 100644 --- a/vendor/github.com/labstack/echo/router.go +++ b/vendor/github.com/labstack/echo/v4/router.go @@ -1,5 +1,7 @@ package echo +import "net/http" + type ( // Router is the registry of all registered routes for an `Echo` instance for // request matching and URL path parameter parsing. @@ -79,7 +81,7 @@ func (r *Router) Add(method, path string, h HandlerFunc) { r.insert(method, path[:i], h, pkind, ppath, pnames) return } - r.insert(method, path[:i], nil, pkind, ppath, pnames) + r.insert(method, path[:i], nil, pkind, "", nil) } else if path[i] == '*' { r.insert(method, path[:i], nil, skind, "", nil) pnames = append(pnames, "*") @@ -226,50 +228,50 @@ func (n *node) findChildByKind(t kind) *node { func (n *node) addHandler(method string, h HandlerFunc) { switch method { - case CONNECT: + case http.MethodConnect: n.methodHandler.connect = h - case DELETE: + case http.MethodDelete: n.methodHandler.delete = h - case GET: + case http.MethodGet: n.methodHandler.get = h - case HEAD: + case http.MethodHead: n.methodHandler.head = h - case OPTIONS: + case http.MethodOptions: n.methodHandler.options = h - case PATCH: + case http.MethodPatch: n.methodHandler.patch = h - case POST: + case http.MethodPost: n.methodHandler.post = h case PROPFIND: n.methodHandler.propfind = h - case PUT: + case http.MethodPut: n.methodHandler.put = h - case TRACE: + case http.MethodTrace: n.methodHandler.trace = h } } func (n *node) findHandler(method string) HandlerFunc { switch method { - case CONNECT: + case http.MethodConnect: return n.methodHandler.connect - case DELETE: + case http.MethodDelete: return n.methodHandler.delete - case GET: + case http.MethodGet: return n.methodHandler.get - case HEAD: + case http.MethodHead: return n.methodHandler.head - case OPTIONS: + case http.MethodOptions: return n.methodHandler.options - case PATCH: + case http.MethodPatch: return n.methodHandler.patch - case POST: + case http.MethodPost: return n.methodHandler.post case PROPFIND: return n.methodHandler.propfind - case PUT: + case http.MethodPut: return n.methodHandler.put - case TRACE: + case http.MethodTrace: return n.methodHandler.trace default: return nil @@ -311,7 +313,7 @@ func (r *Router) Find(method, path string, c Context) { // Search order static > param > any for { if search == "" { - goto End + break } pl := 0 // Prefix length @@ -346,7 +348,7 @@ func (r *Router) Find(method, path string, c Context) { } if search == "" { - goto End + break } // Static node @@ -403,10 +405,9 @@ func (r *Router) Find(method, path string, c Context) { return } pvalues[len(cn.pnames)-1] = search - goto End + break } -End: ctx.handler = cn.findHandler(method) ctx.path = cn.ppath ctx.pnames = cn.pnames diff --git a/vendor/github.com/labstack/gommon/LICENSE b/vendor/github.com/labstack/gommon/LICENSE index d2ae3edf..fc718faf 100644 --- a/vendor/github.com/labstack/gommon/LICENSE +++ b/vendor/github.com/labstack/gommon/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 labstack +Copyright (c) 2018 labstack Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/labstack/gommon/bytes/bytes.go b/vendor/github.com/labstack/gommon/bytes/bytes.go index fd97e6d1..746436cb 100644 --- a/vendor/github.com/labstack/gommon/bytes/bytes.go +++ b/vendor/github.com/labstack/gommon/bytes/bytes.go @@ -7,12 +7,12 @@ import ( ) type ( - Bytes struct { - } + // Bytes struct + Bytes struct{} ) const ( - B = 1 << (10 * iota) + _ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier KB MB GB @@ -22,7 +22,7 @@ const ( ) var ( - pattern = regexp.MustCompile(`(?i)^(-?\d+)([KMGTP]B?|B)$`) + pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)([KMGTPE]B?|B?)$`) global = New() ) @@ -38,29 +38,31 @@ func (*Bytes) Format(b int64) string { value := float64(b) switch { - case b < KB: - return strconv.FormatInt(b, 10) + "B" - case b < MB: - value /= KB - multiple = "KB" - case b < MB: - value /= KB - multiple = "KB" - case b < GB: - value /= MB - multiple = "MB" - case b < TB: - value /= GB - multiple = "GB" - case b < PB: - value /= TB - multiple = "TB" - case b < EB: + case b >= EB: + value /= EB + multiple = "EB" + case b >= PB: value /= PB multiple = "PB" + case b >= TB: + value /= TB + multiple = "TB" + case b >= GB: + value /= GB + multiple = "GB" + case b >= MB: + value /= MB + multiple = "MB" + case b >= KB: + value /= KB + multiple = "KB" + case b == 0: + return "0" + default: + return strconv.FormatInt(b, 10) + "B" } - return fmt.Sprintf("%.02f%s", value, multiple) + return fmt.Sprintf("%.2f%s", value, multiple) } // Parse parses human readable bytes string to bytes integer. @@ -72,27 +74,27 @@ func (*Bytes) Parse(value string) (i int64, err error) { } bytesString := parts[1] multiple := parts[2] - bytes, err := strconv.ParseInt(bytesString, 10, 64) + bytes, err := strconv.ParseFloat(bytesString, 64) if err != nil { return } switch multiple { - case "B": - return bytes * B, nil + default: + return int64(bytes), nil case "K", "KB": - return bytes * KB, nil + return int64(bytes * KB), nil case "M", "MB": - return bytes * MB, nil + return int64(bytes * MB), nil case "G", "GB": - return bytes * GB, nil + return int64(bytes * GB), nil case "T", "TB": - return bytes * TB, nil + return int64(bytes * TB), nil case "P", "PB": - return bytes * PB, nil + return int64(bytes * PB), nil + case "E", "EB": + return int64(bytes * EB), nil } - - return } // Format wraps global Bytes's Format function. diff --git a/vendor/github.com/labstack/gommon/log/log.go b/vendor/github.com/labstack/gommon/log/log.go index 1ac6c00c..132411db 100644 --- a/vendor/github.com/labstack/gommon/log/log.go +++ b/vendor/github.com/labstack/gommon/log/log.go @@ -8,11 +8,10 @@ import ( "os" "path" "runtime" + "strconv" "sync" "time" - "strconv" - "github.com/mattn/go-isatty" "github.com/valyala/fasttemplate" @@ -23,6 +22,7 @@ type ( Logger struct { prefix string level Lvl + skip int output io.Writer template *fasttemplate.Template levels []string @@ -42,6 +42,8 @@ const ( WARN ERROR OFF + panicLevel + fatalLevel ) var ( @@ -50,9 +52,14 @@ var ( `"file":"${short_file}","line":"${line}"}` ) +func init() { + global.skip = 3 +} + func New(prefix string) (l *Logger) { l = &Logger{ level: INFO, + skip: 2, prefix: prefix, template: l.newTemplate(defaultHeader), color: color.New(), @@ -74,6 +81,9 @@ func (l *Logger) initLevels() { l.color.Green("INFO"), l.color.Yellow("WARN"), l.color.Red("ERROR"), + "", + l.color.Yellow("PANIC", color.U), + l.color.Red("FATAL", color.U), } } @@ -188,32 +198,32 @@ func (l *Logger) Errorj(j JSON) { } func (l *Logger) Fatal(i ...interface{}) { - l.Print(i...) + l.log(fatalLevel, "", i...) os.Exit(1) } func (l *Logger) Fatalf(format string, args ...interface{}) { - l.Printf(format, args...) + l.log(fatalLevel, format, args...) os.Exit(1) } func (l *Logger) Fatalj(j JSON) { - l.Printj(j) + l.log(fatalLevel, "json", j) os.Exit(1) } func (l *Logger) Panic(i ...interface{}) { - l.Print(i...) + l.log(panicLevel, "", i...) panic(fmt.Sprint(i...)) } func (l *Logger) Panicf(format string, args ...interface{}) { - l.Printf(format, args...) - panic(fmt.Sprintf(format, args)) + l.log(panicLevel, format, args...) + panic(fmt.Sprintf(format, args...)) } func (l *Logger) Panicj(j JSON) { - l.Printj(j) + l.log(panicLevel, "json", j) panic(j) } @@ -343,7 +353,7 @@ func (l *Logger) log(v Lvl, format string, args ...interface{}) { buf := l.bufferPool.Get().(*bytes.Buffer) buf.Reset() defer l.bufferPool.Put(buf) - _, file, line, _ := runtime.Caller(3) + _, file, line, _ := runtime.Caller(l.skip) if v >= l.level || v == 0 { message := "" diff --git a/vendor/github.com/labstack/gommon/random/random.go b/vendor/github.com/labstack/gommon/random/random.go index b1ae864a..482d0524 100644 --- a/vendor/github.com/labstack/gommon/random/random.go +++ b/vendor/github.com/labstack/gommon/random/random.go @@ -13,13 +13,13 @@ type ( // Charsets const ( - Uppercase string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - Lowercase = "abcdefghijklmnopqrstuvwxyz" - Alphabetic = Uppercase + Lowercase - Numeric = "0123456789" - Alphanumeric = Alphabetic + Numeric - Symbols = "`" + `~!@#$%^&*()-_+={}[]|\;:"<>,./?` - Hex = Numeric + "abcdef" + Uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + Lowercase = "abcdefghijklmnopqrstuvwxyz" + Alphabetic = Uppercase + Lowercase + Numeric = "0123456789" + Alphanumeric = Alphabetic + Numeric + Symbols = "`" + `~!@#$%^&*()-_+={}[]|\;:"<>,./?` + Hex = Numeric + "abcdef" ) var ( diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml index 42768b8b..98db8f06 100644 --- a/vendor/github.com/mattn/go-colorable/.travis.yml +++ b/vendor/github.com/mattn/go-colorable/.travis.yml @@ -2,7 +2,8 @@ language: go go: - tip -sudo: false - +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover script: - - go test -v + - $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md index e84226a7..56729a92 100644 --- a/vendor/github.com/mattn/go-colorable/README.md +++ b/vendor/github.com/mattn/go-colorable/README.md @@ -1,5 +1,10 @@ # go-colorable +[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) +[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) + Colorable writer for windows. For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go new file mode 100644 index 00000000..1f28d773 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_appengine.go @@ -0,0 +1,29 @@ +// +build appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go index a7fe19a8..887f203d 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ b/vendor/github.com/mattn/go-colorable/colorable_others.go @@ -1,10 +1,13 @@ // +build !windows +// +build !appengine package colorable import ( "io" "os" + + _ "github.com/mattn/go-isatty" ) // NewColorable return new instance of Writer which handle escape sequence. diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go index 628ad904..e17a5474 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -1,3 +1,6 @@ +// +build windows +// +build !appengine + package colorable import ( @@ -65,12 +68,13 @@ var ( procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") + procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") ) +// Writer provide colorable Writer to the console type Writer struct { out io.Writer handle syscall.Handle - lastbuf bytes.Buffer oldattr word oldpos coord } @@ -86,9 +90,8 @@ func NewColorable(file *os.File) io.Writer { handle := syscall.Handle(file.Fd()) procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} - } else { - return file } + return file } // NewColorableStdout return new instance of Writer which handle escape sequence for stdout. @@ -360,6 +363,45 @@ var color256 = map[int]int{ 255: 0xeeeeee, } +// `\033]0;TITLESTR\007` +func doTitleSequence(er *bytes.Reader) error { + var c byte + var err error + + c, err = er.ReadByte() + if err != nil { + return err + } + if c != '0' && c != '2' { + return nil + } + c, err = er.ReadByte() + if err != nil { + return err + } + if c != ';' { + return nil + } + title := make([]byte, 0, 80) + for { + c, err = er.ReadByte() + if err != nil { + return err + } + if c == 0x07 || c == '\n' { + break + } + title = append(title, c) + } + if len(title) > 0 { + title8, err := syscall.UTF16PtrFromString(string(title)) + if err == nil { + procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) + } + } + return nil +} + // Write write data on console func (w *Writer) Write(data []byte) (n int, err error) { var csbi consoleScreenBufferInfo @@ -369,11 +411,6 @@ func (w *Writer) Write(data []byte) (n int, err error) { var bw [1]byte loop: for { - r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - if r1 == 0 { - break loop - } - c1, err := er.ReadByte() if err != nil { break loop @@ -385,12 +422,16 @@ loop: } c2, err := er.ReadByte() if err != nil { - w.lastbuf.WriteByte(c1) break loop } + + if c2 == ']' { + if err := doTitleSequence(er); err != nil { + break loop + } + continue + } if c2 != 0x5b { - w.lastbuf.WriteByte(c1) - w.lastbuf.WriteByte(c2) continue } @@ -399,9 +440,6 @@ loop: for { c, err := er.ReadByte() if err != nil { - w.lastbuf.WriteByte(c1) - w.lastbuf.WriteByte(c2) - w.lastbuf.Write(buf.Bytes()) break loop } if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { @@ -411,7 +449,6 @@ loop: buf.Write([]byte(string(c))) } - var csbi consoleScreenBufferInfo switch m { case 'A': n, err = strconv.Atoi(buf.String()) @@ -435,19 +472,16 @@ loop: continue } procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) + csbi.cursorPosition.x += short(n) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) case 'D': n, err = strconv.Atoi(buf.String()) if err != nil { continue } - if n, err = strconv.Atoi(buf.String()); err == nil { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) case 'E': n, err = strconv.Atoi(buf.String()) if err != nil { @@ -474,58 +508,79 @@ loop: procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) csbi.cursorPosition.x = short(n - 1) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H': - token := strings.Split(buf.String(), ";") - if len(token) != 2 { - continue - } - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue + case 'H', 'f': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + if buf.Len() > 0 { + token := strings.Split(buf.String(), ";") + switch len(token) { + case 1: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + csbi.cursorPosition.y = short(n1 - 1) + case 2: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + n2, err := strconv.Atoi(token[1]) + if err != nil { + continue + } + csbi.cursorPosition.x = short(n2 - 1) + csbi.cursorPosition.y = short(n1 - 1) + } + } else { + csbi.cursorPosition.y = 0 } - csbi.cursorPosition.x = short(n2 - 1) - csbi.cursorPosition.y = short(n1 - 1) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) case 'J': - n, err := strconv.Atoi(buf.String()) - if err != nil { - continue + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + var count, written dword var cursor coord + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) switch n { case 0: cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) case 1: cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x) case 2: cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) } - var count, written dword - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) case 'K': - n, err := strconv.Atoi(buf.String()) - if err != nil { - continue + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } } procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) var cursor coord + var count, written dword switch n { case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x - 1) case 1: cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) case 2: cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x) } - var count, written dword - count = dword(csbi.size.x - csbi.cursorPosition.x) procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) case 'm': @@ -547,7 +602,7 @@ loop: attr |= foregroundIntensity case n == 7: attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 22 == n || n == 25 || n == 25: + case n == 22 || n == 25: attr |= foregroundIntensity case n == 27: attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) @@ -634,17 +689,25 @@ loop: } } case 'h': + var ci consoleCursorInfo cs := buf.String() - if cs == "?25" { - var ci consoleCursorInfo + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) ci.visible = 1 procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) } case 'l': + var ci consoleCursorInfo cs := buf.String() - if cs == "?25" { - var ci consoleCursorInfo + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) ci.visible = 0 procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) @@ -656,7 +719,8 @@ loop: procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) } } - return len(data) - w.lastbuf.Len(), nil + + return len(data), nil } type consoleColor struct { @@ -700,22 +764,22 @@ func (c consoleColor) backgroundAttr() (attr word) { } var color16 = []consoleColor{ - consoleColor{0x000000, false, false, false, false}, - consoleColor{0x000080, false, false, true, false}, - consoleColor{0x008000, false, true, false, false}, - consoleColor{0x008080, false, true, true, false}, - consoleColor{0x800000, true, false, false, false}, - consoleColor{0x800080, true, false, true, false}, - consoleColor{0x808000, true, true, false, false}, - consoleColor{0xc0c0c0, true, true, true, false}, - consoleColor{0x808080, false, false, false, true}, - consoleColor{0x0000ff, false, false, true, true}, - consoleColor{0x00ff00, false, true, false, true}, - consoleColor{0x00ffff, false, true, true, true}, - consoleColor{0xff0000, true, false, false, true}, - consoleColor{0xff00ff, true, false, true, true}, - consoleColor{0xffff00, true, true, false, true}, - consoleColor{0xffffff, true, true, true, true}, + {0x000000, false, false, false, false}, + {0x000080, false, false, true, false}, + {0x008000, false, true, false, false}, + {0x008080, false, true, true, false}, + {0x800000, true, false, false, false}, + {0x800080, true, false, true, false}, + {0x808000, true, true, false, false}, + {0xc0c0c0, true, true, true, false}, + {0x808080, false, false, false, true}, + {0x0000ff, false, false, true, true}, + {0x00ff00, false, true, false, true}, + {0x00ffff, false, true, true, true}, + {0xff0000, true, false, false, true}, + {0xff00ff, true, false, true, true}, + {0xffff00, true, true, false, true}, + {0xffffff, true, true, true, true}, } type hsv struct { diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go index ca588c78..9721e16f 100644 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -7,8 +7,7 @@ import ( // NonColorable hold writer but remove escape sequence. type NonColorable struct { - out io.Writer - lastbuf bytes.Buffer + out io.Writer } // NewNonColorable return new instance of Writer which remove escape sequence from Writer. @@ -33,12 +32,9 @@ loop: } c2, err := er.ReadByte() if err != nil { - w.lastbuf.WriteByte(c1) break loop } if c2 != 0x5b { - w.lastbuf.WriteByte(c1) - w.lastbuf.WriteByte(c2) continue } @@ -46,9 +42,6 @@ loop: for { c, err := er.ReadByte() if err != nil { - w.lastbuf.WriteByte(c1) - w.lastbuf.WriteByte(c2) - w.lastbuf.Write(buf.Bytes()) break loop } if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { @@ -57,5 +50,6 @@ loop: buf.Write([]byte(string(c))) } } - return len(data) - w.lastbuf.Len(), nil + + return len(data), nil } diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml index b8111d67..5597e026 100644 --- a/vendor/github.com/mattn/go-isatty/.travis.yml +++ b/vendor/github.com/mattn/go-isatty/.travis.yml @@ -1,8 +1,13 @@ language: go go: - tip + +os: + - linux + - osx + before_install: - go get github.com/mattn/goveralls - go get golang.org/x/tools/cmd/cover script: - - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 + - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 diff --git a/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md index 8e4365f4..1e69004b 100644 --- a/vendor/github.com/mattn/go-isatty/README.md +++ b/vendor/github.com/mattn/go-isatty/README.md @@ -1,6 +1,9 @@ # go-isatty -[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) [![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) +[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) isatty for golang diff --git a/vendor/github.com/mattn/go-isatty/isatty_appengine.go b/vendor/github.com/mattn/go-isatty/isatty_appengine.go index 83c58877..9584a988 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_appengine.go +++ b/vendor/github.com/mattn/go-isatty/isatty_appengine.go @@ -7,3 +7,9 @@ package isatty func IsTerminal(fd uintptr) bool { return false } + +// 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_linux.go b/vendor/github.com/mattn/go-isatty/isatty_linux.go index 9d24bac1..7384cf99 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_linux.go +++ b/vendor/github.com/mattn/go-isatty/isatty_linux.go @@ -1,5 +1,5 @@ // +build linux -// +build !appengine +// +build !appengine,!ppc64,!ppc64le package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go new file mode 100644 index 00000000..44e5d213 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go @@ -0,0 +1,19 @@ +// +build linux +// +build ppc64 ppc64le + +package isatty + +import ( + "unsafe" + + syscall "golang.org/x/sys/unix" +) + +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 +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 616832d2..9d8b4a59 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,8 +1,9 @@ -// +build !windows appengine +// +build !windows +// +build !appengine package isatty -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// 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/nlopes/slack/.gometalinter.json b/vendor/github.com/nlopes/slack/.gometalinter.json new file mode 100644 index 00000000..5fa629d4 --- /dev/null +++ b/vendor/github.com/nlopes/slack/.gometalinter.json @@ -0,0 +1,14 @@ +{ + "DisableAll": true, + "Enable": [ + "structcheck", + "vet", + "misspell", + "unconvert", + "interfacer", + "goimports" + ], + "Vendor": true, + "Exclude": ["vendor"], + "Deadline": "300s" +} diff --git a/vendor/github.com/nlopes/slack/.travis.yml b/vendor/github.com/nlopes/slack/.travis.yml index b0615288..e4b9c754 100644 --- a/vendor/github.com/nlopes/slack/.travis.yml +++ b/vendor/github.com/nlopes/slack/.travis.yml @@ -1,23 +1,25 @@ language: go go: - - 1.7.x - - 1.8.x - - 1.9.x - - 1.10.x - - 1.11.x - - tip + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x + - tip before_install: - export PATH=$HOME/gopath/bin:$PATH + # install gometalinter + - curl -L https://git.io/vp6lP | sh script: - - go test -race ./... - - go test -cover ./... + - PATH=$PWD/bin:$PATH gometalinter ./... + - go test -race -cover ./... matrix: - allow_failures: - - go: tip + allow_failures: + - go: tip git: depth: 10 diff --git a/vendor/github.com/nlopes/slack/CHANGELOG.md b/vendor/github.com/nlopes/slack/CHANGELOG.md index cf0fc2cc..63309f23 100644 --- a/vendor/github.com/nlopes/slack/CHANGELOG.md +++ b/vendor/github.com/nlopes/slack/CHANGELOG.md @@ -1,3 +1,8 @@ +### v0.5.0 - January 20, 2019
+full differences can be viewed using `git log --oneline --decorate --color v0.4.0..v0.5.0`
+- Breaking changes: various old struct fields have been removed or updated to match slack's api.
+- deadlock fix in RTM disconnect.
+
### v0.4.0 - October 06, 2018
full differences can be viewed using `git log --oneline --decorate --color v0.3.0..v0.4.0`
- Breaking Change: renamed ApplyMessageOption, to mark it as unsafe,
diff --git a/vendor/github.com/nlopes/slack/README.md b/vendor/github.com/nlopes/slack/README.md index 849e8bdc..b4148231 100644 --- a/vendor/github.com/nlopes/slack/README.md +++ b/vendor/github.com/nlopes/slack/README.md @@ -9,18 +9,10 @@ a fully managed way. -## Change log -Support for the EventsAPI has recently been added. It is still in its early stages but nearly all events have been added and tested (except for those events in [Developer Preview](https://api.slack.com/slack-apps-preview) mode). API stability for events is not promised at this time. -### v0.2.0 - Feb 10, 2018 +## Changelog -Release adds a bunch of functionality and improvements, mainly to give people a recent version to vendor against. - -Please check [0.2.0](https://github.com/nlopes/slack/releases/tag/v0.2.0) - -### CHANGELOG.md - - [CHANGELOG.md](https://github.com/nlopes/slack/blob/master/CHANGELOG.md) is available. Please visit it for updates. +[CHANGELOG.md](https://github.com/nlopes/slack/blob/master/CHANGELOG.md) is available. Please visit it for updates. ## Installing diff --git a/vendor/github.com/nlopes/slack/channels.go b/vendor/github.com/nlopes/slack/channels.go index 007985bc..711ae7c5 100644 --- a/vendor/github.com/nlopes/slack/channels.go +++ b/vendor/github.com/nlopes/slack/channels.go @@ -38,6 +38,29 @@ func channelRequest(ctx context.Context, client httpClient, path string, values return response, nil } +type channelsConfig struct { + values url.Values +} + +// GetChannelsOption option provided when getting channels. +type GetChannelsOption func(*channelsConfig) error + +// GetChannelsOptionExcludeMembers excludes the members collection from each channel. +func GetChannelsOptionExcludeMembers() GetChannelsOption { + return func(config *channelsConfig) error { + config.values.Add("exclude_members", "true") + return nil + } +} + +// GetChannelsOptionExcludeArchived excludes archived channels from results. +func GetChannelsOptionExcludeArchived() GetChannelsOption { + return func(config *channelsConfig) error { + config.values.Add("exclude_archived", "true") + return nil + } +} + // ArchiveChannel archives the given channel // see https://api.slack.com/methods/channels.archive func (api *Client) ArchiveChannel(channelID string) error { @@ -150,8 +173,9 @@ func (api *Client) GetChannelInfo(channelID string) (*Channel, error) { // see https://api.slack.com/methods/channels.info func (api *Client) GetChannelInfoContext(ctx context.Context, channelID string) (*Channel, error) { values := url.Values{ - "token": {api.token}, - "channel": {channelID}, + "token": {api.token}, + "channel": {channelID}, + "include_locale": {strconv.FormatBool(true)}, } response, err := channelRequest(ctx, api.httpclient, "channels.info", values, api) @@ -247,21 +271,29 @@ func (api *Client) KickUserFromChannelContext(ctx context.Context, channelID, us // GetChannels retrieves all the channels // see https://api.slack.com/methods/channels.list -func (api *Client) GetChannels(excludeArchived bool) ([]Channel, error) { - return api.GetChannelsContext(context.Background(), excludeArchived) +func (api *Client) GetChannels(excludeArchived bool, options ...GetChannelsOption) ([]Channel, error) { + return api.GetChannelsContext(context.Background(), excludeArchived, options...) } // GetChannelsContext retrieves all the channels with a custom context // see https://api.slack.com/methods/channels.list -func (api *Client) GetChannelsContext(ctx context.Context, excludeArchived bool) ([]Channel, error) { - values := url.Values{ - "token": {api.token}, +func (api *Client) GetChannelsContext(ctx context.Context, excludeArchived bool, options ...GetChannelsOption) ([]Channel, error) { + config := channelsConfig{ + values: url.Values{ + "token": {api.token}, + }, } if excludeArchived { - values.Add("exclude_archived", "1") + options = append(options, GetChannelsOptionExcludeArchived()) + } + + for _, opt := range options { + if err := opt(&config); err != nil { + return nil, err + } } - response, err := channelRequest(ctx, api.httpclient, "channels.list", values, api) + response, err := channelRequest(ctx, api.httpclient, "channels.list", config.values, api) if err != nil { return nil, err } diff --git a/vendor/github.com/nlopes/slack/chat.go b/vendor/github.com/nlopes/slack/chat.go index eb8fd6c8..c08c1808 100644 --- a/vendor/github.com/nlopes/slack/chat.go +++ b/vendor/github.com/nlopes/slack/chat.go @@ -43,19 +43,18 @@ func (c chatResponseFull) getMessageTimestamp() string { // PostMessageParameters contains all the parameters necessary (including the optional ones) for a PostMessage() request type PostMessageParameters struct { - Username string `json:"username"` - AsUser bool `json:"as_user"` - Parse string `json:"parse"` - ThreadTimestamp string `json:"thread_ts"` - ReplyBroadcast bool `json:"reply_broadcast"` - LinkNames int `json:"link_names"` - Attachments []Attachment `json:"attachments"` - UnfurlLinks bool `json:"unfurl_links"` - UnfurlMedia bool `json:"unfurl_media"` - IconURL string `json:"icon_url"` - IconEmoji string `json:"icon_emoji"` - Markdown bool `json:"mrkdwn,omitempty"` - EscapeText bool `json:"escape_text"` + Username string `json:"username"` + AsUser bool `json:"as_user"` + Parse string `json:"parse"` + ThreadTimestamp string `json:"thread_ts"` + ReplyBroadcast bool `json:"reply_broadcast"` + LinkNames int `json:"link_names"` + UnfurlLinks bool `json:"unfurl_links"` + UnfurlMedia bool `json:"unfurl_media"` + IconURL string `json:"icon_url"` + IconEmoji string `json:"icon_emoji"` + Markdown bool `json:"mrkdwn,omitempty"` + EscapeText bool `json:"escape_text"` // chat.postEphemeral support Channel string `json:"channel"` @@ -71,7 +70,6 @@ func NewPostMessageParameters() PostMessageParameters { Parse: DEFAULT_MESSAGE_PARSE, ThreadTimestamp: DEFAULT_MESSAGE_THREAD_TIMESTAMP, LinkNames: DEFAULT_MESSAGE_LINK_NAMES, - Attachments: nil, UnfurlLinks: DEFAULT_MESSAGE_UNFURL_LINKS, UnfurlMedia: DEFAULT_MESSAGE_UNFURL_MEDIA, IconURL: DEFAULT_MESSAGE_ICON_URL, diff --git a/vendor/github.com/nlopes/slack/dialog.go b/vendor/github.com/nlopes/slack/dialog.go index 2e45a06c..7b9e3814 100644 --- a/vendor/github.com/nlopes/slack/dialog.go +++ b/vendor/github.com/nlopes/slack/dialog.go @@ -14,7 +14,7 @@ const ( InputTypeText InputType = "text" // InputTypeTextArea textarea input InputTypeTextArea InputType = "textarea" - // InputTypeSelect textfield input + // InputTypeSelect select menus input InputTypeSelect InputType = "select" ) @@ -68,6 +68,17 @@ type DialogResponseMetadata struct { Messages []string `json:"messages"` } +// DialogInputValidationError is an error when user inputs incorrect value to form from within a dialog +type DialogInputValidationError struct { + Name string `json:"name"` + Error string `json:"error"` +} + +// DialogInputValidationErrors lists the name of field and that error messages +type DialogInputValidationErrors struct { + Errors []DialogInputValidationError `json:"errors"` +} + // OpenDialog opens a dialog window where the triggerID originated from. // EXPERIMENTAL: dialog functionality is currently experimental, api is not considered stable. func (api *Client) OpenDialog(triggerID string, dialog Dialog) (err error) { diff --git a/vendor/github.com/nlopes/slack/files.go b/vendor/github.com/nlopes/slack/files.go index 13158582..136ea266 100644 --- a/vendor/github.com/nlopes/slack/files.go +++ b/vendor/github.com/nlopes/slack/files.go @@ -3,6 +3,7 @@ package slack import ( "context" "errors" + "fmt" "io" "net/url" "strconv" @@ -86,12 +87,30 @@ type File struct { CommentsCount int `json:"comments_count"` NumStars int `json:"num_stars"` IsStarred bool `json:"is_starred"` + Shares Share `json:"shares"` +} + +type Share struct { + Public map[string][]ShareFileInfo `json:"public"` +} + +type ShareFileInfo struct { + ReplyUsers []string `json:"reply_users"` + ReplyUsersCount int `json:"reply_users_count"` + ReplyCount int `json:"reply_count"` + Ts string `json:"ts"` + ThreadTs string `json:"thread_ts"` + LatestReply string `json:"latest_reply"` + ChannelName string `json:"channel_name"` + TeamID string `json:"team_id"` } // FileUploadParameters contains all the parameters necessary (including the optional ones) for an UploadFile() request. // // There are three ways to upload a file. You can either set Content if file is small, set Reader if file is large, // or provide a local file path in File to upload it from your filesystem. +// +// Note that when using the Reader option, you *must* specify the Filename, otherwise the Slack API isn't happy. type FileUploadParameters struct { File string Content string @@ -220,6 +239,9 @@ func (api *Client) UploadFileContext(ctx context.Context, params FileUploadParam if err != nil { return nil, err } + if params.Filename == "" { + return nil, fmt.Errorf("files.upload: FileUploadParameters.Filename is mandatory") + } response := &fileResponseFull{} values := url.Values{ "token": {api.token}, diff --git a/vendor/github.com/nlopes/slack/groups.go b/vendor/github.com/nlopes/slack/groups.go index a248f6fd..560faee9 100644 --- a/vendor/github.com/nlopes/slack/groups.go +++ b/vendor/github.com/nlopes/slack/groups.go @@ -113,25 +113,6 @@ func (api *Client) CreateChildGroupContext(ctx context.Context, group string) (* return &response.Group, nil } -// CloseGroup closes a private group -func (api *Client) CloseGroup(group string) (bool, bool, error) { - return api.CloseGroupContext(context.Background(), group) -} - -// CloseGroupContext closes a private group with a custom context -func (api *Client) CloseGroupContext(ctx context.Context, group string) (bool, bool, error) { - values := url.Values{ - "token": {api.token}, - "channel": {group}, - } - - response, err := imRequest(ctx, api.httpclient, "groups.close", values, api) - if err != nil { - return false, false, err - } - return response.NoOp, response.AlreadyClosed, nil -} - // GetGroupHistory fetches all the history for a private group func (api *Client) GetGroupHistory(group string, params HistoryParameters) (*History, error) { return api.GetGroupHistoryContext(context.Background(), group, params) @@ -256,8 +237,9 @@ func (api *Client) GetGroupInfo(group string) (*Group, error) { // GetGroupInfoContext retrieves the given group with a custom context func (api *Client) GetGroupInfoContext(ctx context.Context, group string) (*Group, error) { values := url.Values{ - "token": {api.token}, - "channel": {group}, + "token": {api.token}, + "channel": {group}, + "include_locale": {strconv.FormatBool(true)}, } response, err := groupRequest(ctx, api.httpclient, "groups.info", values, api) diff --git a/vendor/github.com/nlopes/slack/interactions.go b/vendor/github.com/nlopes/slack/interactions.go index 97e31a49..addc2864 100644 --- a/vendor/github.com/nlopes/slack/interactions.go +++ b/vendor/github.com/nlopes/slack/interactions.go @@ -5,6 +5,7 @@ type InteractionType string // Types of interactions that can be received. const ( + InteractionTypeDialogCancellation = InteractionType("dialog_cancellation") InteractionTypeDialogSubmission = InteractionType("dialog_submission") InteractionTypeDialogSuggestion = InteractionType("dialog_suggestion") InteractionTypeInteractionMessage = InteractionType("interactive_message") diff --git a/vendor/github.com/nlopes/slack/reminders.go b/vendor/github.com/nlopes/slack/reminders.go new file mode 100644 index 00000000..54c91789 --- /dev/null +++ b/vendor/github.com/nlopes/slack/reminders.go @@ -0,0 +1,75 @@ +package slack + +import ( + "context" + "net/url" + "time" +) + +type Reminder struct { + ID string `json:"id"` + Creator string `json:"creator"` + User string `json:"user"` + Text string `json:"text"` + Recurring bool `json:"recurring"` + Time time.Time `json:"time"` + CompleteTS int `json:"complete_ts"` +} + +type reminderResp struct { + SlackResponse + Reminder Reminder `json:"reminder"` +} + +func (api *Client) doReminder(ctx context.Context, path string, values url.Values) (*Reminder, error) { + response := &reminderResp{} + if err := postSlackMethod(ctx, api.httpclient, path, values, response, api); err != nil { + return nil, err + } + return &response.Reminder, response.Err() +} + +// AddChannelReminder adds a reminder for a channel. +// +// See https://api.slack.com/methods/reminders.add (NOTE: the ability to set +// reminders on a channel is currently undocumented but has been tested to +// work) +func (api *Client) AddChannelReminder(channelID, text, time string) (*Reminder, error) { + values := url.Values{ + "token": {api.token}, + "text": {text}, + "time": {time}, + "channel": {channelID}, + } + return api.doReminder(context.Background(), "reminders.add", values) +} + +// AddUserReminder adds a reminder for a user. +// +// See https://api.slack.com/methods/reminders.add (NOTE: the ability to set +// reminders on a channel is currently undocumented but has been tested to +// work) +func (api *Client) AddUserReminder(userID, text, time string) (*Reminder, error) { + values := url.Values{ + "token": {api.token}, + "text": {text}, + "time": {time}, + "user": {userID}, + } + return api.doReminder(context.Background(), "reminders.add", values) +} + +// DeleteReminder deletes an existing reminder. +// +// See https://api.slack.com/methods/reminders.delete +func (api *Client) DeleteReminder(id string) error { + values := url.Values{ + "token": {api.token}, + "reminder": {id}, + } + response := &SlackResponse{} + if err := postSlackMethod(context.Background(), api.httpclient, "reminders.delete", values, response, api); err != nil { + return err + } + return response.Err() +} diff --git a/vendor/github.com/nlopes/slack/security.go b/vendor/github.com/nlopes/slack/security.go index 6ab3c698..35727027 100644 --- a/vendor/github.com/nlopes/slack/security.go +++ b/vendor/github.com/nlopes/slack/security.go @@ -42,7 +42,9 @@ func unsafeSignatureVerifier(header http.Header, secret string) (_ SecretsVerifi } hash := hmac.New(sha256.New, []byte(secret)) - hash.Write([]byte(fmt.Sprintf("v0:%s:", stimestamp))) + if _, err = hash.Write([]byte(fmt.Sprintf("v0:%s:", stimestamp))); err != nil { + return SecretsVerifier{}, err + } return SecretsVerifier{ signature: bsignature, @@ -66,7 +68,7 @@ func NewSecretsVerifier(header http.Header, secret string) (sv SecretsVerifier, return SecretsVerifier{}, err } - diff := absDuration(time.Now().Sub(time.Unix(timestamp, 0))) + diff := absDuration(time.Since(time.Unix(timestamp, 0))) if diff > 5*time.Minute { return SecretsVerifier{}, fmt.Errorf("timestamp is too old") } diff --git a/vendor/github.com/nlopes/slack/slack.go b/vendor/github.com/nlopes/slack/slack.go index 1e75142d..c1ba0fc3 100644 --- a/vendor/github.com/nlopes/slack/slack.go +++ b/vendor/github.com/nlopes/slack/slack.go @@ -9,7 +9,7 @@ import ( "os" ) -// APIURL a dded as a var so that we can change this for testing purposes +// APIURL added as a var so that we can change this for testing purposes var APIURL = "https://slack.com/api/" // WEBAPIURLFormat ... @@ -50,7 +50,6 @@ type authTestResponseFull struct { // Client for the slack api. type Client struct { token string - info Info debug bool log ilogger httpclient httpClient diff --git a/vendor/github.com/nlopes/slack/users.go b/vendor/github.com/nlopes/slack/users.go index aa941a74..74b79372 100644 --- a/vendor/github.com/nlopes/slack/users.go +++ b/vendor/github.com/nlopes/slack/users.go @@ -226,8 +226,9 @@ func (api *Client) GetUserInfo(user string) (*User, error) { // GetUserInfoContext will retrieve the complete user information with a custom context func (api *Client) GetUserInfoContext(ctx context.Context, user string) (*User, error) { values := url.Values{ - "token": {api.token}, - "user": {user}, + "token": {api.token}, + "user": {user}, + "include_locale": {strconv.FormatBool(true)}, } response, err := userRequest(ctx, api.httpclient, "users.info", values, api) @@ -302,10 +303,11 @@ func (t UserPagination) Next(ctx context.Context) (_ UserPagination, err error) t.previousResp = t.previousResp.initialize() values := url.Values{ - "limit": {strconv.Itoa(t.limit)}, - "presence": {strconv.FormatBool(t.presence)}, - "token": {t.c.token}, - "cursor": {t.previousResp.Cursor}, + "limit": {strconv.Itoa(t.limit)}, + "presence": {strconv.FormatBool(t.presence)}, + "token": {t.c.token}, + "cursor": {t.previousResp.Cursor}, + "include_locale": {strconv.FormatBool(true)}, } if resp, err = userRequest(ctx, t.c.httpclient, "users.list", values, t.c); err != nil { diff --git a/vendor/github.com/nlopes/slack/websocket.go b/vendor/github.com/nlopes/slack/websocket.go index ec810a9b..e5dee68a 100644 --- a/vendor/github.com/nlopes/slack/websocket.go +++ b/vendor/github.com/nlopes/slack/websocket.go @@ -39,8 +39,6 @@ type RTM struct { wasIntentional bool isConnected bool - websocketURL string - // UserDetails upon connection info *Info @@ -103,7 +101,7 @@ func (rtm *RTM) SendMessage(msg *OutgoingMessage) { } func (rtm *RTM) resetDeadman() { - timerReset(rtm.pingDeadman, deadmanDuration(rtm.pingInterval)) + rtm.pingDeadman.Reset(deadmanDuration(rtm.pingInterval)) } func deadmanDuration(d time.Duration) time.Duration { diff --git a/vendor/github.com/peterhellberg/emojilib/.travis.yml b/vendor/github.com/peterhellberg/emojilib/.travis.yml index 99c59c46..37eff7f6 100644 --- a/vendor/github.com/peterhellberg/emojilib/.travis.yml +++ b/vendor/github.com/peterhellberg/emojilib/.travis.yml @@ -1,11 +1,10 @@ language: go -go: - - "1.10.3" - - "1.9.7" +dist: xenial -sudo: false +go: + - "1.11.5" + - "1.10.8" script: - - go vet ./... - go test ./... diff --git a/vendor/github.com/peterhellberg/emojilib/LICENSE b/vendor/github.com/peterhellberg/emojilib/LICENSE index e1df4843..e6fda0c7 100644 --- a/vendor/github.com/peterhellberg/emojilib/LICENSE +++ b/vendor/github.com/peterhellberg/emojilib/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2018 Peter Hellberg https://c7.se/ +Copyright (c) 2015-2019 Peter Hellberg https://c7.se Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/vendor/github.com/peterhellberg/emojilib/README.md b/vendor/github.com/peterhellberg/emojilib/README.md index 2a8ab690..cbd12937 100644 --- a/vendor/github.com/peterhellberg/emojilib/README.md +++ b/vendor/github.com/peterhellberg/emojilib/README.md @@ -39,7 +39,7 @@ _You’ll need to have the [golang.org/x/tools/imports](https://golang.org/x/too ## License (MIT) -Copyright (c) 2015-2018 [Peter Hellberg](http://c7.se/) +Copyright (c) 2015-2019 [Peter Hellberg](https://c7.se) > Permission is hereby granted, free of charge, to any person obtaining > a copy of this software and associated documentation files (the diff --git a/vendor/github.com/shazow/ssh-chat/internal/sanitize/sanitize.go b/vendor/github.com/shazow/ssh-chat/internal/sanitize/sanitize.go new file mode 100644 index 00000000..ed532c97 --- /dev/null +++ b/vendor/github.com/shazow/ssh-chat/internal/sanitize/sanitize.go @@ -0,0 +1,28 @@ +package sanitize + +import "regexp" + +var reStripName = regexp.MustCompile("[^\\w.-]") + +const maxLength = 16 + +// Name returns a name with only allowed characters and a reasonable length +func Name(s string) string { + s = reStripName.ReplaceAllString(s, "") + nameLength := maxLength + if len(s) <= maxLength { + nameLength = len(s) + } + s = s[:nameLength] + return s +} + +var reStripData = regexp.MustCompile("[^[:ascii:]]|[[:cntrl:]]") + +// Data returns a string with only allowed characters for client-provided metadata inputs. +func Data(s string, maxlen int) string { + if len(s) > maxlen { + s = s[:maxlen] + } + return reStripData.ReplaceAllString(s, "") +} diff --git a/vendor/github.com/shazow/ssh-chat/sshd/auth.go b/vendor/github.com/shazow/ssh-chat/sshd/auth.go index 2fc86fa8..afa7271a 100644 --- a/vendor/github.com/shazow/ssh-chat/sshd/auth.go +++ b/vendor/github.com/shazow/ssh-chat/sshd/auth.go @@ -6,6 +6,7 @@ import ( "errors" "net" + "github.com/shazow/ssh-chat/internal/sanitize" "golang.org/x/crypto/ssh" ) @@ -13,8 +14,8 @@ import ( type Auth interface { // Whether to allow connections without a public key. AllowAnonymous() bool - // Given address and public key, return if the connection should be permitted. - Check(net.Addr, ssh.PublicKey) (bool, error) + // Given address and public key and client agent string, returns nil if the connection should be allowed. + Check(net.Addr, ssh.PublicKey, string) error } // MakeAuth makes an ssh.ServerConfig which performs authentication against an Auth implementation. @@ -23,8 +24,8 @@ func MakeAuth(auth Auth) *ssh.ServerConfig { NoClientAuth: false, // Auth-related things should be constant-time to avoid timing attacks. PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - ok, err := auth.Check(conn.RemoteAddr(), key) - if !ok { + err := auth.Check(conn.RemoteAddr(), key, sanitize.Data(string(conn.ClientVersion()), 64)) + if err != nil { return nil, err } perm := &ssh.Permissions{Extensions: map[string]string{ @@ -36,7 +37,7 @@ func MakeAuth(auth Auth) *ssh.ServerConfig { if !auth.AllowAnonymous() { return nil, errors.New("public key authentication required") } - _, err := auth.Check(conn.RemoteAddr(), nil) + err := auth.Check(conn.RemoteAddr(), nil, sanitize.Data(string(conn.ClientVersion()), 64)) return nil, err }, } diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml index 1f953beb..a8f15451 100644 --- a/vendor/github.com/sirupsen/logrus/.travis.yml +++ b/vendor/github.com/sirupsen/logrus/.travis.yml @@ -1,4 +1,5 @@ language: go +go_import_path: github.com/sirupsen/logrus env: - GOMAXPROCS=4 GORACE=halt_on_error=1 matrix: diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index 093bb13f..39873105 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -361,6 +361,7 @@ The built-in logging formatters are: Third party logging formatters: * [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine. +* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html). * [`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̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index cc85d3aa..df6d188d 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -108,23 +108,34 @@ func (entry *Entry) WithFields(fields Fields) *Entry { for k, v := range entry.Data { data[k] = v } - var field_err string + fieldErr := entry.err for k, v := range fields { - if t := reflect.TypeOf(v); t != nil && t.Kind() == reflect.Func { - field_err = fmt.Sprintf("can not add field %q", k) - if entry.err != "" { - field_err = entry.err + ", " + field_err + isErrField := false + if t := reflect.TypeOf(v); t != nil { + switch t.Kind() { + case reflect.Func: + isErrField = true + case reflect.Ptr: + isErrField = t.Elem().Kind() == reflect.Func + } + } + if isErrField { + tmp := fmt.Sprintf("can not add field %q", k) + if fieldErr != "" { + fieldErr = entry.err + ", " + tmp + } else { + fieldErr = tmp } } else { data[k] = v } } - return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: field_err} + return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr} } // Overrides the time of the Entry. func (entry *Entry) WithTime(t time.Time) *Entry { - return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t} + return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err} } // getPackageName reduces a fully qualified function name to the package name @@ -240,16 +251,18 @@ func (entry *Entry) write() { } } -func (entry *Entry) Trace(args ...interface{}) { - if entry.Logger.IsLevelEnabled(TraceLevel) { - entry.log(TraceLevel, fmt.Sprint(args...)) +func (entry *Entry) Log(level Level, args ...interface{}) { + if entry.Logger.IsLevelEnabled(level) { + entry.log(level, fmt.Sprint(args...)) } } +func (entry *Entry) Trace(args ...interface{}) { + entry.Log(TraceLevel, args...) +} + func (entry *Entry) Debug(args ...interface{}) { - if entry.Logger.IsLevelEnabled(DebugLevel) { - entry.log(DebugLevel, fmt.Sprint(args...)) - } + entry.Log(DebugLevel, args...) } func (entry *Entry) Print(args ...interface{}) { @@ -257,15 +270,11 @@ func (entry *Entry) Print(args ...interface{}) { } func (entry *Entry) Info(args ...interface{}) { - if entry.Logger.IsLevelEnabled(InfoLevel) { - entry.log(InfoLevel, fmt.Sprint(args...)) - } + entry.Log(InfoLevel, args...) } func (entry *Entry) Warn(args ...interface{}) { - if entry.Logger.IsLevelEnabled(WarnLevel) { - entry.log(WarnLevel, fmt.Sprint(args...)) - } + entry.Log(WarnLevel, args...) } func (entry *Entry) Warning(args ...interface{}) { @@ -273,43 +282,35 @@ func (entry *Entry) Warning(args ...interface{}) { } func (entry *Entry) Error(args ...interface{}) { - if entry.Logger.IsLevelEnabled(ErrorLevel) { - entry.log(ErrorLevel, fmt.Sprint(args...)) - } + entry.Log(ErrorLevel, args...) } func (entry *Entry) Fatal(args ...interface{}) { - if entry.Logger.IsLevelEnabled(FatalLevel) { - entry.log(FatalLevel, fmt.Sprint(args...)) - } + entry.Log(FatalLevel, args...) entry.Logger.Exit(1) } func (entry *Entry) Panic(args ...interface{}) { - if entry.Logger.IsLevelEnabled(PanicLevel) { - entry.log(PanicLevel, fmt.Sprint(args...)) - } + entry.Log(PanicLevel, args...) panic(fmt.Sprint(args...)) } // Entry Printf family functions +func (entry *Entry) Logf(level Level, format string, args ...interface{}) { + entry.Log(level, fmt.Sprintf(format, args...)) +} + func (entry *Entry) Tracef(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(TraceLevel) { - entry.Trace(fmt.Sprintf(format, args...)) - } + entry.Logf(TraceLevel, format, args...) } func (entry *Entry) Debugf(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(DebugLevel) { - entry.Debug(fmt.Sprintf(format, args...)) - } + entry.Logf(DebugLevel, format, args...) } func (entry *Entry) Infof(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(InfoLevel) { - entry.Info(fmt.Sprintf(format, args...)) - } + entry.Logf(InfoLevel, format, args...) } func (entry *Entry) Printf(format string, args ...interface{}) { @@ -317,9 +318,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) { } func (entry *Entry) Warnf(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(WarnLevel) { - entry.Warn(fmt.Sprintf(format, args...)) - } + entry.Logf(WarnLevel, format, args...) } func (entry *Entry) Warningf(format string, args ...interface{}) { @@ -327,42 +326,36 @@ func (entry *Entry) Warningf(format string, args ...interface{}) { } func (entry *Entry) Errorf(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(ErrorLevel) { - entry.Error(fmt.Sprintf(format, args...)) - } + entry.Logf(ErrorLevel, format, args...) } func (entry *Entry) Fatalf(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(FatalLevel) { - entry.Fatal(fmt.Sprintf(format, args...)) - } + entry.Logf(FatalLevel, format, args...) entry.Logger.Exit(1) } func (entry *Entry) Panicf(format string, args ...interface{}) { - if entry.Logger.IsLevelEnabled(PanicLevel) { - entry.Panic(fmt.Sprintf(format, args...)) - } + entry.Logf(PanicLevel, format, args...) } // Entry Println family functions -func (entry *Entry) Traceln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(TraceLevel) { - entry.Trace(entry.sprintlnn(args...)) +func (entry *Entry) Logln(level Level, args ...interface{}) { + if entry.Logger.IsLevelEnabled(level) { + entry.Log(level, entry.sprintlnn(args...)) } } +func (entry *Entry) Traceln(args ...interface{}) { + entry.Logln(TraceLevel, args...) +} + func (entry *Entry) Debugln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(DebugLevel) { - entry.Debug(entry.sprintlnn(args...)) - } + entry.Logln(DebugLevel, args...) } func (entry *Entry) Infoln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(InfoLevel) { - entry.Info(entry.sprintlnn(args...)) - } + entry.Logln(InfoLevel, args...) } func (entry *Entry) Println(args ...interface{}) { @@ -370,9 +363,7 @@ func (entry *Entry) Println(args ...interface{}) { } func (entry *Entry) Warnln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(WarnLevel) { - entry.Warn(entry.sprintlnn(args...)) - } + entry.Logln(WarnLevel, args...) } func (entry *Entry) Warningln(args ...interface{}) { @@ -380,22 +371,16 @@ func (entry *Entry) Warningln(args ...interface{}) { } func (entry *Entry) Errorln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(ErrorLevel) { - entry.Error(entry.sprintlnn(args...)) - } + entry.Logln(ErrorLevel, args...) } func (entry *Entry) Fatalln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(FatalLevel) { - entry.Fatal(entry.sprintlnn(args...)) - } + entry.Logln(FatalLevel, args...) entry.Logger.Exit(1) } func (entry *Entry) Panicln(args ...interface{}) { - if entry.Logger.IsLevelEnabled(PanicLevel) { - entry.Panic(entry.sprintlnn(args...)) - } + entry.Logln(PanicLevel, args...) } // Sprintlnn => Sprint no newline. This is to get the behavior of how diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index 5ceca0ea..9bf64e22 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -131,28 +131,24 @@ func (logger *Logger) WithTime(t time.Time) *Entry { return entry.WithTime(t) } -func (logger *Logger) Tracef(format string, args ...interface{}) { - if logger.IsLevelEnabled(TraceLevel) { +func (logger *Logger) Logf(level Level, format string, args ...interface{}) { + if logger.IsLevelEnabled(level) { entry := logger.newEntry() - entry.Tracef(format, args...) + entry.Logf(level, format, args...) logger.releaseEntry(entry) } } +func (logger *Logger) Tracef(format string, args ...interface{}) { + logger.Logf(TraceLevel, format, args...) +} + func (logger *Logger) Debugf(format string, args ...interface{}) { - if logger.IsLevelEnabled(DebugLevel) { - entry := logger.newEntry() - entry.Debugf(format, args...) - logger.releaseEntry(entry) - } + logger.Logf(DebugLevel, format, args...) } func (logger *Logger) Infof(format string, args ...interface{}) { - if logger.IsLevelEnabled(InfoLevel) { - entry := logger.newEntry() - entry.Infof(format, args...) - logger.releaseEntry(entry) - } + logger.Logf(InfoLevel, format, args...) } func (logger *Logger) Printf(format string, args ...interface{}) { @@ -162,68 +158,44 @@ func (logger *Logger) Printf(format string, args ...interface{}) { } func (logger *Logger) Warnf(format string, args ...interface{}) { - if logger.IsLevelEnabled(WarnLevel) { - entry := logger.newEntry() - entry.Warnf(format, args...) - logger.releaseEntry(entry) - } + logger.Logf(WarnLevel, format, args...) } func (logger *Logger) Warningf(format string, args ...interface{}) { - if logger.IsLevelEnabled(WarnLevel) { - entry := logger.newEntry() - entry.Warnf(format, args...) - logger.releaseEntry(entry) - } + logger.Warnf(format, args...) } func (logger *Logger) Errorf(format string, args ...interface{}) { - if logger.IsLevelEnabled(ErrorLevel) { - entry := logger.newEntry() - entry.Errorf(format, args...) - logger.releaseEntry(entry) - } + logger.Logf(ErrorLevel, format, args...) } func (logger *Logger) Fatalf(format string, args ...interface{}) { - if logger.IsLevelEnabled(FatalLevel) { - entry := logger.newEntry() - entry.Fatalf(format, args...) - logger.releaseEntry(entry) - } + logger.Logf(FatalLevel, format, args...) logger.Exit(1) } func (logger *Logger) Panicf(format string, args ...interface{}) { - if logger.IsLevelEnabled(PanicLevel) { + logger.Logf(PanicLevel, format, args...) +} + +func (logger *Logger) Log(level Level, args ...interface{}) { + if logger.IsLevelEnabled(level) { entry := logger.newEntry() - entry.Panicf(format, args...) + entry.Log(level, args...) logger.releaseEntry(entry) } } func (logger *Logger) Trace(args ...interface{}) { - if logger.IsLevelEnabled(TraceLevel) { - entry := logger.newEntry() - entry.Trace(args...) - logger.releaseEntry(entry) - } + logger.Log(TraceLevel, args...) } func (logger *Logger) Debug(args ...interface{}) { - if logger.IsLevelEnabled(DebugLevel) { - entry := logger.newEntry() - entry.Debug(args...) - logger.releaseEntry(entry) - } + logger.Log(DebugLevel, args...) } func (logger *Logger) Info(args ...interface{}) { - if logger.IsLevelEnabled(InfoLevel) { - entry := logger.newEntry() - entry.Info(args...) - logger.releaseEntry(entry) - } + logger.Log(InfoLevel, args...) } func (logger *Logger) Print(args ...interface{}) { @@ -233,68 +205,44 @@ func (logger *Logger) Print(args ...interface{}) { } func (logger *Logger) Warn(args ...interface{}) { - if logger.IsLevelEnabled(WarnLevel) { - entry := logger.newEntry() - entry.Warn(args...) - logger.releaseEntry(entry) - } + logger.Log(WarnLevel, args...) } func (logger *Logger) Warning(args ...interface{}) { - if logger.IsLevelEnabled(WarnLevel) { - entry := logger.newEntry() - entry.Warn(args...) - logger.releaseEntry(entry) - } + logger.Warn(args...) } func (logger *Logger) Error(args ...interface{}) { - if logger.IsLevelEnabled(ErrorLevel) { - entry := logger.newEntry() - entry.Error(args...) - logger.releaseEntry(entry) - } + logger.Log(ErrorLevel, args...) } func (logger *Logger) Fatal(args ...interface{}) { - if logger.IsLevelEnabled(FatalLevel) { - entry := logger.newEntry() - entry.Fatal(args...) - logger.releaseEntry(entry) - } + logger.Log(FatalLevel, args...) logger.Exit(1) } func (logger *Logger) Panic(args ...interface{}) { - if logger.IsLevelEnabled(PanicLevel) { + logger.Log(PanicLevel, args...) +} + +func (logger *Logger) Logln(level Level, args ...interface{}) { + if logger.IsLevelEnabled(level) { entry := logger.newEntry() - entry.Panic(args...) + entry.Logln(level, args...) logger.releaseEntry(entry) } } func (logger *Logger) Traceln(args ...interface{}) { - if logger.IsLevelEnabled(TraceLevel) { - entry := logger.newEntry() - entry.Traceln(args...) - logger.releaseEntry(entry) - } + logger.Logln(TraceLevel, args...) } func (logger *Logger) Debugln(args ...interface{}) { - if logger.IsLevelEnabled(DebugLevel) { - entry := logger.newEntry() - entry.Debugln(args...) - logger.releaseEntry(entry) - } + logger.Logln(DebugLevel, args...) } func (logger *Logger) Infoln(args ...interface{}) { - if logger.IsLevelEnabled(InfoLevel) { - entry := logger.newEntry() - entry.Infoln(args...) - logger.releaseEntry(entry) - } + logger.Logln(InfoLevel, args...) } func (logger *Logger) Println(args ...interface{}) { @@ -304,44 +252,24 @@ func (logger *Logger) Println(args ...interface{}) { } func (logger *Logger) Warnln(args ...interface{}) { - if logger.IsLevelEnabled(WarnLevel) { - entry := logger.newEntry() - entry.Warnln(args...) - logger.releaseEntry(entry) - } + logger.Logln(WarnLevel, args...) } func (logger *Logger) Warningln(args ...interface{}) { - if logger.IsLevelEnabled(WarnLevel) { - entry := logger.newEntry() - entry.Warnln(args...) - logger.releaseEntry(entry) - } + logger.Warn(args...) } func (logger *Logger) Errorln(args ...interface{}) { - if logger.IsLevelEnabled(ErrorLevel) { - entry := logger.newEntry() - entry.Errorln(args...) - logger.releaseEntry(entry) - } + logger.Logln(ErrorLevel, args...) } func (logger *Logger) Fatalln(args ...interface{}) { - if logger.IsLevelEnabled(FatalLevel) { - entry := logger.newEntry() - entry.Fatalln(args...) - logger.releaseEntry(entry) - } + logger.Logln(FatalLevel, args...) logger.Exit(1) } func (logger *Logger) Panicln(args ...interface{}) { - if logger.IsLevelEnabled(PanicLevel) { - entry := logger.newEntry() - entry.Panicln(args...) - logger.releaseEntry(entry) - } + logger.Logln(PanicLevel, args...) } func (logger *Logger) Exit(code int) { diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go index 4ef45186..c1ca8899 100644 --- a/vendor/github.com/sirupsen/logrus/logrus.go +++ b/vendor/github.com/sirupsen/logrus/logrus.go @@ -14,24 +14,11 @@ type Level uint32 // Convert the Level to a string. E.g. PanicLevel becomes "panic". func (level Level) String() string { - switch level { - case TraceLevel: - return "trace" - case DebugLevel: - return "debug" - case InfoLevel: - return "info" - case WarnLevel: - return "warning" - case ErrorLevel: - return "error" - case FatalLevel: - return "fatal" - case PanicLevel: - return "panic" + if b, err := level.MarshalText(); err == nil { + return string(b) + } else { + return "unknown" } - - return "unknown" } // ParseLevel takes a string level and returns the Logrus log level constant. @@ -69,6 +56,27 @@ func (level *Level) UnmarshalText(text []byte) error { return nil } +func (level Level) MarshalText() ([]byte, error) { + switch level { + case TraceLevel: + return []byte("trace"), nil + case DebugLevel: + return []byte("debug"), nil + case InfoLevel: + return []byte("info"), nil + case WarnLevel: + return []byte("warning"), nil + case ErrorLevel: + return []byte("error"), nil + case FatalLevel: + return []byte("fatal"), nil + case PanicLevel: + return []byte("panic"), nil + } + + return nil, fmt.Errorf("not a valid lorus level %q", level) +} + // A constant exposing all logging levels var AllLevels = []Level{ PanicLevel, diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_aix.go b/vendor/github.com/sirupsen/logrus/terminal_check_aix.go new file mode 100644 index 00000000..04fdb7ba --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_aix.go @@ -0,0 +1,9 @@ +// +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_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go index cf309d6f..d4655650 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go @@ -1,4 +1,4 @@ -// +build !appengine,!js,!windows +// +build !appengine,!js,!windows,!aix package logrus diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go index 49ec92f1..fb21649c 100644 --- a/vendor/github.com/sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "os" + "runtime" "sort" "strings" "sync" @@ -90,7 +91,7 @@ func (f *TextFormatter) init(entry *Entry) { } func (f *TextFormatter) isColored() bool { - isColored := f.ForceColors || f.isTerminal + isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) if f.EnvironmentOverrideColors { if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" { @@ -107,14 +108,17 @@ func (f *TextFormatter) isColored() bool { // Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - prefixFieldClashes(entry.Data, f.FieldMap, entry.HasCaller()) - - keys := make([]string, 0, len(entry.Data)) - for k := range entry.Data { + data := make(Fields) + for k, v := range entry.Data { + data[k] = v + } + prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + keys := make([]string, 0, len(data)) + for k := range data { keys = append(keys, k) } - fixedKeys := make([]string, 0, 4+len(entry.Data)) + fixedKeys := make([]string, 0, 4+len(data)) if !f.DisableTimestamp { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime)) } @@ -160,7 +164,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { timestampFormat = defaultTimestampFormat } if f.isColored() { - f.printColored(b, entry, keys, timestampFormat) + f.printColored(b, entry, keys, data, timestampFormat) } else { for _, key := range fixedKeys { var value interface{} @@ -178,7 +182,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller(): value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) default: - value = entry.Data[key] + value = data[key] } f.appendKeyValue(b, key, value) } @@ -188,7 +192,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { return b.Bytes(), nil } -func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) { var levelColor int switch entry.Level { case DebugLevel, TraceLevel: @@ -225,7 +229,7 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) } for _, k := range keys { - v := entry.Data[k] + v := data[k] fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) f.appendValue(b, v) } diff --git a/vendor/github.com/spf13/viper/.gitignore b/vendor/github.com/spf13/viper/.gitignore index 352a34a5..01b5c44b 100644 --- a/vendor/github.com/spf13/viper/.gitignore +++ b/vendor/github.com/spf13/viper/.gitignore @@ -21,4 +21,9 @@ _testmain.go *.exe *.test -*.bench
\ No newline at end of file +*.bench + +.vscode + +# exclude dependencies in the `/vendor` folder +vendor diff --git a/vendor/github.com/spf13/viper/.travis.yml b/vendor/github.com/spf13/viper/.travis.yml index 22a8a00e..bb83057b 100644 --- a/vendor/github.com/spf13/viper/.travis.yml +++ b/vendor/github.com/spf13/viper/.travis.yml @@ -1,8 +1,12 @@ go_import_path: github.com/spf13/viper language: go + +env: + global: + - GO111MODULE="on" + go: - - 1.10.x - 1.11.x - tip diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md index 87bbc8b4..0208eac8 100644 --- a/vendor/github.com/spf13/viper/README.md +++ b/vendor/github.com/spf13/viper/README.md @@ -179,13 +179,14 @@ viper.GetBool("verbose") // true ### Working with Environment Variables Viper has full support for environment variables. This enables 12 factor -applications out of the box. There are four methods that exist to aid working +applications out of the box. There are five methods that exist to aid working with ENV: * `AutomaticEnv()` * `BindEnv(string...) : error` * `SetEnvPrefix(string)` * `SetEnvKeyReplacer(string...) *strings.Replacer` + * `AllowEmptyEnvVar(bool)` _When working with ENV variables, it’s important to recognize that Viper treats ENV variables as case sensitive._ @@ -217,6 +218,10 @@ keys to an extent. This is useful if you want to use `-` or something in your `Get()` calls, but want your environmental variables to use `_` delimiters. An example of using it can be found in `viper_test.go`. +By default empty environment variables are considered unset and will fall back to +the next configuration source. To treat empty environment variables as set, use +the `AllowEmptyEnv` method. + #### Env example ```go diff --git a/vendor/github.com/spf13/viper/go.mod b/vendor/github.com/spf13/viper/go.mod index 3f4e1c22..86e801c1 100644 --- a/vendor/github.com/spf13/viper/go.mod +++ b/vendor/github.com/spf13/viper/go.mod @@ -1,16 +1,24 @@ module github.com/spf13/viper require ( + github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // 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/fsnotify/fsnotify v1.4.7 github.com/hashicorp/hcl v1.0.0 github.com/magiconair/properties v1.8.0 - github.com/mitchellh/mapstructure v1.0.0 + github.com/mitchellh/mapstructure v1.1.2 github.com/pelletier/go-toml v1.2.0 github.com/spf13/afero v1.1.2 - github.com/spf13/cast v1.2.0 + github.com/spf13/cast v1.3.0 github.com/spf13/jwalterweatherman v1.0.0 - github.com/spf13/pflag v1.0.2 - golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 // indirect + 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/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 - gopkg.in/yaml.v2 v2.2.1 + 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 3e3b874b..22d60745 100644 --- a/vendor/github.com/spf13/viper/go.sum +++ b/vendor/github.com/spf13/viper/go.sum @@ -1,3 +1,12 @@ +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/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/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/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -5,22 +14,38 @@ 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/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I= -github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= -github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBmaiBH81O8BugSjHeTFg= -golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -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= diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go index 3debcdec..cee37b21 100644 --- a/vendor/github.com/spf13/viper/viper.go +++ b/vendor/github.com/spf13/viper/viper.go @@ -30,6 +30,7 @@ import ( "path/filepath" "reflect" "strings" + "sync" "time" yaml "gopkg.in/yaml.v2" @@ -186,6 +187,7 @@ type Viper struct { automaticEnvApplied bool envKeyReplacer *strings.Replacer + allowEmptyEnv bool config map[string]interface{} override map[string]interface{} @@ -276,50 +278,73 @@ func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) { } func WatchConfig() { v.WatchConfig() } + func (v *Viper) WatchConfig() { + initWG := sync.WaitGroup{} + initWG.Add(1) go func() { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() - // we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way filename, err := v.getConfigFile() if err != nil { - log.Println("error:", err) + log.Printf("error: %v\n", err) return } configFile := filepath.Clean(filename) configDir, _ := filepath.Split(configFile) + realConfigFile, _ := filepath.EvalSymlinks(filename) - done := make(chan bool) + eventsWG := sync.WaitGroup{} + eventsWG.Add(1) go func() { for { select { - case event := <-watcher.Events: - // we only care about the config file - if filepath.Clean(event.Name) == configFile { - if event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Create == fsnotify.Create { - err := v.ReadInConfig() - if err != nil { - log.Println("error:", err) - } - if v.onConfigChange != nil { - v.onConfigChange(event) - } + case event, ok := <-watcher.Events: + if !ok { // 'Events' channel is closed + eventsWG.Done() + return + } + currentConfigFile, _ := filepath.EvalSymlinks(filename) + // we only care about the config file with the following cases: + // 1 - if the config file was modified or created + // 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement) + const writeOrCreateMask = fsnotify.Write | fsnotify.Create + if (filepath.Clean(event.Name) == configFile && + event.Op&writeOrCreateMask != 0) || + (currentConfigFile != "" && currentConfigFile != realConfigFile) { + realConfigFile = currentConfigFile + err := v.ReadInConfig() + if err != nil { + log.Printf("error reading config file: %v\n", err) } + if v.onConfigChange != nil { + v.onConfigChange(event) + } + } else if filepath.Clean(event.Name) == configFile && + event.Op&fsnotify.Remove&fsnotify.Remove != 0 { + eventsWG.Done() + return + } + + case err, ok := <-watcher.Errors: + if ok { // 'Errors' channel is not closed + log.Printf("watcher error: %v\n", err) } - case err := <-watcher.Errors: - log.Println("error:", err) + eventsWG.Done() + return } } }() - watcher.Add(configDir) - <-done + initWG.Done() // done initalizing the watch in this go routine, so the parent routine can move on... + eventsWG.Wait() // now, wait for event loop to end in this go-routine... }() + initWG.Wait() // make sure that the go routine above fully ended before returning } // SetConfigFile explicitly defines the path, name and extension of the config file. @@ -349,6 +374,14 @@ func (v *Viper) mergeWithEnvPrefix(in string) string { return strings.ToUpper(in) } +// AllowEmptyEnv tells Viper to consider set, +// but empty environment variables as valid values instead of falling back. +// For backward compatibility reasons this is false by default. +func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) } +func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) { + v.allowEmptyEnv = allowEmptyEnv +} + // TODO: should getEnv logic be moved into find(). Can generalize the use of // rewriting keys many things, Ex: Get('someKey') -> some_key // (camel case to snake case for JSON keys perhaps) @@ -356,11 +389,14 @@ func (v *Viper) mergeWithEnvPrefix(in string) string { // getEnv is a wrapper around os.Getenv which replaces characters in the original // key. This allows env vars which have different keys than the config object // keys. -func (v *Viper) getEnv(key string) string { +func (v *Viper) getEnv(key string) (string, bool) { if v.envKeyReplacer != nil { key = v.envKeyReplacer.Replace(key) } - return os.Getenv(key) + + val, ok := os.LookupEnv(key) + + return val, ok && (v.allowEmptyEnv || val != "") } // ConfigFileUsed returns the file used to populate the config registry. @@ -587,10 +623,9 @@ func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string { // "foo.bar.baz" in a lower-priority map func (v *Viper) isPathShadowedInAutoEnv(path []string) string { var parentKey string - var val string for i := 1; i < len(path); i++ { parentKey = strings.Join(path[0:i], v.keyDelim) - if val = v.getEnv(v.mergeWithEnvPrefix(parentKey)); val != "" { + if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok { return parentKey } } @@ -969,7 +1004,7 @@ func (v *Viper) find(lcaseKey string) interface{} { if v.automaticEnvApplied { // even if it hasn't been registered, if automaticEnv is used, // check any Get request - if val = v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); val != "" { + if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok { return val } if nested && v.isPathShadowedInAutoEnv(path) != "" { @@ -978,7 +1013,7 @@ func (v *Viper) find(lcaseKey string) interface{} { } envkey, exists := v.env[lcaseKey] if exists { - if val = v.getEnv(envkey); val != "" { + if val, ok := v.getEnv(envkey); ok { return val } } @@ -1224,13 +1259,21 @@ func (v *Viper) ReadConfig(in io.Reader) error { // MergeConfig merges a new configuration with an existing config. func MergeConfig(in io.Reader) error { return v.MergeConfig(in) } func (v *Viper) MergeConfig(in io.Reader) error { - if v.config == nil { - v.config = make(map[string]interface{}) - } cfg := make(map[string]interface{}) if err := v.unmarshalReader(in, cfg); err != nil { return err } + return v.MergeConfigMap(cfg) +} + +// MergeConfigMap merges the configuration from the map given with an existing config. +// Note that the map given may be modified. +func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) } +func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error { + if v.config == nil { + v.config = make(map[string]interface{}) + } + insensitiviseMap(cfg) mergeMaps(cfg, v.config, nil) return nil } diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE index 473b670a..f38ec595 100644 --- a/vendor/github.com/stretchr/testify/LICENSE +++ b/vendor/github.com/stretchr/testify/LICENSE @@ -1,22 +1,21 @@ -Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +MIT License -Please consider promoting this project if you find it useful. +Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT -OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index 5bdec56c..9bd4a80e 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -39,7 +39,7 @@ type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool // for table driven tests. type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool -// ValuesAssertionFunc is a common function prototype when validating an error value. Can be useful +// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful // for table driven tests. type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool @@ -179,7 +179,11 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { return "" } if len(msgAndArgs) == 1 { - return msgAndArgs[0].(string) + msg := msgAndArgs[0] + if msgAsStr, ok := msg.(string); ok { + return msgAsStr + } + return fmt.Sprintf("%+v", msg) } if len(msgAndArgs) > 1 { return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) @@ -415,6 +419,17 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return Fail(t, "Expected value not to be nil.", msgAndArgs...) } +// containsKind checks if a specified kind in the slice of kinds. +func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool { + for i := 0; i < len(kinds); i++ { + if kind == kinds[i] { + return true + } + } + + return false +} + // isNil checks if a specified object is nil or not, without Failing. func isNil(object interface{}) bool { if object == nil { @@ -423,7 +438,14 @@ func isNil(object interface{}) bool { value := reflect.ValueOf(object) kind := value.Kind() - if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + isNilableKind := containsKind( + []reflect.Kind{ + reflect.Chan, reflect.Func, + reflect.Interface, reflect.Map, + reflect.Ptr, reflect.Slice}, + kind) + + if isNilableKind && value.IsNil() { return true } @@ -1327,7 +1349,7 @@ func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { } // diff returns a diff of both values as long as both are of the same type and -// are a struct, map, slice or array. Otherwise it returns an empty string. +// are a struct, map, slice, array or string. Otherwise it returns an empty string. func diff(expected interface{}, actual interface{}) string { if expected == nil || actual == nil { return "" @@ -1345,7 +1367,7 @@ func diff(expected interface{}, actual interface{}) string { } var e, a string - if ek != reflect.String { + if et != reflect.TypeOf("") { e = spewConfig.Sdump(expected) a = spewConfig.Sdump(actual) } else { diff --git a/vendor/github.com/zfjagann/golang-ring/ring.go b/vendor/github.com/zfjagann/golang-ring/ring.go index 2214c4ba..6d2a7e24 100644 --- a/vendor/github.com/zfjagann/golang-ring/ring.go +++ b/vendor/github.com/zfjagann/golang-ring/ring.go @@ -3,6 +3,8 @@ Package ring provides a simple implementation of a ring buffer. */ package ring +import "sync" + /* The DefaultCapacity of an uninitialized Ring buffer. @@ -15,6 +17,7 @@ Type Ring implements a Circular Buffer. The default value of the Ring struct is a valid (empty) Ring buffer with capacity DefaultCapacify. */ type Ring struct { + sync.Mutex head int // the most recent value written tail int // the least recent value written buff []interface{} @@ -24,6 +27,9 @@ type Ring struct { Set the maximum size of the ring buffer. */ func (r *Ring) SetCapacity(size int) { + r.Lock() + defer r.Unlock() + r.checkInit() r.extend(size) } @@ -31,14 +37,38 @@ func (r *Ring) SetCapacity(size int) { /* Capacity returns the current capacity of the ring buffer. */ -func (r Ring) Capacity() int { - return len(r.buff) +func (r *Ring) Capacity() int { + r.Lock() + defer r.Unlock() + + return r.capacity() +} + +/* +ContentSize returns the current number of elements inside the ring buffer. +*/ +func (r *Ring) ContentSize() int { + r.Lock() + defer r.Unlock() + + if r.head == -1 { + return 0 + } else { + difference := (r.head - r.tail) + if difference < 0 { + difference = -difference + } + return difference + 1 + } } /* Enqueue a value into the Ring buffer. */ func (r *Ring) Enqueue(i interface{}) { + r.Lock() + defer r.Unlock() + r.checkInit() r.set(r.head+1, i) old := r.head @@ -54,6 +84,9 @@ Dequeue a value from the Ring buffer. Returns nil if the ring buffer is empty. */ func (r *Ring) Dequeue() interface{} { + r.Lock() + defer r.Unlock() + r.checkInit() if r.head == -1 { return nil @@ -74,6 +107,9 @@ Read the value that Dequeue would have dequeued without actually dequeuing it. Returns nil if the ring buffer is empty. */ func (r *Ring) Peek() interface{} { + r.Lock() + defer r.Unlock() + r.checkInit() if r.head == -1 { return nil @@ -87,11 +123,14 @@ The returned slice can be modified independently of the circular buffer. However are shared between the slice and circular buffer. */ func (r *Ring) Values() []interface{} { + r.Lock() + defer r.Unlock() + if r.head == -1 { return []interface{}{} } - arr := make([]interface{}, 0, r.Capacity()) - for i := 0; i < r.Capacity(); i++ { + arr := make([]interface{}, 0, r.capacity()) + for i := 0; i < r.capacity(); i++ { idx := r.mod(i + r.tail) arr = append(arr, r.get(idx)) if idx == r.head { @@ -105,6 +144,10 @@ func (r *Ring) Values() []interface{} { *** Unexported methods beyond this point. **/ +func (r *Ring) capacity() int { + return len(r.buff) +} + // sets a value at the given unmodified index and returns the modified index of the value func (r *Ring) set(p int, v interface{}) { r.buff[r.mod(p)] = v @@ -121,13 +164,15 @@ func (r *Ring) mod(p int) int { } func (r *Ring) checkInit() { - if r.buff == nil { - r.buff = make([]interface{}, DefaultCapacity) - for i := range r.buff { - r.buff[i] = nil - } - r.head, r.tail = -1, 0 + if r.buff != nil { + return + } + + r.buff = make([]interface{}, DefaultCapacity) + for i := range r.buff { + r.buff[i] = nil } + r.head, r.tail = -1, 0 } func (r *Ring) extend(size int) { |