Added login, some auth methods and a couple routes with no implementation
This commit is contained in:
parent
f76aa74179
commit
f1cae0d660
79 changed files with 8971 additions and 10 deletions
10
server/api/auth.go
Normal file
10
server/api/auth.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *API) Login(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprintf(w, "FROM API")
|
||||||
|
}
|
9
server/api/user.go
Normal file
9
server/api/user.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *API) CreateUser(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
43
server/api/utils.go
Normal file
43
server/api/utils.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Body map[string]interface{}
|
||||||
|
|
||||||
|
func ParseBody(r *http.Request) *Body {
|
||||||
|
var body Body
|
||||||
|
_ = json.NewDecoder(r.Body).Decode(&body)
|
||||||
|
defer r.Body.Close()
|
||||||
|
return &body
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Body) String(name string) string {
|
||||||
|
if res, ok := (*b)[name].(string); ok {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Body) Int(name string) int {
|
||||||
|
if res, ok := (*b)[name].(int); ok {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func JSON(w http.ResponseWriter, data interface{}, statusCode int) {
|
||||||
|
b, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("cannot decode data when generating a JSON response")
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(statusCode)
|
||||||
|
w.Write(b)
|
||||||
|
}
|
|
@ -2,11 +2,12 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"git.ctrlz.es/mgdelacroix/craban/server"
|
"git.ctrlz.es/mgdelacroix/craban/server"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -15,7 +16,7 @@ func main() {
|
||||||
|
|
||||||
srv, err := server.NewServerWithConfigPath(*configFlag)
|
srv, err := server.NewServerWithConfigPath(*configFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "cannot create server: %s", err)
|
log.Error().Err(err).Msg("cannot create server")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,18 +25,18 @@ func main() {
|
||||||
closed := make(chan bool, 1)
|
closed := make(chan bool, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
fmt.Println("Starting craban server")
|
log.Info().Msg("Starting craban server")
|
||||||
if err := srv.Start(); err != nil {
|
if err := srv.Start(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error running server: %s", err)
|
log.Error().Err(err).Msg("error running server")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
closed <- true
|
closed <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
s := <-c
|
s := <-c
|
||||||
fmt.Printf("Got signal %s, exiting...\n", s)
|
log.Info().Str("signal", s.String()).Msg("got signal, exiting")
|
||||||
if err := srv.Close(); err != nil {
|
if err := srv.Close(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error closing server: %s", err)
|
log.Error().Err(err).Msg("error closing server")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
<-closed
|
<-closed
|
||||||
|
|
BIN
server/craban
BIN
server/craban
Binary file not shown.
|
@ -1,3 +1,5 @@
|
||||||
---
|
---
|
||||||
database_path: craban.sqlite
|
database_path: craban.sqlite
|
||||||
port: 8080
|
port: 8080
|
||||||
|
# leave secret empty for a randomly generated one
|
||||||
|
secret: mysupersecret
|
||||||
|
|
|
@ -4,12 +4,15 @@ go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/squirrel v1.5.0
|
github.com/Masterminds/squirrel v1.5.0
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/handlers v1.5.1
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428
|
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428
|
||||||
github.com/mattn/go-sqlite3 v1.14.8
|
github.com/mattn/go-sqlite3 v1.14.8
|
||||||
|
github.com/rs/zerolog v1.25.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,18 @@ github.com/Masterminds/squirrel v1.5.0 h1:JukIZisrUXadA9pl3rMkjhiamxiB0cXiu+HGp/
|
||||||
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||||
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
|
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U=
|
github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U=
|
||||||
github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
|
github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
||||||
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||||
|
@ -28,13 +32,44 @@ github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxz
|
||||||
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
|
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II=
|
||||||
|
github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -14,12 +14,17 @@ const (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DatabasePath *string `yaml:"database_path"`
|
DatabasePath *string `yaml:"database_path"`
|
||||||
Port *int `yaml:"port"`
|
Port *int `yaml:"port"`
|
||||||
|
Secret *string `yaml:"secret"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) SetDefaults() {
|
func (c *Config) SetDefaults() {
|
||||||
if c.Port == nil {
|
if c.Port == nil {
|
||||||
c.Port = NewInt(DefaultPort)
|
c.Port = NewInt(DefaultPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Secret == nil {
|
||||||
|
c.Secret = NewString(NewUUID())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) IsValid() error {
|
func (c *Config) IsValid() error {
|
||||||
|
@ -31,6 +36,10 @@ func (c *Config) IsValid() error {
|
||||||
return fmt.Errorf("port cannot be empty")
|
return fmt.Errorf("port cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Secret == nil || *c.Secret == "" {
|
||||||
|
return fmt.Errorf("secret cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,5 +54,7 @@ func ReadConfig(path string) (*Config, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.SetDefaults()
|
||||||
|
|
||||||
return &config, nil
|
return &config, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,6 @@ import (
|
||||||
func NewString(s string) *string { return &s }
|
func NewString(s string) *string { return &s }
|
||||||
func NewInt(i int) *int { return &i }
|
func NewInt(i int) *int { return &i }
|
||||||
|
|
||||||
func NewID() string {
|
func NewUUID() string {
|
||||||
return uuid.New().String()
|
return uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,23 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.ctrlz.es/mgdelacroix/craban/api"
|
"git.ctrlz.es/mgdelacroix/craban/api"
|
||||||
"git.ctrlz.es/mgdelacroix/craban/model"
|
"git.ctrlz.es/mgdelacroix/craban/model"
|
||||||
"git.ctrlz.es/mgdelacroix/craban/services/store"
|
"git.ctrlz.es/mgdelacroix/craban/services/store"
|
||||||
"git.ctrlz.es/mgdelacroix/craban/web"
|
"git.ctrlz.es/mgdelacroix/craban/web"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339})
|
||||||
|
log.Logger = log.With().Caller().Logger()
|
||||||
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Config *model.Config
|
Config *model.Config
|
||||||
|
|
||||||
|
@ -25,17 +35,21 @@ func NewServer(config *model.Config) (*Server, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create webserver: %w", err)
|
return nil, fmt.Errorf("cannot create webserver: %w", err)
|
||||||
}
|
}
|
||||||
|
log.Debug().Msg("webserver created")
|
||||||
|
|
||||||
store, err := store.NewStore(*config.DatabasePath)
|
store, err := store.NewStore(*config.DatabasePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create store: %w", err)
|
return nil, fmt.Errorf("cannot create store: %w", err)
|
||||||
}
|
}
|
||||||
|
log.Debug().Msg("store created")
|
||||||
|
|
||||||
webAPI, err := api.NewAPI(store)
|
webAPI, err := api.NewAPI(store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create API: %w", err)
|
return nil, fmt.Errorf("cannot create API: %w", err)
|
||||||
}
|
}
|
||||||
|
log.Debug().Msg("API created")
|
||||||
webserver.RegisterRoutes(webAPI)
|
webserver.RegisterRoutes(webAPI)
|
||||||
|
log.Debug().Msg("webserver routes registered with the API")
|
||||||
|
|
||||||
return &Server{
|
return &Server{
|
||||||
Config: config,
|
Config: config,
|
||||||
|
@ -54,6 +68,7 @@ func NewServerWithConfigPath(path string) (*Server, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start() error {
|
||||||
|
log.Debug().Msg("starting server")
|
||||||
if err := s.WebServer.Start(); err != nil {
|
if err := s.WebServer.Start(); err != nil {
|
||||||
return fmt.Errorf("error starting webserver: %w", err)
|
return fmt.Errorf("error starting webserver: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -61,6 +76,7 @@ func (s *Server) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Close() error {
|
func (s *Server) Close() error {
|
||||||
|
log.Debug().Msg("closing server")
|
||||||
if err := s.WebServer.Close(); err != nil {
|
if err := s.WebServer.Close(); err != nil {
|
||||||
return fmt.Errorf("error stopping webserver: %w", err)
|
return fmt.Errorf("error stopping webserver: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -69,5 +85,6 @@ func (s *Server) Close() error {
|
||||||
return fmt.Errorf("error stopping store: %w", err)
|
return fmt.Errorf("error stopping store: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug().Msg("server closed")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
34
server/utils/utils.go
Normal file
34
server/utils/utils.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dgrijalva/jwt-go"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Encrypt(s string) (string, error) {
|
||||||
|
b, err := bcrypt.GenerateFromPassword([]byte(s), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckHash(hash, password string) bool {
|
||||||
|
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateToken(userID int, secret string) (string, error) {
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||||
|
"userID": strconv.Itoa(userID),
|
||||||
|
})
|
||||||
|
|
||||||
|
return token.SignedString([]byte(secret))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Millis(t time.Time) int {
|
||||||
|
return int(t.UnixNano() / 1000000)
|
||||||
|
}
|
4
server/vendor/github.com/dgrijalva/jwt-go/.gitignore
generated
vendored
Normal file
4
server/vendor/github.com/dgrijalva/jwt-go/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.DS_Store
|
||||||
|
bin
|
||||||
|
|
||||||
|
|
13
server/vendor/github.com/dgrijalva/jwt-go/.travis.yml
generated
vendored
Normal file
13
server/vendor/github.com/dgrijalva/jwt-go/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go vet ./...
|
||||||
|
- go test -v ./...
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.3
|
||||||
|
- 1.4
|
||||||
|
- 1.5
|
||||||
|
- 1.6
|
||||||
|
- 1.7
|
||||||
|
- tip
|
8
server/vendor/github.com/dgrijalva/jwt-go/LICENSE
generated
vendored
Normal file
8
server/vendor/github.com/dgrijalva/jwt-go/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Copyright (c) 2012 Dave Grijalva
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
97
server/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
generated
vendored
Normal file
97
server/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
## Migration Guide from v2 -> v3
|
||||||
|
|
||||||
|
Version 3 adds several new, frequently requested features. To do so, it introduces a few breaking changes. We've worked to keep these as minimal as possible. This guide explains the breaking changes and how you can quickly update your code.
|
||||||
|
|
||||||
|
### `Token.Claims` is now an interface type
|
||||||
|
|
||||||
|
The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`. We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`.
|
||||||
|
|
||||||
|
`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior. It is the default claims type when using `Parse`. The usage is unchanged except you must type cast the claims property.
|
||||||
|
|
||||||
|
The old example for parsing a token looked like this..
|
||||||
|
|
||||||
|
```go
|
||||||
|
if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
|
||||||
|
fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
is now directly mapped to...
|
||||||
|
|
||||||
|
```go
|
||||||
|
if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
|
||||||
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
|
fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`StandardClaims` is designed to be embedded in your custom type. You can supply a custom claims type with the new `ParseWithClaims` function. Here's an example of using a custom claims type.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MyCustomClaims struct {
|
||||||
|
User string
|
||||||
|
*StandardClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil {
|
||||||
|
claims := token.Claims.(*MyCustomClaims)
|
||||||
|
fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `ParseFromRequest` has been moved
|
||||||
|
|
||||||
|
To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`. The method signatues have also been augmented to receive a new argument: `Extractor`.
|
||||||
|
|
||||||
|
`Extractors` do the work of picking the token string out of a request. The interface is simple and composable.
|
||||||
|
|
||||||
|
This simple parsing example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil {
|
||||||
|
fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
is directly mapped to:
|
||||||
|
|
||||||
|
```go
|
||||||
|
if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil {
|
||||||
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
|
fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
There are several concrete `Extractor` types provided for your convenience:
|
||||||
|
|
||||||
|
* `HeaderExtractor` will search a list of headers until one contains content.
|
||||||
|
* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content.
|
||||||
|
* `MultiExtractor` will try a list of `Extractors` in order until one returns content.
|
||||||
|
* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token.
|
||||||
|
* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument
|
||||||
|
* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed. A simple example is stripping the `Bearer ` text from a header
|
||||||
|
|
||||||
|
|
||||||
|
### RSA signing methods no longer accept `[]byte` keys
|
||||||
|
|
||||||
|
Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse.
|
||||||
|
|
||||||
|
To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`. These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types.
|
||||||
|
|
||||||
|
```go
|
||||||
|
func keyLookupFunc(*Token) (interface{}, error) {
|
||||||
|
// Don't forget to validate the alg is what you expect:
|
||||||
|
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
|
||||||
|
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up key
|
||||||
|
key, err := lookupPublicKey(token.Header["kid"])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack key from PEM encoded PKCS8
|
||||||
|
return jwt.ParseRSAPublicKeyFromPEM(key)
|
||||||
|
}
|
||||||
|
```
|
100
server/vendor/github.com/dgrijalva/jwt-go/README.md
generated
vendored
Normal file
100
server/vendor/github.com/dgrijalva/jwt-go/README.md
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
**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?
|
||||||
|
|
||||||
|
JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens.
|
||||||
|
|
||||||
|
In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded. The last part is the signature, encoded the same way.
|
||||||
|
|
||||||
|
The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used.
|
||||||
|
|
||||||
|
The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own.
|
||||||
|
|
||||||
|
## What's in the box?
|
||||||
|
|
||||||
|
This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage:
|
||||||
|
|
||||||
|
* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)
|
||||||
|
* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)
|
||||||
|
* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)
|
||||||
|
|
||||||
|
## Extensions
|
||||||
|
|
||||||
|
This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.
|
||||||
|
|
||||||
|
Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
## Project Status & Versioning
|
||||||
|
|
||||||
|
This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).
|
||||||
|
|
||||||
|
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.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
|
||||||
|
|
||||||
|
### Signing vs Encryption
|
||||||
|
|
||||||
|
A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data:
|
||||||
|
|
||||||
|
* The author of the token was in the possession of the signing secret
|
||||||
|
* The data has not been modified since it was signed
|
||||||
|
|
||||||
|
It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library.
|
||||||
|
|
||||||
|
### Choosing a Signing Method
|
||||||
|
|
||||||
|
There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric.
|
||||||
|
|
||||||
|
Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation.
|
||||||
|
|
||||||
|
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 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 the documentation.
|
118
server/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
generated
vendored
Normal file
118
server/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
## `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
|
||||||
|
* Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods.
|
||||||
|
* `ParseFromRequest` has been moved to `request` subpackage and usage has changed
|
||||||
|
* The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims.
|
||||||
|
* Other Additions and Changes
|
||||||
|
* Added `Claims` interface type to allow users to decode the claims into a custom type
|
||||||
|
* Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into.
|
||||||
|
* Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage
|
||||||
|
* Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims`
|
||||||
|
* Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`.
|
||||||
|
* Added several new, more specific, validation errors to error type bitmask
|
||||||
|
* Moved examples from README to executable example files
|
||||||
|
* Signing method registry is now thread safe
|
||||||
|
* Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser)
|
||||||
|
|
||||||
|
#### 2.7.0
|
||||||
|
|
||||||
|
This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes.
|
||||||
|
|
||||||
|
* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying
|
||||||
|
* Error text for expired tokens includes how long it's been expired
|
||||||
|
* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM`
|
||||||
|
* Documentation updates
|
||||||
|
|
||||||
|
#### 2.6.0
|
||||||
|
|
||||||
|
* Exposed inner error within ValidationError
|
||||||
|
* Fixed validation errors when using UseJSONNumber flag
|
||||||
|
* Added several unit tests
|
||||||
|
|
||||||
|
#### 2.5.0
|
||||||
|
|
||||||
|
* Added support for signing method none. You shouldn't use this. The API tries to make this clear.
|
||||||
|
* Updated/fixed some documentation
|
||||||
|
* Added more helpful error message when trying to parse tokens that begin with `BEARER `
|
||||||
|
|
||||||
|
#### 2.4.0
|
||||||
|
|
||||||
|
* Added new type, Parser, to allow for configuration of various parsing parameters
|
||||||
|
* You can now specify a list of valid signing methods. Anything outside this set will be rejected.
|
||||||
|
* You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON
|
||||||
|
* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go)
|
||||||
|
* Fixed some bugs with ECDSA parsing
|
||||||
|
|
||||||
|
#### 2.3.0
|
||||||
|
|
||||||
|
* Added support for ECDSA signing methods
|
||||||
|
* Added support for RSA PSS signing methods (requires go v1.4)
|
||||||
|
|
||||||
|
#### 2.2.0
|
||||||
|
|
||||||
|
* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic.
|
||||||
|
|
||||||
|
#### 2.1.0
|
||||||
|
|
||||||
|
Backwards compatible API change that was missed in 2.0.0.
|
||||||
|
|
||||||
|
* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte`
|
||||||
|
|
||||||
|
#### 2.0.0
|
||||||
|
|
||||||
|
There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change.
|
||||||
|
|
||||||
|
The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`.
|
||||||
|
|
||||||
|
It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`.
|
||||||
|
|
||||||
|
* **Compatibility Breaking Changes**
|
||||||
|
* `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct`
|
||||||
|
* `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct`
|
||||||
|
* `KeyFunc` now returns `interface{}` instead of `[]byte`
|
||||||
|
* `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key
|
||||||
|
* `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key
|
||||||
|
* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type.
|
||||||
|
* Added public package global `SigningMethodHS256`
|
||||||
|
* Added public package global `SigningMethodHS384`
|
||||||
|
* Added public package global `SigningMethodHS512`
|
||||||
|
* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type.
|
||||||
|
* Added public package global `SigningMethodRS256`
|
||||||
|
* Added public package global `SigningMethodRS384`
|
||||||
|
* Added public package global `SigningMethodRS512`
|
||||||
|
* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged.
|
||||||
|
* Refactored the RSA implementation to be easier to read
|
||||||
|
* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM`
|
||||||
|
|
||||||
|
#### 1.0.2
|
||||||
|
|
||||||
|
* Fixed bug in parsing public keys from certificates
|
||||||
|
* Added more tests around the parsing of keys for RS256
|
||||||
|
* Code refactoring in RS256 implementation. No functional changes
|
||||||
|
|
||||||
|
#### 1.0.1
|
||||||
|
|
||||||
|
* Fixed panic if RS256 signing method was passed an invalid key
|
||||||
|
|
||||||
|
#### 1.0.0
|
||||||
|
|
||||||
|
* First versioned release
|
||||||
|
* API stabilized
|
||||||
|
* Supports creating, signing, parsing, and validating JWT tokens
|
||||||
|
* Supports RS256 and HS256 signing methods
|
134
server/vendor/github.com/dgrijalva/jwt-go/claims.go
generated
vendored
Normal file
134
server/vendor/github.com/dgrijalva/jwt-go/claims.go
generated
vendored
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// For a type to be a Claims object, it must just have a Valid method that determines
|
||||||
|
// if the token is invalid for any supported reason
|
||||||
|
type Claims interface {
|
||||||
|
Valid() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structured version of Claims Section, as referenced at
|
||||||
|
// https://tools.ietf.org/html/rfc7519#section-4.1
|
||||||
|
// See examples for how to use this with your own claim types
|
||||||
|
type StandardClaims struct {
|
||||||
|
Audience string `json:"aud,omitempty"`
|
||||||
|
ExpiresAt int64 `json:"exp,omitempty"`
|
||||||
|
Id string `json:"jti,omitempty"`
|
||||||
|
IssuedAt int64 `json:"iat,omitempty"`
|
||||||
|
Issuer string `json:"iss,omitempty"`
|
||||||
|
NotBefore int64 `json:"nbf,omitempty"`
|
||||||
|
Subject string `json:"sub,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates time based claims "exp, iat, nbf".
|
||||||
|
// There is no accounting for clock skew.
|
||||||
|
// As well, if any of the above claims are not in the token, it will still
|
||||||
|
// be considered a valid claim.
|
||||||
|
func (c StandardClaims) Valid() error {
|
||||||
|
vErr := new(ValidationError)
|
||||||
|
now := TimeFunc().Unix()
|
||||||
|
|
||||||
|
// The claims below are optional, by default, so if they are set to the
|
||||||
|
// default value in Go, let's not fail the verification for them.
|
||||||
|
if c.VerifyExpiresAt(now, false) == false {
|
||||||
|
delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
|
||||||
|
vErr.Inner = fmt.Errorf("token is expired by %v", delta)
|
||||||
|
vErr.Errors |= ValidationErrorExpired
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.VerifyIssuedAt(now, false) == false {
|
||||||
|
vErr.Inner = fmt.Errorf("Token used before issued")
|
||||||
|
vErr.Errors |= ValidationErrorIssuedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.VerifyNotBefore(now, false) == false {
|
||||||
|
vErr.Inner = fmt.Errorf("token is not valid yet")
|
||||||
|
vErr.Errors |= ValidationErrorNotValidYet
|
||||||
|
}
|
||||||
|
|
||||||
|
if vErr.valid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return vErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the aud claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
|
||||||
|
return verifyAud(c.Audience, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the exp claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
|
||||||
|
return verifyExp(c.ExpiresAt, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the iat claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
|
||||||
|
return verifyIat(c.IssuedAt, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the iss claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
|
||||||
|
return verifyIss(c.Issuer, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the nbf claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
|
||||||
|
return verifyNbf(c.NotBefore, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- helpers
|
||||||
|
|
||||||
|
func verifyAud(aud string, cmp string, required bool) bool {
|
||||||
|
if aud == "" {
|
||||||
|
return !required
|
||||||
|
}
|
||||||
|
if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyExp(exp int64, now int64, required bool) bool {
|
||||||
|
if exp == 0 {
|
||||||
|
return !required
|
||||||
|
}
|
||||||
|
return now <= exp
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyIat(iat int64, now int64, required bool) bool {
|
||||||
|
if iat == 0 {
|
||||||
|
return !required
|
||||||
|
}
|
||||||
|
return now >= iat
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyIss(iss string, cmp string, required bool) bool {
|
||||||
|
if iss == "" {
|
||||||
|
return !required
|
||||||
|
}
|
||||||
|
if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyNbf(nbf int64, now int64, required bool) bool {
|
||||||
|
if nbf == 0 {
|
||||||
|
return !required
|
||||||
|
}
|
||||||
|
return now >= nbf
|
||||||
|
}
|
4
server/vendor/github.com/dgrijalva/jwt-go/doc.go
generated
vendored
Normal file
4
server/vendor/github.com/dgrijalva/jwt-go/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html
|
||||||
|
//
|
||||||
|
// See README.md for more info.
|
||||||
|
package jwt
|
148
server/vendor/github.com/dgrijalva/jwt-go/ecdsa.go
generated
vendored
Normal file
148
server/vendor/github.com/dgrijalva/jwt-go/ecdsa.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Sadly this is missing from crypto/ecdsa compared to crypto/rsa
|
||||||
|
ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
KeySize int
|
||||||
|
CurveBits int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific instances for EC256 and company
|
||||||
|
var (
|
||||||
|
SigningMethodES256 *SigningMethodECDSA
|
||||||
|
SigningMethodES384 *SigningMethodECDSA
|
||||||
|
SigningMethodES512 *SigningMethodECDSA
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// ES256
|
||||||
|
SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256}
|
||||||
|
RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodES256
|
||||||
|
})
|
||||||
|
|
||||||
|
// ES384
|
||||||
|
SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384}
|
||||||
|
RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodES384
|
||||||
|
})
|
||||||
|
|
||||||
|
// ES512
|
||||||
|
SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521}
|
||||||
|
RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodES512
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SigningMethodECDSA) Alg() string {
|
||||||
|
return m.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Verify method from SigningMethod
|
||||||
|
// For this verify method, key must be an ecdsa.PublicKey struct
|
||||||
|
func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Decode the signature
|
||||||
|
var sig []byte
|
||||||
|
if sig, err = DecodeSegment(signature); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the key
|
||||||
|
var ecdsaKey *ecdsa.PublicKey
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
ecdsaKey = k
|
||||||
|
default:
|
||||||
|
return ErrInvalidKeyType
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sig) != 2*m.KeySize {
|
||||||
|
return ErrECDSAVerification
|
||||||
|
}
|
||||||
|
|
||||||
|
r := big.NewInt(0).SetBytes(sig[:m.KeySize])
|
||||||
|
s := big.NewInt(0).SetBytes(sig[m.KeySize:])
|
||||||
|
|
||||||
|
// Create hasher
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return ErrHashUnavailable
|
||||||
|
}
|
||||||
|
hasher := m.Hash.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
// Verify the signature
|
||||||
|
if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return ErrECDSAVerification
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Sign method from SigningMethod
|
||||||
|
// For this signing method, key must be an ecdsa.PrivateKey struct
|
||||||
|
func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
|
||||||
|
// Get the key
|
||||||
|
var ecdsaKey *ecdsa.PrivateKey
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
ecdsaKey = k
|
||||||
|
default:
|
||||||
|
return "", ErrInvalidKeyType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the hasher
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return "", ErrHashUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
hasher := m.Hash.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
// Sign the string and return r, s
|
||||||
|
if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil {
|
||||||
|
curveBits := ecdsaKey.Curve.Params().BitSize
|
||||||
|
|
||||||
|
if m.CurveBits != curveBits {
|
||||||
|
return "", ErrInvalidKey
|
||||||
|
}
|
||||||
|
|
||||||
|
keyBytes := curveBits / 8
|
||||||
|
if curveBits%8 > 0 {
|
||||||
|
keyBytes += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// We serialize the outpus (r and s) into big-endian byte arrays and pad
|
||||||
|
// them with zeros on the left to make sure the sizes work out. Both arrays
|
||||||
|
// must be keyBytes long, and the output must be 2*keyBytes long.
|
||||||
|
rBytes := r.Bytes()
|
||||||
|
rBytesPadded := make([]byte, keyBytes)
|
||||||
|
copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
|
||||||
|
|
||||||
|
sBytes := s.Bytes()
|
||||||
|
sBytesPadded := make([]byte, keyBytes)
|
||||||
|
copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
|
||||||
|
|
||||||
|
out := append(rBytesPadded, sBytesPadded...)
|
||||||
|
|
||||||
|
return EncodeSegment(out), nil
|
||||||
|
} else {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
67
server/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
generated
vendored
Normal file
67
server/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNotECPublicKey = errors.New("Key is not a valid ECDSA public key")
|
||||||
|
ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parse PEM encoded Elliptic Curve Private Key Structure
|
||||||
|
func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Parse PEM block
|
||||||
|
var block *pem.Block
|
||||||
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
|
return nil, ErrKeyMustBePEMEncoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the key
|
||||||
|
var parsedKey interface{}
|
||||||
|
if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkey *ecdsa.PrivateKey
|
||||||
|
var ok bool
|
||||||
|
if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
|
||||||
|
return nil, ErrNotECPrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse PEM encoded PKCS1 or PKCS8 public key
|
||||||
|
func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Parse PEM block
|
||||||
|
var block *pem.Block
|
||||||
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
|
return nil, ErrKeyMustBePEMEncoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the key
|
||||||
|
var parsedKey interface{}
|
||||||
|
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
||||||
|
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
|
||||||
|
parsedKey = cert.PublicKey
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkey *ecdsa.PublicKey
|
||||||
|
var ok bool
|
||||||
|
if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
|
||||||
|
return nil, ErrNotECPublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkey, nil
|
||||||
|
}
|
59
server/vendor/github.com/dgrijalva/jwt-go/errors.go
generated
vendored
Normal file
59
server/vendor/github.com/dgrijalva/jwt-go/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error constants
|
||||||
|
var (
|
||||||
|
ErrInvalidKey = errors.New("key is invalid")
|
||||||
|
ErrInvalidKeyType = errors.New("key is of invalid type")
|
||||||
|
ErrHashUnavailable = errors.New("the requested hash function is unavailable")
|
||||||
|
)
|
||||||
|
|
||||||
|
// The errors that might occur when parsing and validating a token
|
||||||
|
const (
|
||||||
|
ValidationErrorMalformed uint32 = 1 << iota // Token is malformed
|
||||||
|
ValidationErrorUnverifiable // Token could not be verified because of signing problems
|
||||||
|
ValidationErrorSignatureInvalid // Signature validation failed
|
||||||
|
|
||||||
|
// Standard Claim validation errors
|
||||||
|
ValidationErrorAudience // AUD validation failed
|
||||||
|
ValidationErrorExpired // EXP validation failed
|
||||||
|
ValidationErrorIssuedAt // IAT validation failed
|
||||||
|
ValidationErrorIssuer // ISS validation failed
|
||||||
|
ValidationErrorNotValidYet // NBF validation failed
|
||||||
|
ValidationErrorId // JTI validation failed
|
||||||
|
ValidationErrorClaimsInvalid // Generic claims validation error
|
||||||
|
)
|
||||||
|
|
||||||
|
// Helper for constructing a ValidationError with a string error message
|
||||||
|
func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
|
||||||
|
return &ValidationError{
|
||||||
|
text: errorText,
|
||||||
|
Errors: errorFlags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The error from Parse if token is not valid
|
||||||
|
type ValidationError struct {
|
||||||
|
Inner error // stores the error returned by external dependencies, i.e.: KeyFunc
|
||||||
|
Errors uint32 // bitfield. see ValidationError... constants
|
||||||
|
text string // errors that do not have a valid error just have text
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validation error is an error type
|
||||||
|
func (e ValidationError) Error() string {
|
||||||
|
if e.Inner != nil {
|
||||||
|
return e.Inner.Error()
|
||||||
|
} else if e.text != "" {
|
||||||
|
return e.text
|
||||||
|
} else {
|
||||||
|
return "token is invalid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No errors
|
||||||
|
func (e *ValidationError) valid() bool {
|
||||||
|
return e.Errors == 0
|
||||||
|
}
|
95
server/vendor/github.com/dgrijalva/jwt-go/hmac.go
generated
vendored
Normal file
95
server/vendor/github.com/dgrijalva/jwt-go/hmac.go
generated
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/hmac"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific instances for HS256 and company
|
||||||
|
var (
|
||||||
|
SigningMethodHS256 *SigningMethodHMAC
|
||||||
|
SigningMethodHS384 *SigningMethodHMAC
|
||||||
|
SigningMethodHS512 *SigningMethodHMAC
|
||||||
|
ErrSignatureInvalid = errors.New("signature is invalid")
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// HS256
|
||||||
|
SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256}
|
||||||
|
RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodHS256
|
||||||
|
})
|
||||||
|
|
||||||
|
// HS384
|
||||||
|
SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384}
|
||||||
|
RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodHS384
|
||||||
|
})
|
||||||
|
|
||||||
|
// HS512
|
||||||
|
SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512}
|
||||||
|
RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodHS512
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SigningMethodHMAC) Alg() string {
|
||||||
|
return m.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the signature of HSXXX tokens. Returns nil if the signature is valid.
|
||||||
|
func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {
|
||||||
|
// Verify the key is the right type
|
||||||
|
keyBytes, ok := key.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return ErrInvalidKeyType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode signature, for comparison
|
||||||
|
sig, err := DecodeSegment(signature)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can we use the specified hashing method?
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return ErrHashUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
// This signing method is symmetric, so we validate the signature
|
||||||
|
// by reproducing the signature from the signing string and key, then
|
||||||
|
// comparing that against the provided signature.
|
||||||
|
hasher := hmac.New(m.Hash.New, keyBytes)
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
if !hmac.Equal(sig, hasher.Sum(nil)) {
|
||||||
|
return ErrSignatureInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// No validation errors. Signature is good.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Sign method from SigningMethod for this signing method.
|
||||||
|
// Key must be []byte
|
||||||
|
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
|
||||||
|
if keyBytes, ok := key.([]byte); ok {
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return "", ErrHashUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
hasher := hmac.New(m.Hash.New, keyBytes)
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
return EncodeSegment(hasher.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", ErrInvalidKeyType
|
||||||
|
}
|
94
server/vendor/github.com/dgrijalva/jwt-go/map_claims.go
generated
vendored
Normal file
94
server/vendor/github.com/dgrijalva/jwt-go/map_claims.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
// "fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Claims type that uses the map[string]interface{} for JSON decoding
|
||||||
|
// This is the default claims type if you don't supply one
|
||||||
|
type MapClaims map[string]interface{}
|
||||||
|
|
||||||
|
// Compares the aud claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
|
||||||
|
aud, _ := m["aud"].(string)
|
||||||
|
return verifyAud(aud, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the exp claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
|
||||||
|
switch exp := m["exp"].(type) {
|
||||||
|
case float64:
|
||||||
|
return verifyExp(int64(exp), cmp, req)
|
||||||
|
case json.Number:
|
||||||
|
v, _ := exp.Int64()
|
||||||
|
return verifyExp(v, cmp, req)
|
||||||
|
}
|
||||||
|
return req == false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the iat claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
|
||||||
|
switch iat := m["iat"].(type) {
|
||||||
|
case float64:
|
||||||
|
return verifyIat(int64(iat), cmp, req)
|
||||||
|
case json.Number:
|
||||||
|
v, _ := iat.Int64()
|
||||||
|
return verifyIat(v, cmp, req)
|
||||||
|
}
|
||||||
|
return req == false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the iss claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
|
||||||
|
iss, _ := m["iss"].(string)
|
||||||
|
return verifyIss(iss, cmp, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares the nbf claim against cmp.
|
||||||
|
// If required is false, this method will return true if the value matches or is unset
|
||||||
|
func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
|
||||||
|
switch nbf := m["nbf"].(type) {
|
||||||
|
case float64:
|
||||||
|
return verifyNbf(int64(nbf), cmp, req)
|
||||||
|
case json.Number:
|
||||||
|
v, _ := nbf.Int64()
|
||||||
|
return verifyNbf(v, cmp, req)
|
||||||
|
}
|
||||||
|
return req == false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates time based claims "exp, iat, nbf".
|
||||||
|
// There is no accounting for clock skew.
|
||||||
|
// As well, if any of the above claims are not in the token, it will still
|
||||||
|
// be considered a valid claim.
|
||||||
|
func (m MapClaims) Valid() error {
|
||||||
|
vErr := new(ValidationError)
|
||||||
|
now := TimeFunc().Unix()
|
||||||
|
|
||||||
|
if m.VerifyExpiresAt(now, false) == false {
|
||||||
|
vErr.Inner = errors.New("Token is expired")
|
||||||
|
vErr.Errors |= ValidationErrorExpired
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.VerifyIssuedAt(now, false) == false {
|
||||||
|
vErr.Inner = errors.New("Token used before issued")
|
||||||
|
vErr.Errors |= ValidationErrorIssuedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.VerifyNotBefore(now, false) == false {
|
||||||
|
vErr.Inner = errors.New("Token is not valid yet")
|
||||||
|
vErr.Errors |= ValidationErrorNotValidYet
|
||||||
|
}
|
||||||
|
|
||||||
|
if vErr.valid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return vErr
|
||||||
|
}
|
52
server/vendor/github.com/dgrijalva/jwt-go/none.go
generated
vendored
Normal file
52
server/vendor/github.com/dgrijalva/jwt-go/none.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
// Implements the none signing method. This is required by the spec
|
||||||
|
// but you probably should never use it.
|
||||||
|
var SigningMethodNone *signingMethodNone
|
||||||
|
|
||||||
|
const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed"
|
||||||
|
|
||||||
|
var NoneSignatureTypeDisallowedError error
|
||||||
|
|
||||||
|
type signingMethodNone struct{}
|
||||||
|
type unsafeNoneMagicConstant string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SigningMethodNone = &signingMethodNone{}
|
||||||
|
NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid)
|
||||||
|
|
||||||
|
RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodNone
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *signingMethodNone) Alg() string {
|
||||||
|
return "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key
|
||||||
|
func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) {
|
||||||
|
// Key must be UnsafeAllowNoneSignatureType to prevent accidentally
|
||||||
|
// accepting 'none' signing method
|
||||||
|
if _, ok := key.(unsafeNoneMagicConstant); !ok {
|
||||||
|
return NoneSignatureTypeDisallowedError
|
||||||
|
}
|
||||||
|
// If signing method is none, signature must be an empty string
|
||||||
|
if signature != "" {
|
||||||
|
return NewValidationError(
|
||||||
|
"'none' signing method with non-empty signature",
|
||||||
|
ValidationErrorSignatureInvalid,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept 'none' signing method.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key
|
||||||
|
func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) {
|
||||||
|
if _, ok := key.(unsafeNoneMagicConstant); ok {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return "", NoneSignatureTypeDisallowedError
|
||||||
|
}
|
148
server/vendor/github.com/dgrijalva/jwt-go/parser.go
generated
vendored
Normal file
148
server/vendor/github.com/dgrijalva/jwt-go/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Parser struct {
|
||||||
|
ValidMethods []string // If populated, only these methods will be considered valid
|
||||||
|
UseJSONNumber bool // Use JSON Number format in JSON decoder
|
||||||
|
SkipClaimsValidation bool // Skip claims validation during token parsing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse, validate, and return a token.
|
||||||
|
// keyFunc will receive the parsed token and should return the key for validating.
|
||||||
|
// If everything is kosher, err will be nil
|
||||||
|
func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
|
||||||
|
return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
|
||||||
|
token, parts, err := p.ParseUnverified(tokenString, claims)
|
||||||
|
if err != nil {
|
||||||
|
return token, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify signing method is in the required set
|
||||||
|
if p.ValidMethods != nil {
|
||||||
|
var signingMethodValid = false
|
||||||
|
var alg = token.Method.Alg()
|
||||||
|
for _, m := range p.ValidMethods {
|
||||||
|
if m == alg {
|
||||||
|
signingMethodValid = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !signingMethodValid {
|
||||||
|
// signing method is not in the listed set
|
||||||
|
return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup key
|
||||||
|
var key interface{}
|
||||||
|
if keyFunc == nil {
|
||||||
|
// keyFunc was not provided. short circuiting validation
|
||||||
|
return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable)
|
||||||
|
}
|
||||||
|
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}
|
||||||
|
}
|
||||||
|
|
||||||
|
vErr := &ValidationError{}
|
||||||
|
|
||||||
|
// Validate Claims
|
||||||
|
if !p.SkipClaimsValidation {
|
||||||
|
if err := token.Claims.Valid(); err != nil {
|
||||||
|
|
||||||
|
// If the Claims Valid returned an error, check if it is a validation error,
|
||||||
|
// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
|
||||||
|
if e, ok := err.(*ValidationError); !ok {
|
||||||
|
vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
|
||||||
|
} else {
|
||||||
|
vErr = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform validation
|
||||||
|
token.Signature = parts[2]
|
||||||
|
if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
|
||||||
|
vErr.Inner = err
|
||||||
|
vErr.Errors |= ValidationErrorSignatureInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
if vErr.valid() {
|
||||||
|
token.Valid = true
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
101
server/vendor/github.com/dgrijalva/jwt-go/rsa.go
generated
vendored
Normal file
101
server/vendor/github.com/dgrijalva/jwt-go/rsa.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific instances for RS256 and company
|
||||||
|
var (
|
||||||
|
SigningMethodRS256 *SigningMethodRSA
|
||||||
|
SigningMethodRS384 *SigningMethodRSA
|
||||||
|
SigningMethodRS512 *SigningMethodRSA
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// RS256
|
||||||
|
SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256}
|
||||||
|
RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodRS256
|
||||||
|
})
|
||||||
|
|
||||||
|
// RS384
|
||||||
|
SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384}
|
||||||
|
RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodRS384
|
||||||
|
})
|
||||||
|
|
||||||
|
// RS512
|
||||||
|
SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512}
|
||||||
|
RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodRS512
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SigningMethodRSA) Alg() string {
|
||||||
|
return m.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Verify method from SigningMethod
|
||||||
|
// For this signing method, must be an *rsa.PublicKey structure.
|
||||||
|
func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Decode the signature
|
||||||
|
var sig []byte
|
||||||
|
if sig, err = DecodeSegment(signature); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rsaKey *rsa.PublicKey
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
if rsaKey, ok = key.(*rsa.PublicKey); !ok {
|
||||||
|
return ErrInvalidKeyType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create hasher
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return ErrHashUnavailable
|
||||||
|
}
|
||||||
|
hasher := m.Hash.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
// Verify the signature
|
||||||
|
return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Sign method from SigningMethod
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Validate type of key
|
||||||
|
if rsaKey, ok = key.(*rsa.PrivateKey); !ok {
|
||||||
|
return "", ErrInvalidKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the hasher
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return "", ErrHashUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
hasher := m.Hash.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
// Sign the string and return the encoded bytes
|
||||||
|
if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
|
||||||
|
return EncodeSegment(sigBytes), nil
|
||||||
|
} else {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
126
server/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
generated
vendored
Normal file
126
server/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
// +build go1.4
|
||||||
|
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Implements the RSAPSS family of signing methods signing methods
|
||||||
|
type SigningMethodRSAPSS struct {
|
||||||
|
*SigningMethodRSA
|
||||||
|
Options *rsa.PSSOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific instances for RS/PS and company
|
||||||
|
var (
|
||||||
|
SigningMethodPS256 *SigningMethodRSAPSS
|
||||||
|
SigningMethodPS384 *SigningMethodRSAPSS
|
||||||
|
SigningMethodPS512 *SigningMethodRSAPSS
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// PS256
|
||||||
|
SigningMethodPS256 = &SigningMethodRSAPSS{
|
||||||
|
&SigningMethodRSA{
|
||||||
|
Name: "PS256",
|
||||||
|
Hash: crypto.SHA256,
|
||||||
|
},
|
||||||
|
&rsa.PSSOptions{
|
||||||
|
SaltLength: rsa.PSSSaltLengthAuto,
|
||||||
|
Hash: crypto.SHA256,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodPS256
|
||||||
|
})
|
||||||
|
|
||||||
|
// PS384
|
||||||
|
SigningMethodPS384 = &SigningMethodRSAPSS{
|
||||||
|
&SigningMethodRSA{
|
||||||
|
Name: "PS384",
|
||||||
|
Hash: crypto.SHA384,
|
||||||
|
},
|
||||||
|
&rsa.PSSOptions{
|
||||||
|
SaltLength: rsa.PSSSaltLengthAuto,
|
||||||
|
Hash: crypto.SHA384,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodPS384
|
||||||
|
})
|
||||||
|
|
||||||
|
// PS512
|
||||||
|
SigningMethodPS512 = &SigningMethodRSAPSS{
|
||||||
|
&SigningMethodRSA{
|
||||||
|
Name: "PS512",
|
||||||
|
Hash: crypto.SHA512,
|
||||||
|
},
|
||||||
|
&rsa.PSSOptions{
|
||||||
|
SaltLength: rsa.PSSSaltLengthAuto,
|
||||||
|
Hash: crypto.SHA512,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodPS512
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Verify method from SigningMethod
|
||||||
|
// For this verify method, key must be an rsa.PublicKey struct
|
||||||
|
func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Decode the signature
|
||||||
|
var sig []byte
|
||||||
|
if sig, err = DecodeSegment(signature); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rsaKey *rsa.PublicKey
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
rsaKey = k
|
||||||
|
default:
|
||||||
|
return ErrInvalidKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create hasher
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return ErrHashUnavailable
|
||||||
|
}
|
||||||
|
hasher := m.Hash.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Sign method from SigningMethod
|
||||||
|
// For this signing method, key must be an rsa.PrivateKey struct
|
||||||
|
func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) {
|
||||||
|
var rsaKey *rsa.PrivateKey
|
||||||
|
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
rsaKey = k
|
||||||
|
default:
|
||||||
|
return "", ErrInvalidKeyType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the hasher
|
||||||
|
if !m.Hash.Available() {
|
||||||
|
return "", ErrHashUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
hasher := m.Hash.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
|
// Sign the string and return the encoded bytes
|
||||||
|
if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {
|
||||||
|
return EncodeSegment(sigBytes), nil
|
||||||
|
} else {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
101
server/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
generated
vendored
Normal file
101
server/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
|
||||||
|
ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key")
|
||||||
|
ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parse PEM encoded PKCS1 or PKCS8 private key
|
||||||
|
func ParseRSAPrivateKeyFromPEM(key []byte) (*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{}
|
||||||
|
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
|
||||||
|
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); 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 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
|
||||||
|
|
||||||
|
// Parse PEM block
|
||||||
|
var block *pem.Block
|
||||||
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
|
return nil, ErrKeyMustBePEMEncoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the key
|
||||||
|
var parsedKey interface{}
|
||||||
|
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
||||||
|
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
|
||||||
|
parsedKey = cert.PublicKey
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkey *rsa.PublicKey
|
||||||
|
var ok bool
|
||||||
|
if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
|
||||||
|
return nil, ErrNotRSAPublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkey, nil
|
||||||
|
}
|
35
server/vendor/github.com/dgrijalva/jwt-go/signing_method.go
generated
vendored
Normal file
35
server/vendor/github.com/dgrijalva/jwt-go/signing_method.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var signingMethods = map[string]func() SigningMethod{}
|
||||||
|
var signingMethodLock = new(sync.RWMutex)
|
||||||
|
|
||||||
|
// Implement SigningMethod to add new methods for signing or verifying tokens.
|
||||||
|
type SigningMethod interface {
|
||||||
|
Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid
|
||||||
|
Sign(signingString string, key interface{}) (string, error) // Returns encoded signature or error
|
||||||
|
Alg() string // returns the alg identifier for this method (example: 'HS256')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the "alg" name and a factory function for signing method.
|
||||||
|
// This is typically done during init() in the method's implementation
|
||||||
|
func RegisterSigningMethod(alg string, f func() SigningMethod) {
|
||||||
|
signingMethodLock.Lock()
|
||||||
|
defer signingMethodLock.Unlock()
|
||||||
|
|
||||||
|
signingMethods[alg] = f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a signing method from an "alg" string
|
||||||
|
func GetSigningMethod(alg string) (method SigningMethod) {
|
||||||
|
signingMethodLock.RLock()
|
||||||
|
defer signingMethodLock.RUnlock()
|
||||||
|
|
||||||
|
if methodF, ok := signingMethods[alg]; ok {
|
||||||
|
method = methodF()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
108
server/vendor/github.com/dgrijalva/jwt-go/token.go
generated
vendored
Normal file
108
server/vendor/github.com/dgrijalva/jwt-go/token.go
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
|
||||||
|
// You can override it to use another time value. This is useful for testing or if your
|
||||||
|
// server uses a different time zone than your tokens.
|
||||||
|
var TimeFunc = time.Now
|
||||||
|
|
||||||
|
// Parse methods use this callback function to supply
|
||||||
|
// the key for verification. The function receives the parsed,
|
||||||
|
// but unverified Token. This allows you to use properties in the
|
||||||
|
// Header of the token (such as `kid`) to identify which key to use.
|
||||||
|
type Keyfunc func(*Token) (interface{}, error)
|
||||||
|
|
||||||
|
// A JWT Token. Different fields will be used depending on whether you're
|
||||||
|
// creating or parsing/verifying a token.
|
||||||
|
type Token struct {
|
||||||
|
Raw string // The raw token. Populated when you Parse a token
|
||||||
|
Method SigningMethod // The signing method used or to be used
|
||||||
|
Header map[string]interface{} // The first segment of the token
|
||||||
|
Claims Claims // The second segment of the token
|
||||||
|
Signature string // The third segment of the token. Populated when you Parse a token
|
||||||
|
Valid bool // Is the token valid? Populated when you Parse/Verify a token
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Token. Takes a signing method
|
||||||
|
func New(method SigningMethod) *Token {
|
||||||
|
return NewWithClaims(method, MapClaims{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithClaims(method SigningMethod, claims Claims) *Token {
|
||||||
|
return &Token{
|
||||||
|
Header: map[string]interface{}{
|
||||||
|
"typ": "JWT",
|
||||||
|
"alg": method.Alg(),
|
||||||
|
},
|
||||||
|
Claims: claims,
|
||||||
|
Method: method,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the complete, signed token
|
||||||
|
func (t *Token) SignedString(key interface{}) (string, error) {
|
||||||
|
var sig, sstr string
|
||||||
|
var err error
|
||||||
|
if sstr, err = t.SigningString(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if sig, err = t.Method.Sign(sstr, key); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.Join([]string{sstr, sig}, "."), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the signing string. This is the
|
||||||
|
// most expensive part of the whole deal. Unless you
|
||||||
|
// need this for something special, just go straight for
|
||||||
|
// the SignedString.
|
||||||
|
func (t *Token) SigningString() (string, error) {
|
||||||
|
var err error
|
||||||
|
parts := make([]string, 2)
|
||||||
|
for i, _ := range parts {
|
||||||
|
var jsonValue []byte
|
||||||
|
if i == 0 {
|
||||||
|
if jsonValue, err = json.Marshal(t.Header); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if jsonValue, err = json.Marshal(t.Claims); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parts[i] = EncodeSegment(jsonValue)
|
||||||
|
}
|
||||||
|
return strings.Join(parts, "."), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse, validate, and return a token.
|
||||||
|
// keyFunc will receive the parsed token and should return the key for validating.
|
||||||
|
// If everything is kosher, err will be nil
|
||||||
|
func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
|
||||||
|
return new(Parser).Parse(tokenString, keyFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
|
||||||
|
return new(Parser).ParseWithClaims(tokenString, claims, keyFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode JWT specific base64url encoding with padding stripped
|
||||||
|
func EncodeSegment(seg []byte) string {
|
||||||
|
return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode JWT specific base64url encoding with padding stripped
|
||||||
|
func DecodeSegment(seg string) ([]byte, error) {
|
||||||
|
if l := len(seg) % 4; l > 0 {
|
||||||
|
seg += strings.Repeat("=", 4-l)
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64.URLEncoding.DecodeString(seg)
|
||||||
|
}
|
25
server/vendor/github.com/rs/zerolog/.gitignore
generated
vendored
Normal file
25
server/vendor/github.com/rs/zerolog/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
tmp
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
1
server/vendor/github.com/rs/zerolog/CNAME
generated
vendored
Normal file
1
server/vendor/github.com/rs/zerolog/CNAME
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
zerolog.io
|
21
server/vendor/github.com/rs/zerolog/LICENSE
generated
vendored
Normal file
21
server/vendor/github.com/rs/zerolog/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017 Olivier Poitrey
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
695
server/vendor/github.com/rs/zerolog/README.md
generated
vendored
Normal file
695
server/vendor/github.com/rs/zerolog/README.md
generated
vendored
Normal file
|
@ -0,0 +1,695 @@
|
||||||
|
# Zero Allocation JSON Logger
|
||||||
|
|
||||||
|
[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://travis-ci.org/rs/zerolog.svg?branch=master)](https://travis-ci.org/rs/zerolog) [![Coverage](http://gocover.io/_badge/github.com/rs/zerolog)](http://gocover.io/github.com/rs/zerolog)
|
||||||
|
|
||||||
|
The zerolog package provides a fast and simple logger dedicated to JSON output.
|
||||||
|
|
||||||
|
Zerolog's API is designed to provide both a great developer experience and stunning [performance](#benchmarks). Its unique chaining API allows zerolog to write JSON (or CBOR) log events by avoiding allocations and reflection.
|
||||||
|
|
||||||
|
Uber's [zap](https://godoc.org/go.uber.org/zap) library pioneered this approach. Zerolog is taking this concept to the next level with a simpler to use API and even better performance.
|
||||||
|
|
||||||
|
To keep the code base and the API simple, zerolog focuses on efficient structured logging only. Pretty logging on the console is made possible using the provided (but inefficient) [`zerolog.ConsoleWriter`](#pretty-logging).
|
||||||
|
|
||||||
|
![Pretty Logging Image](pretty.png)
|
||||||
|
|
||||||
|
## Who uses zerolog
|
||||||
|
|
||||||
|
Find out [who uses zerolog](https://github.com/rs/zerolog/wiki/Who-uses-zerolog) and add your company / project to the list.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* [Blazing fast](#benchmarks)
|
||||||
|
* [Low to zero allocation](#benchmarks)
|
||||||
|
* [Leveled logging](#leveled-logging)
|
||||||
|
* [Sampling](#log-sampling)
|
||||||
|
* [Hooks](#hooks)
|
||||||
|
* [Contextual fields](#contextual-logging)
|
||||||
|
* `context.Context` integration
|
||||||
|
* [Integration with `net/http`](#integration-with-nethttp)
|
||||||
|
* [JSON and CBOR encoding formats](#binary-encoding)
|
||||||
|
* [Pretty logging for development](#pretty-logging)
|
||||||
|
* [Error Logging (with optional Stacktrace)](#error-logging)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get -u github.com/rs/zerolog/log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Simple Logging Example
|
||||||
|
|
||||||
|
For simple logging, import the global logger package **github.com/rs/zerolog/log**
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// UNIX Time is faster and smaller than most timestamps
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
log.Print("hello world")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"time":1516134303,"level":"debug","message":"hello world"}
|
||||||
|
```
|
||||||
|
> Note: By default log writes to `os.Stderr`
|
||||||
|
> Note: The default log level for `log.Print` is *debug*
|
||||||
|
|
||||||
|
### Contextual Logging
|
||||||
|
|
||||||
|
**zerolog** allows data to be added to log messages in the form of key:value pairs. The data added to the message adds "context" about the log event that can be critical for debugging as well as myriad other purposes. An example of this is below:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
log.Debug().
|
||||||
|
Str("Scale", "833 cents").
|
||||||
|
Float64("Interval", 833.09).
|
||||||
|
Msg("Fibonacci is everywhere")
|
||||||
|
|
||||||
|
log.Debug().
|
||||||
|
Str("Name", "Tom").
|
||||||
|
Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"level":"debug","Scale":"833 cents","Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere"}
|
||||||
|
// Output: {"level":"debug","Name":"Tom","time":1562212768}
|
||||||
|
```
|
||||||
|
|
||||||
|
> You'll note in the above example that when adding contextual fields, the fields are strongly typed. You can find the full list of supported fields [here](#standard-types)
|
||||||
|
|
||||||
|
### Leveled Logging
|
||||||
|
|
||||||
|
#### Simple Leveled Logging Example
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
log.Info().Msg("hello world")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"time":1516134303,"level":"info","message":"hello world"}
|
||||||
|
```
|
||||||
|
|
||||||
|
> It is very important to note that when using the **zerolog** chaining API, as shown above (`log.Info().Msg("hello world"`), the chain must have either the `Msg` or `Msgf` method call. If you forget to add either of these, the log will not occur and there is no compile time error to alert you of this.
|
||||||
|
|
||||||
|
**zerolog** allows for logging at the following levels (from highest to lowest):
|
||||||
|
|
||||||
|
* panic (`zerolog.PanicLevel`, 5)
|
||||||
|
* fatal (`zerolog.FatalLevel`, 4)
|
||||||
|
* error (`zerolog.ErrorLevel`, 3)
|
||||||
|
* warn (`zerolog.WarnLevel`, 2)
|
||||||
|
* info (`zerolog.InfoLevel`, 1)
|
||||||
|
* debug (`zerolog.DebugLevel`, 0)
|
||||||
|
* trace (`zerolog.TraceLevel`, -1)
|
||||||
|
|
||||||
|
You can set the Global logging level to any of these options using the `SetGlobalLevel` function in the zerolog package, passing in one of the given constants above, e.g. `zerolog.InfoLevel` would be the "info" level. Whichever level is chosen, all logs with a level greater than or equal to that level will be written. To turn off logging entirely, pass the `zerolog.Disabled` constant.
|
||||||
|
|
||||||
|
#### Setting Global Log Level
|
||||||
|
|
||||||
|
This example uses command-line flags to demonstrate various outputs depending on the chosen log level.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
debug := flag.Bool("debug", false, "sets log level to debug")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// Default level for this example is info, unless debug flag is present
|
||||||
|
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||||
|
if *debug {
|
||||||
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Msg("This message appears only when log level set to Debug")
|
||||||
|
log.Info().Msg("This message appears when log level set to Debug or Info")
|
||||||
|
|
||||||
|
if e := log.Debug(); e.Enabled() {
|
||||||
|
// Compute log output only if enabled.
|
||||||
|
value := "bar"
|
||||||
|
e.Str("foo", value).Msg("some debug message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Info Output (no flag)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./logLevelExample
|
||||||
|
{"time":1516387492,"level":"info","message":"This message appears when log level set to Debug or Info"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Debug Output (debug flag set)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./logLevelExample -debug
|
||||||
|
{"time":1516387573,"level":"debug","message":"This message appears only when log level set to Debug"}
|
||||||
|
{"time":1516387573,"level":"info","message":"This message appears when log level set to Debug or Info"}
|
||||||
|
{"time":1516387573,"level":"debug","foo":"bar","message":"some debug message"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Logging without Level or Message
|
||||||
|
|
||||||
|
You may choose to log without a specific level by using the `Log` method. You may also write without a message by setting an empty string in the `msg string` parameter of the `Msg` method. Both are demonstrated in the example below.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
log.Log().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Msg("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"time":1494567715,"foo":"bar"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Logging
|
||||||
|
|
||||||
|
You can log errors using the `Err` method
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
err := errors.New("seems we have an error here")
|
||||||
|
log.Error().Err(err).Msg("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"level":"error","error":"seems we have an error here","time":1609085256}
|
||||||
|
```
|
||||||
|
|
||||||
|
> The default field name for errors is `error`, you can change this by setting `zerolog.ErrorFieldName` to meet your needs.
|
||||||
|
|
||||||
|
#### Error Logging with Stacktrace
|
||||||
|
|
||||||
|
Using `github.com/pkg/errors`, you can add a formatted stacktrace to your errors.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/rs/zerolog/pkgerrors"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
|
||||||
|
|
||||||
|
err := outer()
|
||||||
|
log.Error().Stack().Err(err).Msg("")
|
||||||
|
}
|
||||||
|
|
||||||
|
func inner() error {
|
||||||
|
return errors.New("seems we have an error here")
|
||||||
|
}
|
||||||
|
|
||||||
|
func middle() error {
|
||||||
|
err := inner()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func outer() error {
|
||||||
|
err := middle()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"level":"error","stack":[{"func":"inner","line":"20","source":"errors.go"},{"func":"middle","line":"24","source":"errors.go"},{"func":"outer","line":"32","source":"errors.go"},{"func":"main","line":"15","source":"errors.go"},{"func":"main","line":"204","source":"proc.go"},{"func":"goexit","line":"1374","source":"asm_amd64.s"}],"error":"seems we have an error here","time":1609086683}
|
||||||
|
```
|
||||||
|
|
||||||
|
> zerolog.ErrorStackMarshaler must be set in order for the stack to output anything.
|
||||||
|
|
||||||
|
#### Logging Fatal Messages
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := errors.New("A repo man spends his life getting into tense situations")
|
||||||
|
service := "myservice"
|
||||||
|
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
log.Fatal().
|
||||||
|
Err(err).
|
||||||
|
Str("service", service).
|
||||||
|
Msgf("Cannot start %s", service)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"time":1516133263,"level":"fatal","error":"A repo man spends his life getting into tense situations","service":"myservice","message":"Cannot start myservice"}
|
||||||
|
// exit status 1
|
||||||
|
```
|
||||||
|
|
||||||
|
> NOTE: Using `Msgf` generates one allocation even when the logger is disabled.
|
||||||
|
|
||||||
|
|
||||||
|
### Create logger instance to manage different outputs
|
||||||
|
|
||||||
|
```go
|
||||||
|
logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
|
||||||
|
logger.Info().Str("foo", "bar").Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"level":"info","time":1494567715,"message":"hello world","foo":"bar"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sub-loggers let you chain loggers with additional context
|
||||||
|
|
||||||
|
```go
|
||||||
|
sublogger := log.With().
|
||||||
|
Str("component", "foo").
|
||||||
|
Logger()
|
||||||
|
sublogger.Info().Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"level":"info","time":1494567715,"message":"hello world","component":"foo"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pretty logging
|
||||||
|
|
||||||
|
To log a human-friendly, colorized output, use `zerolog.ConsoleWriter`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||||
|
|
||||||
|
log.Info().Str("foo", "bar").Msg("Hello world")
|
||||||
|
|
||||||
|
// Output: 3:04PM INF Hello World foo=bar
|
||||||
|
```
|
||||||
|
|
||||||
|
To customize the configuration and formatting:
|
||||||
|
|
||||||
|
```go
|
||||||
|
output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}
|
||||||
|
output.FormatLevel = func(i interface{}) string {
|
||||||
|
return strings.ToUpper(fmt.Sprintf("| %-6s|", i))
|
||||||
|
}
|
||||||
|
output.FormatMessage = func(i interface{}) string {
|
||||||
|
return fmt.Sprintf("***%s****", i)
|
||||||
|
}
|
||||||
|
output.FormatFieldName = func(i interface{}) string {
|
||||||
|
return fmt.Sprintf("%s:", i)
|
||||||
|
}
|
||||||
|
output.FormatFieldValue = func(i interface{}) string {
|
||||||
|
return strings.ToUpper(fmt.Sprintf("%s", i))
|
||||||
|
}
|
||||||
|
|
||||||
|
log := zerolog.New(output).With().Timestamp().Logger()
|
||||||
|
|
||||||
|
log.Info().Str("foo", "bar").Msg("Hello World")
|
||||||
|
|
||||||
|
// Output: 2006-01-02T15:04:05Z07:00 | INFO | ***Hello World**** foo:BAR
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sub dictionary
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.Info().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Dict("dict", zerolog.Dict().
|
||||||
|
Str("bar", "baz").
|
||||||
|
Int("n", 1),
|
||||||
|
).Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"level":"info","time":1494567715,"foo":"bar","dict":{"bar":"baz","n":1},"message":"hello world"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize automatic field names
|
||||||
|
|
||||||
|
```go
|
||||||
|
zerolog.TimestampFieldName = "t"
|
||||||
|
zerolog.LevelFieldName = "l"
|
||||||
|
zerolog.MessageFieldName = "m"
|
||||||
|
|
||||||
|
log.Info().Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"l":"info","t":1494567715,"m":"hello world"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add contextual fields to the global logger
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.Logger = log.With().Str("foo", "bar").Logger()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add file and line number to log
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.Logger = log.With().Caller().Logger()
|
||||||
|
log.Info().Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"level": "info", "message": "hello world", "caller": "/go/src/your_project/some_file:21"}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Thread-safe, lock-free, non-blocking writer
|
||||||
|
|
||||||
|
If your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a `diode.Writer` as follow:
|
||||||
|
|
||||||
|
```go
|
||||||
|
wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {
|
||||||
|
fmt.Printf("Logger Dropped %d messages", missed)
|
||||||
|
})
|
||||||
|
log := zerolog.New(wr)
|
||||||
|
log.Print("test")
|
||||||
|
```
|
||||||
|
|
||||||
|
You will need to install `code.cloudfoundry.org/go-diodes` to use this feature.
|
||||||
|
|
||||||
|
### Log Sampling
|
||||||
|
|
||||||
|
```go
|
||||||
|
sampled := log.Sample(&zerolog.BasicSampler{N: 10})
|
||||||
|
sampled.Info().Msg("will be logged every 10 messages")
|
||||||
|
|
||||||
|
// Output: {"time":1494567715,"level":"info","message":"will be logged every 10 messages"}
|
||||||
|
```
|
||||||
|
|
||||||
|
More advanced sampling:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Will let 5 debug messages per period of 1 second.
|
||||||
|
// Over 5 debug message, 1 every 100 debug messages are logged.
|
||||||
|
// Other levels are not sampled.
|
||||||
|
sampled := log.Sample(zerolog.LevelSampler{
|
||||||
|
DebugSampler: &zerolog.BurstSampler{
|
||||||
|
Burst: 5,
|
||||||
|
Period: 1*time.Second,
|
||||||
|
NextSampler: &zerolog.BasicSampler{N: 100},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
sampled.Debug().Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"time":1494567715,"level":"debug","message":"hello world"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hooks
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SeverityHook struct{}
|
||||||
|
|
||||||
|
func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
|
||||||
|
if level != zerolog.NoLevel {
|
||||||
|
e.Str("severity", level.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hooked := log.Hook(SeverityHook{})
|
||||||
|
hooked.Warn().Msg("")
|
||||||
|
|
||||||
|
// Output: {"level":"warn","severity":"warn"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pass a sub-logger by context
|
||||||
|
|
||||||
|
```go
|
||||||
|
ctx := log.With().Str("component", "module").Logger().WithContext(ctx)
|
||||||
|
|
||||||
|
log.Ctx(ctx).Info().Msg("hello world")
|
||||||
|
|
||||||
|
// Output: {"component":"module","level":"info","message":"hello world"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set as standard logger output
|
||||||
|
|
||||||
|
```go
|
||||||
|
log := zerolog.New(os.Stdout).With().
|
||||||
|
Str("foo", "bar").
|
||||||
|
Logger()
|
||||||
|
|
||||||
|
stdlog.SetFlags(0)
|
||||||
|
stdlog.SetOutput(log)
|
||||||
|
|
||||||
|
stdlog.Print("hello world")
|
||||||
|
|
||||||
|
// Output: {"foo":"bar","message":"hello world"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration with `net/http`
|
||||||
|
|
||||||
|
The `github.com/rs/zerolog/hlog` package provides some helpers to integrate zerolog with `http.Handler`.
|
||||||
|
|
||||||
|
In this example we use [alice](https://github.com/justinas/alice) to install logger for better readability.
|
||||||
|
|
||||||
|
```go
|
||||||
|
log := zerolog.New(os.Stdout).With().
|
||||||
|
Timestamp().
|
||||||
|
Str("role", "my-service").
|
||||||
|
Str("host", host).
|
||||||
|
Logger()
|
||||||
|
|
||||||
|
c := alice.New()
|
||||||
|
|
||||||
|
// Install the logger handler with default output on the console
|
||||||
|
c = c.Append(hlog.NewHandler(log))
|
||||||
|
|
||||||
|
// Install some provided extra handler to set some request's context fields.
|
||||||
|
// Thanks to that handler, all our logs will come with some prepopulated fields.
|
||||||
|
c = c.Append(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
|
||||||
|
hlog.FromRequest(r).Info().
|
||||||
|
Str("method", r.Method).
|
||||||
|
Stringer("url", r.URL).
|
||||||
|
Int("status", status).
|
||||||
|
Int("size", size).
|
||||||
|
Dur("duration", duration).
|
||||||
|
Msg("")
|
||||||
|
}))
|
||||||
|
c = c.Append(hlog.RemoteAddrHandler("ip"))
|
||||||
|
c = c.Append(hlog.UserAgentHandler("user_agent"))
|
||||||
|
c = c.Append(hlog.RefererHandler("referer"))
|
||||||
|
c = c.Append(hlog.RequestIDHandler("req_id", "Request-Id"))
|
||||||
|
|
||||||
|
// Here is your final handler
|
||||||
|
h := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Get the logger from the request's context. You can safely assume it
|
||||||
|
// will be always there: if the handler is removed, hlog.FromRequest
|
||||||
|
// will return a no-op logger.
|
||||||
|
hlog.FromRequest(r).Info().
|
||||||
|
Str("user", "current user").
|
||||||
|
Str("status", "ok").
|
||||||
|
Msg("Something happened")
|
||||||
|
|
||||||
|
// Output: {"level":"info","time":"2001-02-03T04:05:06Z","role":"my-service","host":"local-hostname","req_id":"b4g0l5t6tfid6dtrapu0","user":"current user","status":"ok","message":"Something happened"}
|
||||||
|
}))
|
||||||
|
http.Handle("/", h)
|
||||||
|
|
||||||
|
if err := http.ListenAndServe(":8080", nil); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Startup failed")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multiple Log Output
|
||||||
|
`zerolog.MultiLevelWriter` may be used to send the log message to multiple outputs.
|
||||||
|
In this example, we send the log message to both `os.Stdout` and the in-built ConsoleWriter.
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
|
||||||
|
|
||||||
|
multi := zerolog.MultiLevelWriter(consoleWriter, os.Stdout)
|
||||||
|
|
||||||
|
logger := zerolog.New(multi).With().Timestamp().Logger()
|
||||||
|
|
||||||
|
logger.Info().Msg("Hello World!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output (Line 1: Console; Line 2: Stdout)
|
||||||
|
// 12:36PM INF Hello World!
|
||||||
|
// {"level":"info","time":"2019-11-07T12:36:38+03:00","message":"Hello World!"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Global Settings
|
||||||
|
|
||||||
|
Some settings can be changed and will by applied to all loggers:
|
||||||
|
|
||||||
|
* `log.Logger`: You can set this value to customize the global logger (the one used by package level methods).
|
||||||
|
* `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Call this with `zerolog.Disabled` to disable logging altogether (quiet mode).
|
||||||
|
* `zerolog.DisableSampling`: If argument is `true`, all sampled loggers will stop sampling and issue 100% of their log events.
|
||||||
|
* `zerolog.TimestampFieldName`: Can be set to customize `Timestamp` field name.
|
||||||
|
* `zerolog.LevelFieldName`: Can be set to customize level field name.
|
||||||
|
* `zerolog.MessageFieldName`: Can be set to customize message field name.
|
||||||
|
* `zerolog.ErrorFieldName`: Can be set to customize `Err` field name.
|
||||||
|
* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formated as UNIX timestamp.
|
||||||
|
* `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`).
|
||||||
|
* `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`).
|
||||||
|
* `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking.
|
||||||
|
|
||||||
|
## Field Types
|
||||||
|
|
||||||
|
### Standard Types
|
||||||
|
|
||||||
|
* `Str`
|
||||||
|
* `Bool`
|
||||||
|
* `Int`, `Int8`, `Int16`, `Int32`, `Int64`
|
||||||
|
* `Uint`, `Uint8`, `Uint16`, `Uint32`, `Uint64`
|
||||||
|
* `Float32`, `Float64`
|
||||||
|
|
||||||
|
### Advanced Fields
|
||||||
|
|
||||||
|
* `Err`: Takes an `error` and renders it as a string using the `zerolog.ErrorFieldName` field name.
|
||||||
|
* `Func`: Run a `func` only if the level is enabled.
|
||||||
|
* `Timestamp`: Inserts a timestamp field with `zerolog.TimestampFieldName` field name, formatted using `zerolog.TimeFieldFormat`.
|
||||||
|
* `Time`: Adds a field with time formatted with `zerolog.TimeFieldFormat`.
|
||||||
|
* `Dur`: Adds a field with `time.Duration`.
|
||||||
|
* `Dict`: Adds a sub-key/value as a field of the event.
|
||||||
|
* `RawJSON`: Adds a field with an already encoded JSON (`[]byte`)
|
||||||
|
* `Hex`: Adds a field with value formatted as a hexadecimal string (`[]byte`)
|
||||||
|
* `Interface`: Uses reflection to marshal the type.
|
||||||
|
|
||||||
|
Most fields are also available in the slice format (`Strs` for `[]string`, `Errs` for `[]error` etc.)
|
||||||
|
|
||||||
|
## Binary Encoding
|
||||||
|
|
||||||
|
In addition to the default JSON encoding, `zerolog` can produce binary logs using [CBOR](http://cbor.io) encoding. The choice of encoding can be decided at compile time using the build tag `binary_log` as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go build -tags binary_log .
|
||||||
|
```
|
||||||
|
|
||||||
|
To Decode binary encoded log files you can use any CBOR decoder. One has been tested to work
|
||||||
|
with zerolog library is [CSD](https://github.com/toravir/csd/).
|
||||||
|
|
||||||
|
## Related Projects
|
||||||
|
|
||||||
|
* [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog`
|
||||||
|
* [overlog](https://github.com/Trendyol/overlog): Implementation of `Mapped Diagnostic Context` interface using `zerolog`
|
||||||
|
* [zerologr](https://github.com/hn8/zerologr): Implementation of `logr.LogSink` interface using `zerolog`
|
||||||
|
|
||||||
|
## Benchmarks
|
||||||
|
|
||||||
|
See [logbench](http://hackemist.com/logbench/) for more comprehensive and up-to-date benchmarks.
|
||||||
|
|
||||||
|
All operations are allocation free (those numbers *include* JSON encoding):
|
||||||
|
|
||||||
|
```text
|
||||||
|
BenchmarkLogEmpty-8 100000000 19.1 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkDisabled-8 500000000 4.07 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInfo-8 30000000 42.5 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkContextFields-8 30000000 44.9 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkLogFields-8 10000000 184 ns/op 0 B/op 0 allocs/op
|
||||||
|
```
|
||||||
|
|
||||||
|
There are a few Go logging benchmarks and comparisons that include zerolog.
|
||||||
|
|
||||||
|
* [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench)
|
||||||
|
* [uber-common/zap](https://github.com/uber-go/zap#performance)
|
||||||
|
|
||||||
|
Using Uber's zap comparison benchmark:
|
||||||
|
|
||||||
|
Log a message and 10 fields:
|
||||||
|
|
||||||
|
| Library | Time | Bytes Allocated | Objects Allocated |
|
||||||
|
| :--- | :---: | :---: | :---: |
|
||||||
|
| zerolog | 767 ns/op | 552 B/op | 6 allocs/op |
|
||||||
|
| :zap: zap | 848 ns/op | 704 B/op | 2 allocs/op |
|
||||||
|
| :zap: zap (sugared) | 1363 ns/op | 1610 B/op | 20 allocs/op |
|
||||||
|
| go-kit | 3614 ns/op | 2895 B/op | 66 allocs/op |
|
||||||
|
| lion | 5392 ns/op | 5807 B/op | 63 allocs/op |
|
||||||
|
| logrus | 5661 ns/op | 6092 B/op | 78 allocs/op |
|
||||||
|
| apex/log | 15332 ns/op | 3832 B/op | 65 allocs/op |
|
||||||
|
| log15 | 20657 ns/op | 5632 B/op | 93 allocs/op |
|
||||||
|
|
||||||
|
Log a message with a logger that already has 10 fields of context:
|
||||||
|
|
||||||
|
| Library | Time | Bytes Allocated | Objects Allocated |
|
||||||
|
| :--- | :---: | :---: | :---: |
|
||||||
|
| zerolog | 52 ns/op | 0 B/op | 0 allocs/op |
|
||||||
|
| :zap: zap | 283 ns/op | 0 B/op | 0 allocs/op |
|
||||||
|
| :zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op |
|
||||||
|
| lion | 2702 ns/op | 4074 B/op | 38 allocs/op |
|
||||||
|
| go-kit | 3378 ns/op | 3046 B/op | 52 allocs/op |
|
||||||
|
| logrus | 4309 ns/op | 4564 B/op | 63 allocs/op |
|
||||||
|
| apex/log | 13456 ns/op | 2898 B/op | 51 allocs/op |
|
||||||
|
| log15 | 14179 ns/op | 2642 B/op | 44 allocs/op |
|
||||||
|
|
||||||
|
Log a static string, without any context or `printf`-style templating:
|
||||||
|
|
||||||
|
| Library | Time | Bytes Allocated | Objects Allocated |
|
||||||
|
| :--- | :---: | :---: | :---: |
|
||||||
|
| zerolog | 50 ns/op | 0 B/op | 0 allocs/op |
|
||||||
|
| :zap: zap | 236 ns/op | 0 B/op | 0 allocs/op |
|
||||||
|
| standard library | 453 ns/op | 80 B/op | 2 allocs/op |
|
||||||
|
| :zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op |
|
||||||
|
| go-kit | 508 ns/op | 656 B/op | 13 allocs/op |
|
||||||
|
| lion | 771 ns/op | 1224 B/op | 10 allocs/op |
|
||||||
|
| logrus | 1244 ns/op | 1505 B/op | 27 allocs/op |
|
||||||
|
| apex/log | 2751 ns/op | 584 B/op | 11 allocs/op |
|
||||||
|
| log15 | 5181 ns/op | 1592 B/op | 26 allocs/op |
|
||||||
|
|
||||||
|
## Caveats
|
||||||
|
|
||||||
|
Note that zerolog does no de-duplication of fields. Using the same key multiple times creates multiple keys in final JSON:
|
||||||
|
|
||||||
|
```go
|
||||||
|
logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
logger.Info().
|
||||||
|
Timestamp().
|
||||||
|
Msg("dup")
|
||||||
|
// Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"}
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case, many consumers will take the last value, but this is not guaranteed; check yours if in doubt.
|
1
server/vendor/github.com/rs/zerolog/_config.yml
generated
vendored
Normal file
1
server/vendor/github.com/rs/zerolog/_config.yml
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
remote_theme: rs/gh-readme
|
233
server/vendor/github.com/rs/zerolog/array.go
generated
vendored
Normal file
233
server/vendor/github.com/rs/zerolog/array.go
generated
vendored
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var arrayPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &Array{
|
||||||
|
buf: make([]byte, 0, 500),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array is used to prepopulate an array of items
|
||||||
|
// which can be re-used to add to log messages.
|
||||||
|
type Array struct {
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func putArray(a *Array) {
|
||||||
|
// Proper usage of a sync.Pool requires each entry to have approximately
|
||||||
|
// the same memory cost. To obtain this property when the stored type
|
||||||
|
// contains a variably-sized buffer, we add a hard limit on the maximum buffer
|
||||||
|
// to place back in the pool.
|
||||||
|
//
|
||||||
|
// See https://golang.org/issue/23199
|
||||||
|
const maxSize = 1 << 16 // 64KiB
|
||||||
|
if cap(a.buf) > maxSize {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
arrayPool.Put(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arr creates an array to be added to an Event or Context.
|
||||||
|
func Arr() *Array {
|
||||||
|
a := arrayPool.Get().(*Array)
|
||||||
|
a.buf = a.buf[:0]
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalZerologArray method here is no-op - since data is
|
||||||
|
// already in the needed format.
|
||||||
|
func (*Array) MarshalZerologArray(*Array) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Array) write(dst []byte) []byte {
|
||||||
|
dst = enc.AppendArrayStart(dst)
|
||||||
|
if len(a.buf) > 0 {
|
||||||
|
dst = append(append(dst, a.buf...))
|
||||||
|
}
|
||||||
|
dst = enc.AppendArrayEnd(dst)
|
||||||
|
putArray(a)
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object marshals an object that implement the LogObjectMarshaler
|
||||||
|
// interface and append append it to the array.
|
||||||
|
func (a *Array) Object(obj LogObjectMarshaler) *Array {
|
||||||
|
e := Dict()
|
||||||
|
obj.MarshalZerologObject(e)
|
||||||
|
e.buf = enc.AppendEndMarker(e.buf)
|
||||||
|
a.buf = append(enc.AppendArrayDelim(a.buf), e.buf...)
|
||||||
|
putEvent(e)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Str append append the val as a string to the array.
|
||||||
|
func (a *Array) Str(val string) *Array {
|
||||||
|
a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes append append the val as a string to the array.
|
||||||
|
func (a *Array) Bytes(val []byte) *Array {
|
||||||
|
a.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex append append the val as a hex string to the array.
|
||||||
|
func (a *Array) Hex(val []byte) *Array {
|
||||||
|
a.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// RawJSON adds already encoded JSON to the array.
|
||||||
|
func (a *Array) RawJSON(val []byte) *Array {
|
||||||
|
a.buf = appendJSON(enc.AppendArrayDelim(a.buf), val)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err serializes and appends the err to the array.
|
||||||
|
func (a *Array) Err(err error) *Array {
|
||||||
|
switch m := ErrorMarshalFunc(err).(type) {
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
e := newEvent(nil, 0)
|
||||||
|
e.buf = e.buf[:0]
|
||||||
|
e.appendObject(m)
|
||||||
|
a.buf = append(enc.AppendArrayDelim(a.buf), e.buf...)
|
||||||
|
putEvent(e)
|
||||||
|
case error:
|
||||||
|
if m == nil || isNilValue(m) {
|
||||||
|
a.buf = enc.AppendNil(enc.AppendArrayDelim(a.buf))
|
||||||
|
} else {
|
||||||
|
a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), m)
|
||||||
|
default:
|
||||||
|
a.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool append append the val as a bool to the array.
|
||||||
|
func (a *Array) Bool(b bool) *Array {
|
||||||
|
a.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int append append i as a int to the array.
|
||||||
|
func (a *Array) Int(i int) *Array {
|
||||||
|
a.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8 append append i as a int8 to the array.
|
||||||
|
func (a *Array) Int8(i int8) *Array {
|
||||||
|
a.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16 append append i as a int16 to the array.
|
||||||
|
func (a *Array) Int16(i int16) *Array {
|
||||||
|
a.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32 append append i as a int32 to the array.
|
||||||
|
func (a *Array) Int32(i int32) *Array {
|
||||||
|
a.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 append append i as a int64 to the array.
|
||||||
|
func (a *Array) Int64(i int64) *Array {
|
||||||
|
a.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint append append i as a uint to the array.
|
||||||
|
func (a *Array) Uint(i uint) *Array {
|
||||||
|
a.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8 append append i as a uint8 to the array.
|
||||||
|
func (a *Array) Uint8(i uint8) *Array {
|
||||||
|
a.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16 append append i as a uint16 to the array.
|
||||||
|
func (a *Array) Uint16(i uint16) *Array {
|
||||||
|
a.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32 append append i as a uint32 to the array.
|
||||||
|
func (a *Array) Uint32(i uint32) *Array {
|
||||||
|
a.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 append append i as a uint64 to the array.
|
||||||
|
func (a *Array) Uint64(i uint64) *Array {
|
||||||
|
a.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 append append f as a float32 to the array.
|
||||||
|
func (a *Array) Float32(f float32) *Array {
|
||||||
|
a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 append append f as a float64 to the array.
|
||||||
|
func (a *Array) Float64(f float64) *Array {
|
||||||
|
a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time append append t formated as string using zerolog.TimeFieldFormat.
|
||||||
|
func (a *Array) Time(t time.Time) *Array {
|
||||||
|
a.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dur append append d to the array.
|
||||||
|
func (a *Array) Dur(d time.Duration) *Array {
|
||||||
|
a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface append append i marshaled using reflection.
|
||||||
|
func (a *Array) Interface(i interface{}) *Array {
|
||||||
|
if obj, ok := i.(LogObjectMarshaler); ok {
|
||||||
|
return a.Object(obj)
|
||||||
|
}
|
||||||
|
a.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), i)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPAddr adds IPv4 or IPv6 address to the array
|
||||||
|
func (a *Array) IPAddr(ip net.IP) *Array {
|
||||||
|
a.buf = enc.AppendIPAddr(enc.AppendArrayDelim(a.buf), ip)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPPrefix adds IPv4 or IPv6 Prefix (IP + mask) to the array
|
||||||
|
func (a *Array) IPPrefix(pfx net.IPNet) *Array {
|
||||||
|
a.buf = enc.AppendIPPrefix(enc.AppendArrayDelim(a.buf), pfx)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// MACAddr adds a MAC (Ethernet) address to the array
|
||||||
|
func (a *Array) MACAddr(ha net.HardwareAddr) *Array {
|
||||||
|
a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)
|
||||||
|
return a
|
||||||
|
}
|
409
server/vendor/github.com/rs/zerolog/console.go
generated
vendored
Normal file
409
server/vendor/github.com/rs/zerolog/console.go
generated
vendored
Normal file
|
@ -0,0 +1,409 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
colorBlack = iota + 30
|
||||||
|
colorRed
|
||||||
|
colorGreen
|
||||||
|
colorYellow
|
||||||
|
colorBlue
|
||||||
|
colorMagenta
|
||||||
|
colorCyan
|
||||||
|
colorWhite
|
||||||
|
|
||||||
|
colorBold = 1
|
||||||
|
colorDarkGray = 90
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
consoleBufPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return bytes.NewBuffer(make([]byte, 0, 100))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
consoleDefaultTimeFormat = time.Kitchen
|
||||||
|
)
|
||||||
|
|
||||||
|
// Formatter transforms the input into a formatted string.
|
||||||
|
type Formatter func(interface{}) string
|
||||||
|
|
||||||
|
// ConsoleWriter parses the JSON input and writes it in an
|
||||||
|
// (optionally) colorized, human-friendly format to Out.
|
||||||
|
type ConsoleWriter struct {
|
||||||
|
// Out is the output destination.
|
||||||
|
Out io.Writer
|
||||||
|
|
||||||
|
// NoColor disables the colorized output.
|
||||||
|
NoColor bool
|
||||||
|
|
||||||
|
// TimeFormat specifies the format for timestamp in output.
|
||||||
|
TimeFormat string
|
||||||
|
|
||||||
|
// PartsOrder defines the order of parts in output.
|
||||||
|
PartsOrder []string
|
||||||
|
|
||||||
|
// PartsExclude defines parts to not display in output.
|
||||||
|
PartsExclude []string
|
||||||
|
|
||||||
|
FormatTimestamp Formatter
|
||||||
|
FormatLevel Formatter
|
||||||
|
FormatCaller Formatter
|
||||||
|
FormatMessage Formatter
|
||||||
|
FormatFieldName Formatter
|
||||||
|
FormatFieldValue Formatter
|
||||||
|
FormatErrFieldName Formatter
|
||||||
|
FormatErrFieldValue Formatter
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConsoleWriter creates and initializes a new ConsoleWriter.
|
||||||
|
func NewConsoleWriter(options ...func(w *ConsoleWriter)) ConsoleWriter {
|
||||||
|
w := ConsoleWriter{
|
||||||
|
Out: os.Stdout,
|
||||||
|
TimeFormat: consoleDefaultTimeFormat,
|
||||||
|
PartsOrder: consoleDefaultPartsOrder(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range options {
|
||||||
|
opt(&w)
|
||||||
|
}
|
||||||
|
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write transforms the JSON input with formatters and appends to w.Out.
|
||||||
|
func (w ConsoleWriter) Write(p []byte) (n int, err error) {
|
||||||
|
if w.PartsOrder == nil {
|
||||||
|
w.PartsOrder = consoleDefaultPartsOrder()
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf = consoleBufPool.Get().(*bytes.Buffer)
|
||||||
|
defer func() {
|
||||||
|
buf.Reset()
|
||||||
|
consoleBufPool.Put(buf)
|
||||||
|
}()
|
||||||
|
|
||||||
|
var evt map[string]interface{}
|
||||||
|
p = decodeIfBinaryToBytes(p)
|
||||||
|
d := json.NewDecoder(bytes.NewReader(p))
|
||||||
|
d.UseNumber()
|
||||||
|
err = d.Decode(&evt)
|
||||||
|
if err != nil {
|
||||||
|
return n, fmt.Errorf("cannot decode event: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range w.PartsOrder {
|
||||||
|
w.writePart(buf, evt, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.writeFields(evt, buf)
|
||||||
|
|
||||||
|
err = buf.WriteByte('\n')
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
_, err = buf.WriteTo(w.Out)
|
||||||
|
return len(p), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeFields appends formatted key-value pairs to buf.
|
||||||
|
func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer) {
|
||||||
|
var fields = make([]string, 0, len(evt))
|
||||||
|
for field := range evt {
|
||||||
|
switch field {
|
||||||
|
case LevelFieldName, TimestampFieldName, MessageFieldName, CallerFieldName:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields = append(fields, field)
|
||||||
|
}
|
||||||
|
sort.Strings(fields)
|
||||||
|
|
||||||
|
if len(fields) > 0 {
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the "error" field to the front
|
||||||
|
ei := sort.Search(len(fields), func(i int) bool { return fields[i] >= ErrorFieldName })
|
||||||
|
if ei < len(fields) && fields[ei] == ErrorFieldName {
|
||||||
|
fields[ei] = ""
|
||||||
|
fields = append([]string{ErrorFieldName}, fields...)
|
||||||
|
var xfields = make([]string, 0, len(fields))
|
||||||
|
for _, field := range fields {
|
||||||
|
if field == "" { // Skip empty fields
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
xfields = append(xfields, field)
|
||||||
|
}
|
||||||
|
fields = xfields
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, field := range fields {
|
||||||
|
var fn Formatter
|
||||||
|
var fv Formatter
|
||||||
|
|
||||||
|
if field == ErrorFieldName {
|
||||||
|
if w.FormatErrFieldName == nil {
|
||||||
|
fn = consoleDefaultFormatErrFieldName(w.NoColor)
|
||||||
|
} else {
|
||||||
|
fn = w.FormatErrFieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.FormatErrFieldValue == nil {
|
||||||
|
fv = consoleDefaultFormatErrFieldValue(w.NoColor)
|
||||||
|
} else {
|
||||||
|
fv = w.FormatErrFieldValue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if w.FormatFieldName == nil {
|
||||||
|
fn = consoleDefaultFormatFieldName(w.NoColor)
|
||||||
|
} else {
|
||||||
|
fn = w.FormatFieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.FormatFieldValue == nil {
|
||||||
|
fv = consoleDefaultFormatFieldValue
|
||||||
|
} else {
|
||||||
|
fv = w.FormatFieldValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteString(fn(field))
|
||||||
|
|
||||||
|
switch fValue := evt[field].(type) {
|
||||||
|
case string:
|
||||||
|
if needsQuote(fValue) {
|
||||||
|
buf.WriteString(fv(strconv.Quote(fValue)))
|
||||||
|
} else {
|
||||||
|
buf.WriteString(fv(fValue))
|
||||||
|
}
|
||||||
|
case json.Number:
|
||||||
|
buf.WriteString(fv(fValue))
|
||||||
|
default:
|
||||||
|
b, err := json.Marshal(fValue)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(buf, colorize("[error: %v]", colorRed, w.NoColor), err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(buf, fv(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i < len(fields)-1 { // Skip space for last field
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// writePart appends a formatted part to buf.
|
||||||
|
func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, p string) {
|
||||||
|
var f Formatter
|
||||||
|
|
||||||
|
if w.PartsExclude != nil && len(w.PartsExclude) > 0 {
|
||||||
|
for _, exclude := range w.PartsExclude {
|
||||||
|
if exclude == p {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p {
|
||||||
|
case LevelFieldName:
|
||||||
|
if w.FormatLevel == nil {
|
||||||
|
f = consoleDefaultFormatLevel(w.NoColor)
|
||||||
|
} else {
|
||||||
|
f = w.FormatLevel
|
||||||
|
}
|
||||||
|
case TimestampFieldName:
|
||||||
|
if w.FormatTimestamp == nil {
|
||||||
|
f = consoleDefaultFormatTimestamp(w.TimeFormat, w.NoColor)
|
||||||
|
} else {
|
||||||
|
f = w.FormatTimestamp
|
||||||
|
}
|
||||||
|
case MessageFieldName:
|
||||||
|
if w.FormatMessage == nil {
|
||||||
|
f = consoleDefaultFormatMessage
|
||||||
|
} else {
|
||||||
|
f = w.FormatMessage
|
||||||
|
}
|
||||||
|
case CallerFieldName:
|
||||||
|
if w.FormatCaller == nil {
|
||||||
|
f = consoleDefaultFormatCaller(w.NoColor)
|
||||||
|
} else {
|
||||||
|
f = w.FormatCaller
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if w.FormatFieldValue == nil {
|
||||||
|
f = consoleDefaultFormatFieldValue
|
||||||
|
} else {
|
||||||
|
f = w.FormatFieldValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var s = f(evt[p])
|
||||||
|
|
||||||
|
if len(s) > 0 {
|
||||||
|
buf.WriteString(s)
|
||||||
|
if p != w.PartsOrder[len(w.PartsOrder)-1] { // Skip space for last part
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// needsQuote returns true when the string s should be quoted in output.
|
||||||
|
func needsQuote(s string) bool {
|
||||||
|
for i := range s {
|
||||||
|
if s[i] < 0x20 || s[i] > 0x7e || s[i] == ' ' || s[i] == '\\' || s[i] == '"' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// colorize returns the string s wrapped in ANSI code c, unless disabled is true.
|
||||||
|
func colorize(s interface{}, c int, disabled bool) string {
|
||||||
|
if disabled {
|
||||||
|
return fmt.Sprintf("%s", s)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("\x1b[%dm%v\x1b[0m", c, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- DEFAULT FORMATTERS ---------------------------------------------------
|
||||||
|
|
||||||
|
func consoleDefaultPartsOrder() []string {
|
||||||
|
return []string{
|
||||||
|
TimestampFieldName,
|
||||||
|
LevelFieldName,
|
||||||
|
CallerFieldName,
|
||||||
|
MessageFieldName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter {
|
||||||
|
if timeFormat == "" {
|
||||||
|
timeFormat = consoleDefaultTimeFormat
|
||||||
|
}
|
||||||
|
return func(i interface{}) string {
|
||||||
|
t := "<nil>"
|
||||||
|
switch tt := i.(type) {
|
||||||
|
case string:
|
||||||
|
ts, err := time.Parse(TimeFieldFormat, tt)
|
||||||
|
if err != nil {
|
||||||
|
t = tt
|
||||||
|
} else {
|
||||||
|
t = ts.Format(timeFormat)
|
||||||
|
}
|
||||||
|
case json.Number:
|
||||||
|
i, err := tt.Int64()
|
||||||
|
if err != nil {
|
||||||
|
t = tt.String()
|
||||||
|
} else {
|
||||||
|
var sec, nsec int64 = i, 0
|
||||||
|
switch TimeFieldFormat {
|
||||||
|
case TimeFormatUnixMs:
|
||||||
|
nsec = int64(time.Duration(i) * time.Millisecond)
|
||||||
|
sec = 0
|
||||||
|
case TimeFormatUnixMicro:
|
||||||
|
nsec = int64(time.Duration(i) * time.Microsecond)
|
||||||
|
sec = 0
|
||||||
|
}
|
||||||
|
ts := time.Unix(sec, nsec).UTC()
|
||||||
|
t = ts.Format(timeFormat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return colorize(t, colorDarkGray, noColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatLevel(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
|
var l string
|
||||||
|
if ll, ok := i.(string); ok {
|
||||||
|
switch ll {
|
||||||
|
case LevelTraceValue:
|
||||||
|
l = colorize("TRC", colorMagenta, noColor)
|
||||||
|
case LevelDebugValue:
|
||||||
|
l = colorize("DBG", colorYellow, noColor)
|
||||||
|
case LevelInfoValue:
|
||||||
|
l = colorize("INF", colorGreen, noColor)
|
||||||
|
case LevelWarnValue:
|
||||||
|
l = colorize("WRN", colorRed, noColor)
|
||||||
|
case LevelErrorValue:
|
||||||
|
l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor)
|
||||||
|
case LevelFatalValue:
|
||||||
|
l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor)
|
||||||
|
case LevelPanicValue:
|
||||||
|
l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor)
|
||||||
|
default:
|
||||||
|
l = colorize("???", colorBold, noColor)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if i == nil {
|
||||||
|
l = colorize("???", colorBold, noColor)
|
||||||
|
} else {
|
||||||
|
l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatCaller(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
|
var c string
|
||||||
|
if cc, ok := i.(string); ok {
|
||||||
|
c = cc
|
||||||
|
}
|
||||||
|
if len(c) > 0 {
|
||||||
|
if cwd, err := os.Getwd(); err == nil {
|
||||||
|
if rel, err := filepath.Rel(cwd, c); err == nil {
|
||||||
|
c = rel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = colorize(c, colorBold, noColor) + colorize(" >", colorCyan, noColor)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatMessage(i interface{}) string {
|
||||||
|
if i == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatFieldName(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
|
return colorize(fmt.Sprintf("%s=", i), colorCyan, noColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatFieldValue(i interface{}) string {
|
||||||
|
return fmt.Sprintf("%s", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatErrFieldName(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
|
return colorize(fmt.Sprintf("%s=", i), colorRed, noColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatErrFieldValue(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
|
return colorize(fmt.Sprintf("%s", i), colorRed, noColor)
|
||||||
|
}
|
||||||
|
}
|
433
server/vendor/github.com/rs/zerolog/context.go
generated
vendored
Normal file
433
server/vendor/github.com/rs/zerolog/context.go
generated
vendored
Normal file
|
@ -0,0 +1,433 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Context configures a new sub-logger with contextual fields.
|
||||||
|
type Context struct {
|
||||||
|
l Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger returns the logger with the context previously set.
|
||||||
|
func (c Context) Logger() Logger {
|
||||||
|
return c.l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields is a helper function to use a map or slice to set fields using type assertion.
|
||||||
|
// Only map[string]interface{} and []interface{} are accepted. []interface{} must
|
||||||
|
// alternate string keys and arbitrary values, and extraneous ones are ignored.
|
||||||
|
func (c Context) Fields(fields interface{}) Context {
|
||||||
|
c.l.context = appendFields(c.l.context, fields)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dict adds the field key with the dict to the logger context.
|
||||||
|
func (c Context) Dict(key string, dict *Event) Context {
|
||||||
|
dict.buf = enc.AppendEndMarker(dict.buf)
|
||||||
|
c.l.context = append(enc.AppendKey(c.l.context, key), dict.buf...)
|
||||||
|
putEvent(dict)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array adds the field key with an array to the event context.
|
||||||
|
// Use zerolog.Arr() to create the array or pass a type that
|
||||||
|
// implement the LogArrayMarshaler interface.
|
||||||
|
func (c Context) Array(key string, arr LogArrayMarshaler) Context {
|
||||||
|
c.l.context = enc.AppendKey(c.l.context, key)
|
||||||
|
if arr, ok := arr.(*Array); ok {
|
||||||
|
c.l.context = arr.write(c.l.context)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
var a *Array
|
||||||
|
if aa, ok := arr.(*Array); ok {
|
||||||
|
a = aa
|
||||||
|
} else {
|
||||||
|
a = Arr()
|
||||||
|
arr.MarshalZerologArray(a)
|
||||||
|
}
|
||||||
|
c.l.context = a.write(c.l.context)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||||
|
func (c Context) Object(key string, obj LogObjectMarshaler) Context {
|
||||||
|
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
|
||||||
|
e.Object(key, obj)
|
||||||
|
c.l.context = enc.AppendObjectData(c.l.context, e.buf)
|
||||||
|
putEvent(e)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface.
|
||||||
|
func (c Context) EmbedObject(obj LogObjectMarshaler) Context {
|
||||||
|
e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
|
||||||
|
e.EmbedObject(obj)
|
||||||
|
c.l.context = enc.AppendObjectData(c.l.context, e.buf)
|
||||||
|
putEvent(e)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Str adds the field key with val as a string to the logger context.
|
||||||
|
func (c Context) Str(key, val string) Context {
|
||||||
|
c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strs adds the field key with val as a string to the logger context.
|
||||||
|
func (c Context) Strs(key string, vals []string) Context {
|
||||||
|
c.l.context = enc.AppendStrings(enc.AppendKey(c.l.context, key), vals)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stringer adds the field key with val.String() (or null if val is nil) to the logger context.
|
||||||
|
func (c Context) Stringer(key string, val fmt.Stringer) Context {
|
||||||
|
if val != nil {
|
||||||
|
c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val.String())
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), nil)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes adds the field key with val as a []byte to the logger context.
|
||||||
|
func (c Context) Bytes(key string, val []byte) Context {
|
||||||
|
c.l.context = enc.AppendBytes(enc.AppendKey(c.l.context, key), val)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex adds the field key with val as a hex string to the logger context.
|
||||||
|
func (c Context) Hex(key string, val []byte) Context {
|
||||||
|
c.l.context = enc.AppendHex(enc.AppendKey(c.l.context, key), val)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// RawJSON adds already encoded JSON to context.
|
||||||
|
//
|
||||||
|
// No sanity check is performed on b; it must not contain carriage returns and
|
||||||
|
// be valid JSON.
|
||||||
|
func (c Context) RawJSON(key string, b []byte) Context {
|
||||||
|
c.l.context = appendJSON(enc.AppendKey(c.l.context, key), b)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnErr adds the field key with serialized err to the logger context.
|
||||||
|
func (c Context) AnErr(key string, err error) Context {
|
||||||
|
switch m := ErrorMarshalFunc(err).(type) {
|
||||||
|
case nil:
|
||||||
|
return c
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
return c.Object(key, m)
|
||||||
|
case error:
|
||||||
|
if m == nil || isNilValue(m) {
|
||||||
|
return c
|
||||||
|
} else {
|
||||||
|
return c.Str(key, m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
return c.Str(key, m)
|
||||||
|
default:
|
||||||
|
return c.Interface(key, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errs adds the field key with errs as an array of serialized errors to the
|
||||||
|
// logger context.
|
||||||
|
func (c Context) Errs(key string, errs []error) Context {
|
||||||
|
arr := Arr()
|
||||||
|
for _, err := range errs {
|
||||||
|
switch m := ErrorMarshalFunc(err).(type) {
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
arr = arr.Object(m)
|
||||||
|
case error:
|
||||||
|
if m == nil || isNilValue(m) {
|
||||||
|
arr = arr.Interface(nil)
|
||||||
|
} else {
|
||||||
|
arr = arr.Str(m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
arr = arr.Str(m)
|
||||||
|
default:
|
||||||
|
arr = arr.Interface(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Array(key, arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err adds the field "error" with serialized err to the logger context.
|
||||||
|
func (c Context) Err(err error) Context {
|
||||||
|
return c.AnErr(ErrorFieldName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool adds the field key with val as a bool to the logger context.
|
||||||
|
func (c Context) Bool(key string, b bool) Context {
|
||||||
|
c.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bools adds the field key with val as a []bool to the logger context.
|
||||||
|
func (c Context) Bools(key string, b []bool) Context {
|
||||||
|
c.l.context = enc.AppendBools(enc.AppendKey(c.l.context, key), b)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int adds the field key with i as a int to the logger context.
|
||||||
|
func (c Context) Int(key string, i int) Context {
|
||||||
|
c.l.context = enc.AppendInt(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints adds the field key with i as a []int to the logger context.
|
||||||
|
func (c Context) Ints(key string, i []int) Context {
|
||||||
|
c.l.context = enc.AppendInts(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8 adds the field key with i as a int8 to the logger context.
|
||||||
|
func (c Context) Int8(key string, i int8) Context {
|
||||||
|
c.l.context = enc.AppendInt8(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints8 adds the field key with i as a []int8 to the logger context.
|
||||||
|
func (c Context) Ints8(key string, i []int8) Context {
|
||||||
|
c.l.context = enc.AppendInts8(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16 adds the field key with i as a int16 to the logger context.
|
||||||
|
func (c Context) Int16(key string, i int16) Context {
|
||||||
|
c.l.context = enc.AppendInt16(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints16 adds the field key with i as a []int16 to the logger context.
|
||||||
|
func (c Context) Ints16(key string, i []int16) Context {
|
||||||
|
c.l.context = enc.AppendInts16(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32 adds the field key with i as a int32 to the logger context.
|
||||||
|
func (c Context) Int32(key string, i int32) Context {
|
||||||
|
c.l.context = enc.AppendInt32(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints32 adds the field key with i as a []int32 to the logger context.
|
||||||
|
func (c Context) Ints32(key string, i []int32) Context {
|
||||||
|
c.l.context = enc.AppendInts32(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 adds the field key with i as a int64 to the logger context.
|
||||||
|
func (c Context) Int64(key string, i int64) Context {
|
||||||
|
c.l.context = enc.AppendInt64(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints64 adds the field key with i as a []int64 to the logger context.
|
||||||
|
func (c Context) Ints64(key string, i []int64) Context {
|
||||||
|
c.l.context = enc.AppendInts64(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint adds the field key with i as a uint to the logger context.
|
||||||
|
func (c Context) Uint(key string, i uint) Context {
|
||||||
|
c.l.context = enc.AppendUint(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints adds the field key with i as a []uint to the logger context.
|
||||||
|
func (c Context) Uints(key string, i []uint) Context {
|
||||||
|
c.l.context = enc.AppendUints(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8 adds the field key with i as a uint8 to the logger context.
|
||||||
|
func (c Context) Uint8(key string, i uint8) Context {
|
||||||
|
c.l.context = enc.AppendUint8(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints8 adds the field key with i as a []uint8 to the logger context.
|
||||||
|
func (c Context) Uints8(key string, i []uint8) Context {
|
||||||
|
c.l.context = enc.AppendUints8(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16 adds the field key with i as a uint16 to the logger context.
|
||||||
|
func (c Context) Uint16(key string, i uint16) Context {
|
||||||
|
c.l.context = enc.AppendUint16(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints16 adds the field key with i as a []uint16 to the logger context.
|
||||||
|
func (c Context) Uints16(key string, i []uint16) Context {
|
||||||
|
c.l.context = enc.AppendUints16(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32 adds the field key with i as a uint32 to the logger context.
|
||||||
|
func (c Context) Uint32(key string, i uint32) Context {
|
||||||
|
c.l.context = enc.AppendUint32(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints32 adds the field key with i as a []uint32 to the logger context.
|
||||||
|
func (c Context) Uints32(key string, i []uint32) Context {
|
||||||
|
c.l.context = enc.AppendUints32(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 adds the field key with i as a uint64 to the logger context.
|
||||||
|
func (c Context) Uint64(key string, i uint64) Context {
|
||||||
|
c.l.context = enc.AppendUint64(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints64 adds the field key with i as a []uint64 to the logger context.
|
||||||
|
func (c Context) Uints64(key string, i []uint64) Context {
|
||||||
|
c.l.context = enc.AppendUints64(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 adds the field key with f as a float32 to the logger context.
|
||||||
|
func (c Context) Float32(key string, f float32) Context {
|
||||||
|
c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floats32 adds the field key with f as a []float32 to the logger context.
|
||||||
|
func (c Context) Floats32(key string, f []float32) Context {
|
||||||
|
c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 adds the field key with f as a float64 to the logger context.
|
||||||
|
func (c Context) Float64(key string, f float64) Context {
|
||||||
|
c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floats64 adds the field key with f as a []float64 to the logger context.
|
||||||
|
func (c Context) Floats64(key string, f []float64) Context {
|
||||||
|
c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type timestampHook struct{}
|
||||||
|
|
||||||
|
func (ts timestampHook) Run(e *Event, level Level, msg string) {
|
||||||
|
e.Timestamp()
|
||||||
|
}
|
||||||
|
|
||||||
|
var th = timestampHook{}
|
||||||
|
|
||||||
|
// Timestamp adds the current local time as UNIX timestamp to the logger context with the "time" key.
|
||||||
|
// To customize the key name, change zerolog.TimestampFieldName.
|
||||||
|
//
|
||||||
|
// NOTE: It won't dedupe the "time" key if the *Context has one already.
|
||||||
|
func (c Context) Timestamp() Context {
|
||||||
|
c.l = c.l.Hook(th)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
||||||
|
func (c Context) Time(key string, t time.Time) Context {
|
||||||
|
c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
||||||
|
func (c Context) Times(key string, t []time.Time) Context {
|
||||||
|
c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dur adds the fields key with d divided by unit and stored as a float.
|
||||||
|
func (c Context) Dur(key string, d time.Duration) Context {
|
||||||
|
c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Durs adds the fields key with d divided by unit and stored as a float.
|
||||||
|
func (c Context) Durs(key string, d []time.Duration) Context {
|
||||||
|
c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface adds the field key with obj marshaled using reflection.
|
||||||
|
func (c Context) Interface(key string, i interface{}) Context {
|
||||||
|
c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type callerHook struct {
|
||||||
|
callerSkipFrameCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCallerHook(skipFrameCount int) callerHook {
|
||||||
|
return callerHook{callerSkipFrameCount: skipFrameCount}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ch callerHook) Run(e *Event, level Level, msg string) {
|
||||||
|
switch ch.callerSkipFrameCount {
|
||||||
|
case useGlobalSkipFrameCount:
|
||||||
|
// Extra frames to skip (added by hook infra).
|
||||||
|
e.caller(CallerSkipFrameCount + contextCallerSkipFrameCount)
|
||||||
|
default:
|
||||||
|
// Extra frames to skip (added by hook infra).
|
||||||
|
e.caller(ch.callerSkipFrameCount + contextCallerSkipFrameCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// useGlobalSkipFrameCount acts as a flag to informat callerHook.Run
|
||||||
|
// to use the global CallerSkipFrameCount.
|
||||||
|
const useGlobalSkipFrameCount = math.MinInt32
|
||||||
|
|
||||||
|
// ch is the default caller hook using the global CallerSkipFrameCount.
|
||||||
|
var ch = newCallerHook(useGlobalSkipFrameCount)
|
||||||
|
|
||||||
|
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
|
func (c Context) Caller() Context {
|
||||||
|
c.l = c.l.Hook(ch)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallerWithSkipFrameCount adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
|
// The specified skipFrameCount int will override the global CallerSkipFrameCount for this context's respective logger.
|
||||||
|
// If set to -1 the global CallerSkipFrameCount will be used.
|
||||||
|
func (c Context) CallerWithSkipFrameCount(skipFrameCount int) Context {
|
||||||
|
c.l = c.l.Hook(newCallerHook(skipFrameCount))
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack enables stack trace printing for the error passed to Err().
|
||||||
|
func (c Context) Stack() Context {
|
||||||
|
c.l.stack = true
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPAddr adds IPv4 or IPv6 Address to the context
|
||||||
|
func (c Context) IPAddr(key string, ip net.IP) Context {
|
||||||
|
c.l.context = enc.AppendIPAddr(enc.AppendKey(c.l.context, key), ip)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the context
|
||||||
|
func (c Context) IPPrefix(key string, pfx net.IPNet) Context {
|
||||||
|
c.l.context = enc.AppendIPPrefix(enc.AppendKey(c.l.context, key), pfx)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// MACAddr adds MAC address to the context
|
||||||
|
func (c Context) MACAddr(key string, ha net.HardwareAddr) Context {
|
||||||
|
c.l.context = enc.AppendMACAddr(enc.AppendKey(c.l.context, key), ha)
|
||||||
|
return c
|
||||||
|
}
|
51
server/vendor/github.com/rs/zerolog/ctx.go
generated
vendored
Normal file
51
server/vendor/github.com/rs/zerolog/ctx.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
var disabledLogger *Logger
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SetGlobalLevel(TraceLevel)
|
||||||
|
l := Nop()
|
||||||
|
disabledLogger = &l
|
||||||
|
}
|
||||||
|
|
||||||
|
type ctxKey struct{}
|
||||||
|
|
||||||
|
// WithContext returns a copy of ctx with l associated. If an instance of Logger
|
||||||
|
// is already in the context, the context is not updated.
|
||||||
|
//
|
||||||
|
// For instance, to add a field to an existing logger in the context, use this
|
||||||
|
// notation:
|
||||||
|
//
|
||||||
|
// ctx := r.Context()
|
||||||
|
// l := zerolog.Ctx(ctx)
|
||||||
|
// l.UpdateContext(func(c Context) Context {
|
||||||
|
// return c.Str("bar", "baz")
|
||||||
|
// })
|
||||||
|
func (l *Logger) WithContext(ctx context.Context) context.Context {
|
||||||
|
if lp, ok := ctx.Value(ctxKey{}).(*Logger); ok {
|
||||||
|
if lp == l {
|
||||||
|
// Do not store same logger.
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
} else if l.level == Disabled {
|
||||||
|
// Do not store disabled logger.
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, ctxKey{}, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ctx returns the Logger associated with the ctx. If no logger
|
||||||
|
// is associated, DefaultContextLogger is returned, unless DefaultContextLogger
|
||||||
|
// is nil, in which case a disabled logger is returned.
|
||||||
|
func Ctx(ctx context.Context) *Logger {
|
||||||
|
if l, ok := ctx.Value(ctxKey{}).(*Logger); ok {
|
||||||
|
return l
|
||||||
|
} else if l = DefaultContextLogger; l != nil {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
return disabledLogger
|
||||||
|
}
|
56
server/vendor/github.com/rs/zerolog/encoder.go
generated
vendored
Normal file
56
server/vendor/github.com/rs/zerolog/encoder.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type encoder interface {
|
||||||
|
AppendArrayDelim(dst []byte) []byte
|
||||||
|
AppendArrayEnd(dst []byte) []byte
|
||||||
|
AppendArrayStart(dst []byte) []byte
|
||||||
|
AppendBeginMarker(dst []byte) []byte
|
||||||
|
AppendBool(dst []byte, val bool) []byte
|
||||||
|
AppendBools(dst []byte, vals []bool) []byte
|
||||||
|
AppendBytes(dst, s []byte) []byte
|
||||||
|
AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte
|
||||||
|
AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte
|
||||||
|
AppendEndMarker(dst []byte) []byte
|
||||||
|
AppendFloat32(dst []byte, val float32) []byte
|
||||||
|
AppendFloat64(dst []byte, val float64) []byte
|
||||||
|
AppendFloats32(dst []byte, vals []float32) []byte
|
||||||
|
AppendFloats64(dst []byte, vals []float64) []byte
|
||||||
|
AppendHex(dst, s []byte) []byte
|
||||||
|
AppendIPAddr(dst []byte, ip net.IP) []byte
|
||||||
|
AppendIPPrefix(dst []byte, pfx net.IPNet) []byte
|
||||||
|
AppendInt(dst []byte, val int) []byte
|
||||||
|
AppendInt16(dst []byte, val int16) []byte
|
||||||
|
AppendInt32(dst []byte, val int32) []byte
|
||||||
|
AppendInt64(dst []byte, val int64) []byte
|
||||||
|
AppendInt8(dst []byte, val int8) []byte
|
||||||
|
AppendInterface(dst []byte, i interface{}) []byte
|
||||||
|
AppendInts(dst []byte, vals []int) []byte
|
||||||
|
AppendInts16(dst []byte, vals []int16) []byte
|
||||||
|
AppendInts32(dst []byte, vals []int32) []byte
|
||||||
|
AppendInts64(dst []byte, vals []int64) []byte
|
||||||
|
AppendInts8(dst []byte, vals []int8) []byte
|
||||||
|
AppendKey(dst []byte, key string) []byte
|
||||||
|
AppendLineBreak(dst []byte) []byte
|
||||||
|
AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte
|
||||||
|
AppendNil(dst []byte) []byte
|
||||||
|
AppendObjectData(dst []byte, o []byte) []byte
|
||||||
|
AppendString(dst []byte, s string) []byte
|
||||||
|
AppendStrings(dst []byte, vals []string) []byte
|
||||||
|
AppendTime(dst []byte, t time.Time, format string) []byte
|
||||||
|
AppendTimes(dst []byte, vals []time.Time, format string) []byte
|
||||||
|
AppendUint(dst []byte, val uint) []byte
|
||||||
|
AppendUint16(dst []byte, val uint16) []byte
|
||||||
|
AppendUint32(dst []byte, val uint32) []byte
|
||||||
|
AppendUint64(dst []byte, val uint64) []byte
|
||||||
|
AppendUint8(dst []byte, val uint8) []byte
|
||||||
|
AppendUints(dst []byte, vals []uint) []byte
|
||||||
|
AppendUints16(dst []byte, vals []uint16) []byte
|
||||||
|
AppendUints32(dst []byte, vals []uint32) []byte
|
||||||
|
AppendUints64(dst []byte, vals []uint64) []byte
|
||||||
|
AppendUints8(dst []byte, vals []uint8) []byte
|
||||||
|
}
|
42
server/vendor/github.com/rs/zerolog/encoder_cbor.go
generated
vendored
Normal file
42
server/vendor/github.com/rs/zerolog/encoder_cbor.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// +build binary_log
|
||||||
|
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
// This file contains bindings to do binary encoding.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rs/zerolog/internal/cbor"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ encoder = (*cbor.Encoder)(nil)
|
||||||
|
|
||||||
|
enc = cbor.Encoder{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// using closure to reflect the changes at runtime.
|
||||||
|
cbor.JSONMarshalFunc = func(v interface{}) ([]byte, error) {
|
||||||
|
return InterfaceMarshalFunc(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendJSON(dst []byte, j []byte) []byte {
|
||||||
|
return cbor.AppendEmbeddedJSON(dst, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeIfBinaryToString - converts a binary formatted log msg to a
|
||||||
|
// JSON formatted String Log message.
|
||||||
|
func decodeIfBinaryToString(in []byte) string {
|
||||||
|
return cbor.DecodeIfBinaryToString(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeObjectToStr(in []byte) string {
|
||||||
|
return cbor.DecodeObjectToStr(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeIfBinaryToBytes - converts a binary formatted log msg to a
|
||||||
|
// JSON formatted Bytes Log message.
|
||||||
|
func decodeIfBinaryToBytes(in []byte) []byte {
|
||||||
|
return cbor.DecodeIfBinaryToBytes(in)
|
||||||
|
}
|
39
server/vendor/github.com/rs/zerolog/encoder_json.go
generated
vendored
Normal file
39
server/vendor/github.com/rs/zerolog/encoder_json.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// +build !binary_log
|
||||||
|
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
// encoder_json.go file contains bindings to generate
|
||||||
|
// JSON encoded byte stream.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rs/zerolog/internal/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ encoder = (*json.Encoder)(nil)
|
||||||
|
|
||||||
|
enc = json.Encoder{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// using closure to reflect the changes at runtime.
|
||||||
|
json.JSONMarshalFunc = func(v interface{}) ([]byte, error) {
|
||||||
|
return InterfaceMarshalFunc(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendJSON(dst []byte, j []byte) []byte {
|
||||||
|
return append(dst, j...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIfBinaryToString(in []byte) string {
|
||||||
|
return string(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeObjectToStr(in []byte) string {
|
||||||
|
return string(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIfBinaryToBytes(in []byte) []byte {
|
||||||
|
return in
|
||||||
|
}
|
767
server/vendor/github.com/rs/zerolog/event.go
generated
vendored
Normal file
767
server/vendor/github.com/rs/zerolog/event.go
generated
vendored
Normal file
|
@ -0,0 +1,767 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var eventPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &Event{
|
||||||
|
buf: make([]byte, 0, 500),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event represents a log event. It is instanced by one of the level method of
|
||||||
|
// Logger and finalized by the Msg or Msgf method.
|
||||||
|
type Event struct {
|
||||||
|
buf []byte
|
||||||
|
w LevelWriter
|
||||||
|
level Level
|
||||||
|
done func(msg string)
|
||||||
|
stack bool // enable error stack trace
|
||||||
|
ch []Hook // hooks from context
|
||||||
|
skipFrame int // The number of additional frames to skip when printing the caller.
|
||||||
|
}
|
||||||
|
|
||||||
|
func putEvent(e *Event) {
|
||||||
|
// Proper usage of a sync.Pool requires each entry to have approximately
|
||||||
|
// the same memory cost. To obtain this property when the stored type
|
||||||
|
// contains a variably-sized buffer, we add a hard limit on the maximum buffer
|
||||||
|
// to place back in the pool.
|
||||||
|
//
|
||||||
|
// See https://golang.org/issue/23199
|
||||||
|
const maxSize = 1 << 16 // 64KiB
|
||||||
|
if cap(e.buf) > maxSize {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eventPool.Put(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogObjectMarshaler provides a strongly-typed and encoding-agnostic interface
|
||||||
|
// to be implemented by types used with Event/Context's Object methods.
|
||||||
|
type LogObjectMarshaler interface {
|
||||||
|
MarshalZerologObject(e *Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogArrayMarshaler provides a strongly-typed and encoding-agnostic interface
|
||||||
|
// to be implemented by types used with Event/Context's Array methods.
|
||||||
|
type LogArrayMarshaler interface {
|
||||||
|
MarshalZerologArray(a *Array)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newEvent(w LevelWriter, level Level) *Event {
|
||||||
|
e := eventPool.Get().(*Event)
|
||||||
|
e.buf = e.buf[:0]
|
||||||
|
e.ch = nil
|
||||||
|
e.buf = enc.AppendBeginMarker(e.buf)
|
||||||
|
e.w = w
|
||||||
|
e.level = level
|
||||||
|
e.stack = false
|
||||||
|
e.skipFrame = 0
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Event) write() (err error) {
|
||||||
|
if e == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if e.level != Disabled {
|
||||||
|
e.buf = enc.AppendEndMarker(e.buf)
|
||||||
|
e.buf = enc.AppendLineBreak(e.buf)
|
||||||
|
if e.w != nil {
|
||||||
|
_, err = e.w.WriteLevel(e.level, e.buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putEvent(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enabled return false if the *Event is going to be filtered out by
|
||||||
|
// log level or sampling.
|
||||||
|
func (e *Event) Enabled() bool {
|
||||||
|
return e != nil && e.level != Disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discard disables the event so Msg(f) won't print it.
|
||||||
|
func (e *Event) Discard() *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.level = Disabled
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Msg sends the *Event with msg added as the message field if not empty.
|
||||||
|
//
|
||||||
|
// NOTICE: once this method is called, the *Event should be disposed.
|
||||||
|
// Calling Msg twice can have unexpected result.
|
||||||
|
func (e *Event) Msg(msg string) {
|
||||||
|
if e == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e.msg(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send is equivalent to calling Msg("").
|
||||||
|
//
|
||||||
|
// NOTICE: once this method is called, the *Event should be disposed.
|
||||||
|
func (e *Event) Send() {
|
||||||
|
if e == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e.msg("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Msgf sends the event with formatted msg added as the message field if not empty.
|
||||||
|
//
|
||||||
|
// NOTICE: once this method is called, the *Event should be disposed.
|
||||||
|
// Calling Msgf twice can have unexpected result.
|
||||||
|
func (e *Event) Msgf(format string, v ...interface{}) {
|
||||||
|
if e == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e.msg(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Event) msg(msg string) {
|
||||||
|
for _, hook := range e.ch {
|
||||||
|
hook.Run(e, e.level, msg)
|
||||||
|
}
|
||||||
|
if msg != "" {
|
||||||
|
e.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg)
|
||||||
|
}
|
||||||
|
if e.done != nil {
|
||||||
|
defer e.done(msg)
|
||||||
|
}
|
||||||
|
if err := e.write(); err != nil {
|
||||||
|
if ErrorHandler != nil {
|
||||||
|
ErrorHandler(err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields is a helper function to use a map or slice to set fields using type assertion.
|
||||||
|
// Only map[string]interface{} and []interface{} are accepted. []interface{} must
|
||||||
|
// alternate string keys and arbitrary values, and extraneous ones are ignored.
|
||||||
|
func (e *Event) Fields(fields interface{}) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = appendFields(e.buf, fields)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dict adds the field key with a dict to the event context.
|
||||||
|
// Use zerolog.Dict() to create the dictionary.
|
||||||
|
func (e *Event) Dict(key string, dict *Event) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
dict.buf = enc.AppendEndMarker(dict.buf)
|
||||||
|
e.buf = append(enc.AppendKey(e.buf, key), dict.buf...)
|
||||||
|
putEvent(dict)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dict creates an Event to be used with the *Event.Dict method.
|
||||||
|
// Call usual field methods like Str, Int etc to add fields to this
|
||||||
|
// event and give it as argument the *Event.Dict method.
|
||||||
|
func Dict() *Event {
|
||||||
|
return newEvent(nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array adds the field key with an array to the event context.
|
||||||
|
// Use zerolog.Arr() to create the array or pass a type that
|
||||||
|
// implement the LogArrayMarshaler interface.
|
||||||
|
func (e *Event) Array(key string, arr LogArrayMarshaler) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendKey(e.buf, key)
|
||||||
|
var a *Array
|
||||||
|
if aa, ok := arr.(*Array); ok {
|
||||||
|
a = aa
|
||||||
|
} else {
|
||||||
|
a = Arr()
|
||||||
|
arr.MarshalZerologArray(a)
|
||||||
|
}
|
||||||
|
e.buf = a.write(e.buf)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Event) appendObject(obj LogObjectMarshaler) {
|
||||||
|
e.buf = enc.AppendBeginMarker(e.buf)
|
||||||
|
obj.MarshalZerologObject(e)
|
||||||
|
e.buf = enc.AppendEndMarker(e.buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object marshals an object that implement the LogObjectMarshaler interface.
|
||||||
|
func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendKey(e.buf, key)
|
||||||
|
if obj == nil {
|
||||||
|
e.buf = enc.AppendNil(e.buf)
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
e.appendObject(obj)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Func allows an anonymous func to run only if the event is enabled.
|
||||||
|
func (e *Event) Func(f func(e *Event)) *Event {
|
||||||
|
if e != nil && e.Enabled() {
|
||||||
|
f(e)
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmbedObject marshals an object that implement the LogObjectMarshaler interface.
|
||||||
|
func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
if obj == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
obj.MarshalZerologObject(e)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Str adds the field key with val as a string to the *Event context.
|
||||||
|
func (e *Event) Str(key, val string) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strs adds the field key with vals as a []string to the *Event context.
|
||||||
|
func (e *Event) Strs(key string, vals []string) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendStrings(enc.AppendKey(e.buf, key), vals)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stringer adds the field key with val.String() (or null if val is nil) to the *Event context.
|
||||||
|
func (e *Event) Stringer(key string, val fmt.Stringer) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != nil {
|
||||||
|
e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val.String())
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), nil)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes adds the field key with val as a string to the *Event context.
|
||||||
|
//
|
||||||
|
// Runes outside of normal ASCII ranges will be hex-encoded in the resulting
|
||||||
|
// JSON.
|
||||||
|
func (e *Event) Bytes(key string, val []byte) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendBytes(enc.AppendKey(e.buf, key), val)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex adds the field key with val as a hex string to the *Event context.
|
||||||
|
func (e *Event) Hex(key string, val []byte) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendHex(enc.AppendKey(e.buf, key), val)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// RawJSON adds already encoded JSON to the log line under key.
|
||||||
|
//
|
||||||
|
// No sanity check is performed on b; it must not contain carriage returns and
|
||||||
|
// be valid JSON.
|
||||||
|
func (e *Event) RawJSON(key string, b []byte) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = appendJSON(enc.AppendKey(e.buf, key), b)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnErr adds the field key with serialized err to the *Event context.
|
||||||
|
// If err is nil, no field is added.
|
||||||
|
func (e *Event) AnErr(key string, err error) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
switch m := ErrorMarshalFunc(err).(type) {
|
||||||
|
case nil:
|
||||||
|
return e
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
return e.Object(key, m)
|
||||||
|
case error:
|
||||||
|
if m == nil || isNilValue(m) {
|
||||||
|
return e
|
||||||
|
} else {
|
||||||
|
return e.Str(key, m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
return e.Str(key, m)
|
||||||
|
default:
|
||||||
|
return e.Interface(key, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errs adds the field key with errs as an array of serialized errors to the
|
||||||
|
// *Event context.
|
||||||
|
func (e *Event) Errs(key string, errs []error) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
arr := Arr()
|
||||||
|
for _, err := range errs {
|
||||||
|
switch m := ErrorMarshalFunc(err).(type) {
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
arr = arr.Object(m)
|
||||||
|
case error:
|
||||||
|
arr = arr.Err(m)
|
||||||
|
case string:
|
||||||
|
arr = arr.Str(m)
|
||||||
|
default:
|
||||||
|
arr = arr.Interface(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.Array(key, arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err adds the field "error" with serialized err to the *Event context.
|
||||||
|
// If err is nil, no field is added.
|
||||||
|
//
|
||||||
|
// To customize the key name, change zerolog.ErrorFieldName.
|
||||||
|
//
|
||||||
|
// If Stack() has been called before and zerolog.ErrorStackMarshaler is defined,
|
||||||
|
// the err is passed to ErrorStackMarshaler and the result is appended to the
|
||||||
|
// zerolog.ErrorStackFieldName.
|
||||||
|
func (e *Event) Err(err error) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
if e.stack && ErrorStackMarshaler != nil {
|
||||||
|
switch m := ErrorStackMarshaler(err).(type) {
|
||||||
|
case nil:
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
e.Object(ErrorStackFieldName, m)
|
||||||
|
case error:
|
||||||
|
if m != nil && !isNilValue(m) {
|
||||||
|
e.Str(ErrorStackFieldName, m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
e.Str(ErrorStackFieldName, m)
|
||||||
|
default:
|
||||||
|
e.Interface(ErrorStackFieldName, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e.AnErr(ErrorFieldName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack enables stack trace printing for the error passed to Err().
|
||||||
|
//
|
||||||
|
// ErrorStackMarshaler must be set for this method to do something.
|
||||||
|
func (e *Event) Stack() *Event {
|
||||||
|
if e != nil {
|
||||||
|
e.stack = true
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool adds the field key with val as a bool to the *Event context.
|
||||||
|
func (e *Event) Bool(key string, b bool) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendBool(enc.AppendKey(e.buf, key), b)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bools adds the field key with val as a []bool to the *Event context.
|
||||||
|
func (e *Event) Bools(key string, b []bool) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendBools(enc.AppendKey(e.buf, key), b)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int adds the field key with i as a int to the *Event context.
|
||||||
|
func (e *Event) Int(key string, i int) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInt(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints adds the field key with i as a []int to the *Event context.
|
||||||
|
func (e *Event) Ints(key string, i []int) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInts(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8 adds the field key with i as a int8 to the *Event context.
|
||||||
|
func (e *Event) Int8(key string, i int8) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInt8(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints8 adds the field key with i as a []int8 to the *Event context.
|
||||||
|
func (e *Event) Ints8(key string, i []int8) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInts8(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16 adds the field key with i as a int16 to the *Event context.
|
||||||
|
func (e *Event) Int16(key string, i int16) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInt16(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints16 adds the field key with i as a []int16 to the *Event context.
|
||||||
|
func (e *Event) Ints16(key string, i []int16) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInts16(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32 adds the field key with i as a int32 to the *Event context.
|
||||||
|
func (e *Event) Int32(key string, i int32) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInt32(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints32 adds the field key with i as a []int32 to the *Event context.
|
||||||
|
func (e *Event) Ints32(key string, i []int32) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInts32(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 adds the field key with i as a int64 to the *Event context.
|
||||||
|
func (e *Event) Int64(key string, i int64) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInt64(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints64 adds the field key with i as a []int64 to the *Event context.
|
||||||
|
func (e *Event) Ints64(key string, i []int64) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInts64(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint adds the field key with i as a uint to the *Event context.
|
||||||
|
func (e *Event) Uint(key string, i uint) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUint(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints adds the field key with i as a []int to the *Event context.
|
||||||
|
func (e *Event) Uints(key string, i []uint) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUints(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8 adds the field key with i as a uint8 to the *Event context.
|
||||||
|
func (e *Event) Uint8(key string, i uint8) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUint8(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints8 adds the field key with i as a []int8 to the *Event context.
|
||||||
|
func (e *Event) Uints8(key string, i []uint8) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUints8(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16 adds the field key with i as a uint16 to the *Event context.
|
||||||
|
func (e *Event) Uint16(key string, i uint16) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUint16(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints16 adds the field key with i as a []int16 to the *Event context.
|
||||||
|
func (e *Event) Uints16(key string, i []uint16) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUints16(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32 adds the field key with i as a uint32 to the *Event context.
|
||||||
|
func (e *Event) Uint32(key string, i uint32) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUint32(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints32 adds the field key with i as a []int32 to the *Event context.
|
||||||
|
func (e *Event) Uints32(key string, i []uint32) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUints32(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 adds the field key with i as a uint64 to the *Event context.
|
||||||
|
func (e *Event) Uint64(key string, i uint64) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUint64(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uints64 adds the field key with i as a []int64 to the *Event context.
|
||||||
|
func (e *Event) Uints64(key string, i []uint64) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendUints64(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 adds the field key with f as a float32 to the *Event context.
|
||||||
|
func (e *Event) Float32(key string, f float32) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floats32 adds the field key with f as a []float32 to the *Event context.
|
||||||
|
func (e *Event) Floats32(key string, f []float32) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 adds the field key with f as a float64 to the *Event context.
|
||||||
|
func (e *Event) Float64(key string, f float64) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floats64 adds the field key with f as a []float64 to the *Event context.
|
||||||
|
func (e *Event) Floats64(key string, f []float64) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timestamp adds the current local time as UNIX timestamp to the *Event context with the "time" key.
|
||||||
|
// To customize the key name, change zerolog.TimestampFieldName.
|
||||||
|
//
|
||||||
|
// NOTE: It won't dedupe the "time" key if the *Event (or *Context) has one
|
||||||
|
// already.
|
||||||
|
func (e *Event) Timestamp() *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendTime(enc.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
||||||
|
func (e *Event) Time(key string, t time.Time) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendTime(enc.AppendKey(e.buf, key), t, TimeFieldFormat)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
|
||||||
|
func (e *Event) Times(key string, t []time.Time) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendTimes(enc.AppendKey(e.buf, key), t, TimeFieldFormat)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dur adds the field key with duration d stored as zerolog.DurationFieldUnit.
|
||||||
|
// If zerolog.DurationFieldInteger is true, durations are rendered as integer
|
||||||
|
// instead of float.
|
||||||
|
func (e *Event) Dur(key string, d time.Duration) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Durs adds the field key with duration d stored as zerolog.DurationFieldUnit.
|
||||||
|
// If zerolog.DurationFieldInteger is true, durations are rendered as integer
|
||||||
|
// instead of float.
|
||||||
|
func (e *Event) Durs(key string, d []time.Duration) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimeDiff adds the field key with positive duration between time t and start.
|
||||||
|
// If time t is not greater than start, duration will be 0.
|
||||||
|
// Duration format follows the same principle as Dur().
|
||||||
|
func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
var d time.Duration
|
||||||
|
if t.After(start) {
|
||||||
|
d = t.Sub(start)
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface adds the field key with i marshaled using reflection.
|
||||||
|
func (e *Event) Interface(key string, i interface{}) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
if obj, ok := i.(LogObjectMarshaler); ok {
|
||||||
|
return e.Object(key, obj)
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), i)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallerSkipFrame instructs any future Caller calls to skip the specified number of frames.
|
||||||
|
// This includes those added via hooks from the context.
|
||||||
|
func (e *Event) CallerSkipFrame(skip int) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.skipFrame += skip
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
|
// The argument skip is the number of stack frames to ascend
|
||||||
|
// Skip If not passed, use the global variable CallerSkipFrameCount
|
||||||
|
func (e *Event) Caller(skip ...int) *Event {
|
||||||
|
sk := CallerSkipFrameCount
|
||||||
|
if len(skip) > 0 {
|
||||||
|
sk = skip[0] + CallerSkipFrameCount
|
||||||
|
}
|
||||||
|
return e.caller(sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Event) caller(skip int) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
_, file, line, ok := runtime.Caller(skip + e.skipFrame)
|
||||||
|
if !ok {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(file, line))
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPAddr adds IPv4 or IPv6 Address to the event
|
||||||
|
func (e *Event) IPAddr(key string, ip net.IP) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendIPAddr(enc.AppendKey(e.buf, key), ip)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the event
|
||||||
|
func (e *Event) IPPrefix(key string, pfx net.IPNet) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendIPPrefix(enc.AppendKey(e.buf, key), pfx)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// MACAddr adds MAC address to the event
|
||||||
|
func (e *Event) MACAddr(key string, ha net.HardwareAddr) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = enc.AppendMACAddr(enc.AppendKey(e.buf, key), ha)
|
||||||
|
return e
|
||||||
|
}
|
277
server/vendor/github.com/rs/zerolog/fields.go
generated
vendored
Normal file
277
server/vendor/github.com/rs/zerolog/fields.go
generated
vendored
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isNilValue(i interface{}) bool {
|
||||||
|
return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendFields(dst []byte, fields interface{}) []byte {
|
||||||
|
switch fields := fields.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
if n := len(fields); n&0x1 == 1 { // odd number
|
||||||
|
fields = fields[:n-1]
|
||||||
|
}
|
||||||
|
dst = appendFieldList(dst, fields)
|
||||||
|
case map[string]interface{}:
|
||||||
|
keys := make([]string, 0, len(fields))
|
||||||
|
for key := range fields {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
kv := make([]interface{}, 2)
|
||||||
|
for _, key := range keys {
|
||||||
|
kv[0], kv[1] = key, fields[key]
|
||||||
|
dst = appendFieldList(dst, kv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendFieldList(dst []byte, kvList []interface{}) []byte {
|
||||||
|
for i, n := 0, len(kvList); i < n; i += 2 {
|
||||||
|
key, val := kvList[i], kvList[i+1]
|
||||||
|
if key, ok := key.(string); ok {
|
||||||
|
dst = enc.AppendKey(dst, key)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if val, ok := val.(LogObjectMarshaler); ok {
|
||||||
|
e := newEvent(nil, 0)
|
||||||
|
e.buf = e.buf[:0]
|
||||||
|
e.appendObject(val)
|
||||||
|
dst = append(dst, e.buf...)
|
||||||
|
putEvent(e)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch val := val.(type) {
|
||||||
|
case string:
|
||||||
|
dst = enc.AppendString(dst, val)
|
||||||
|
case []byte:
|
||||||
|
dst = enc.AppendBytes(dst, val)
|
||||||
|
case error:
|
||||||
|
switch m := ErrorMarshalFunc(val).(type) {
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
e := newEvent(nil, 0)
|
||||||
|
e.buf = e.buf[:0]
|
||||||
|
e.appendObject(m)
|
||||||
|
dst = append(dst, e.buf...)
|
||||||
|
putEvent(e)
|
||||||
|
case error:
|
||||||
|
if m == nil || isNilValue(m) {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendString(dst, m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
dst = enc.AppendString(dst, m)
|
||||||
|
default:
|
||||||
|
dst = enc.AppendInterface(dst, m)
|
||||||
|
}
|
||||||
|
case []error:
|
||||||
|
dst = enc.AppendArrayStart(dst)
|
||||||
|
for i, err := range val {
|
||||||
|
switch m := ErrorMarshalFunc(err).(type) {
|
||||||
|
case LogObjectMarshaler:
|
||||||
|
e := newEvent(nil, 0)
|
||||||
|
e.buf = e.buf[:0]
|
||||||
|
e.appendObject(m)
|
||||||
|
dst = append(dst, e.buf...)
|
||||||
|
putEvent(e)
|
||||||
|
case error:
|
||||||
|
if m == nil || isNilValue(m) {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendString(dst, m.Error())
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
dst = enc.AppendString(dst, m)
|
||||||
|
default:
|
||||||
|
dst = enc.AppendInterface(dst, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
if i < (len(val) - 1) {
|
||||||
|
enc.AppendArrayDelim(dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = enc.AppendArrayEnd(dst)
|
||||||
|
case bool:
|
||||||
|
dst = enc.AppendBool(dst, val)
|
||||||
|
case int:
|
||||||
|
dst = enc.AppendInt(dst, val)
|
||||||
|
case int8:
|
||||||
|
dst = enc.AppendInt8(dst, val)
|
||||||
|
case int16:
|
||||||
|
dst = enc.AppendInt16(dst, val)
|
||||||
|
case int32:
|
||||||
|
dst = enc.AppendInt32(dst, val)
|
||||||
|
case int64:
|
||||||
|
dst = enc.AppendInt64(dst, val)
|
||||||
|
case uint:
|
||||||
|
dst = enc.AppendUint(dst, val)
|
||||||
|
case uint8:
|
||||||
|
dst = enc.AppendUint8(dst, val)
|
||||||
|
case uint16:
|
||||||
|
dst = enc.AppendUint16(dst, val)
|
||||||
|
case uint32:
|
||||||
|
dst = enc.AppendUint32(dst, val)
|
||||||
|
case uint64:
|
||||||
|
dst = enc.AppendUint64(dst, val)
|
||||||
|
case float32:
|
||||||
|
dst = enc.AppendFloat32(dst, val)
|
||||||
|
case float64:
|
||||||
|
dst = enc.AppendFloat64(dst, val)
|
||||||
|
case time.Time:
|
||||||
|
dst = enc.AppendTime(dst, val, TimeFieldFormat)
|
||||||
|
case time.Duration:
|
||||||
|
dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
case *string:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendString(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *bool:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendBool(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *int:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendInt(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *int8:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendInt8(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *int16:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendInt16(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *int32:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendInt32(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *int64:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendInt64(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *uint:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendUint(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *uint8:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendUint8(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *uint16:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendUint16(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *uint32:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendUint32(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *uint64:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendUint64(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *float32:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendFloat32(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *float64:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendFloat64(dst, *val)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *time.Time:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendTime(dst, *val, TimeFieldFormat)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case *time.Duration:
|
||||||
|
if val != nil {
|
||||||
|
dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
} else {
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
}
|
||||||
|
case []string:
|
||||||
|
dst = enc.AppendStrings(dst, val)
|
||||||
|
case []bool:
|
||||||
|
dst = enc.AppendBools(dst, val)
|
||||||
|
case []int:
|
||||||
|
dst = enc.AppendInts(dst, val)
|
||||||
|
case []int8:
|
||||||
|
dst = enc.AppendInts8(dst, val)
|
||||||
|
case []int16:
|
||||||
|
dst = enc.AppendInts16(dst, val)
|
||||||
|
case []int32:
|
||||||
|
dst = enc.AppendInts32(dst, val)
|
||||||
|
case []int64:
|
||||||
|
dst = enc.AppendInts64(dst, val)
|
||||||
|
case []uint:
|
||||||
|
dst = enc.AppendUints(dst, val)
|
||||||
|
// case []uint8:
|
||||||
|
// dst = enc.AppendUints8(dst, val)
|
||||||
|
case []uint16:
|
||||||
|
dst = enc.AppendUints16(dst, val)
|
||||||
|
case []uint32:
|
||||||
|
dst = enc.AppendUints32(dst, val)
|
||||||
|
case []uint64:
|
||||||
|
dst = enc.AppendUints64(dst, val)
|
||||||
|
case []float32:
|
||||||
|
dst = enc.AppendFloats32(dst, val)
|
||||||
|
case []float64:
|
||||||
|
dst = enc.AppendFloats64(dst, val)
|
||||||
|
case []time.Time:
|
||||||
|
dst = enc.AppendTimes(dst, val, TimeFieldFormat)
|
||||||
|
case []time.Duration:
|
||||||
|
dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger)
|
||||||
|
case nil:
|
||||||
|
dst = enc.AppendNil(dst)
|
||||||
|
case net.IP:
|
||||||
|
dst = enc.AppendIPAddr(dst, val)
|
||||||
|
case net.IPNet:
|
||||||
|
dst = enc.AppendIPPrefix(dst, val)
|
||||||
|
case net.HardwareAddr:
|
||||||
|
dst = enc.AppendMACAddr(dst, val)
|
||||||
|
case json.RawMessage:
|
||||||
|
dst = appendJSON(dst, val)
|
||||||
|
default:
|
||||||
|
dst = enc.AppendInterface(dst, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
138
server/vendor/github.com/rs/zerolog/globals.go
generated
vendored
Normal file
138
server/vendor/github.com/rs/zerolog/globals.go
generated
vendored
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TimeFormatUnix defines a time format that makes time fields to be
|
||||||
|
// serialized as Unix timestamp integers.
|
||||||
|
TimeFormatUnix = ""
|
||||||
|
|
||||||
|
// TimeFormatUnixMs defines a time format that makes time fields to be
|
||||||
|
// serialized as Unix timestamp integers in milliseconds.
|
||||||
|
TimeFormatUnixMs = "UNIXMS"
|
||||||
|
|
||||||
|
// TimeFormatUnixMicro defines a time format that makes time fields to be
|
||||||
|
// serialized as Unix timestamp integers in microseconds.
|
||||||
|
TimeFormatUnixMicro = "UNIXMICRO"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// TimestampFieldName is the field name used for the timestamp field.
|
||||||
|
TimestampFieldName = "time"
|
||||||
|
|
||||||
|
// LevelFieldName is the field name used for the level field.
|
||||||
|
LevelFieldName = "level"
|
||||||
|
|
||||||
|
// LevelTraceValue is the value used for the trace level field.
|
||||||
|
LevelTraceValue = "trace"
|
||||||
|
// LevelDebugValue is the value used for the debug level field.
|
||||||
|
LevelDebugValue = "debug"
|
||||||
|
// LevelInfoValue is the value used for the info level field.
|
||||||
|
LevelInfoValue = "info"
|
||||||
|
// LevelWarnValue is the value used for the warn level field.
|
||||||
|
LevelWarnValue = "warn"
|
||||||
|
// LevelErrorValue is the value used for the error level field.
|
||||||
|
LevelErrorValue = "error"
|
||||||
|
// LevelFatalValue is the value used for the fatal level field.
|
||||||
|
LevelFatalValue = "fatal"
|
||||||
|
// LevelPanicValue is the value used for the panic level field.
|
||||||
|
LevelPanicValue = "panic"
|
||||||
|
|
||||||
|
// LevelFieldMarshalFunc allows customization of global level field marshaling.
|
||||||
|
LevelFieldMarshalFunc = func(l Level) string {
|
||||||
|
return l.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageFieldName is the field name used for the message field.
|
||||||
|
MessageFieldName = "message"
|
||||||
|
|
||||||
|
// ErrorFieldName is the field name used for error fields.
|
||||||
|
ErrorFieldName = "error"
|
||||||
|
|
||||||
|
// CallerFieldName is the field name used for caller field.
|
||||||
|
CallerFieldName = "caller"
|
||||||
|
|
||||||
|
// CallerSkipFrameCount is the number of stack frames to skip to find the caller.
|
||||||
|
CallerSkipFrameCount = 2
|
||||||
|
|
||||||
|
// CallerMarshalFunc allows customization of global caller marshaling
|
||||||
|
CallerMarshalFunc = func(file string, line int) string {
|
||||||
|
return file + ":" + strconv.Itoa(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorStackFieldName is the field name used for error stacks.
|
||||||
|
ErrorStackFieldName = "stack"
|
||||||
|
|
||||||
|
// ErrorStackMarshaler extract the stack from err if any.
|
||||||
|
ErrorStackMarshaler func(err error) interface{}
|
||||||
|
|
||||||
|
// ErrorMarshalFunc allows customization of global error marshaling
|
||||||
|
ErrorMarshalFunc = func(err error) interface{} {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterfaceMarshalFunc allows customization of interface marshaling.
|
||||||
|
// Default: "encoding/json.Marshal"
|
||||||
|
InterfaceMarshalFunc = json.Marshal
|
||||||
|
|
||||||
|
// TimeFieldFormat defines the time format of the Time field type. If set to
|
||||||
|
// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX
|
||||||
|
// timestamp as integer.
|
||||||
|
TimeFieldFormat = time.RFC3339
|
||||||
|
|
||||||
|
// TimestampFunc defines the function called to generate a timestamp.
|
||||||
|
TimestampFunc = time.Now
|
||||||
|
|
||||||
|
// DurationFieldUnit defines the unit for time.Duration type fields added
|
||||||
|
// using the Dur method.
|
||||||
|
DurationFieldUnit = time.Millisecond
|
||||||
|
|
||||||
|
// DurationFieldInteger renders Dur fields as integer instead of float if
|
||||||
|
// set to true.
|
||||||
|
DurationFieldInteger = false
|
||||||
|
|
||||||
|
// ErrorHandler is called whenever zerolog fails to write an event on its
|
||||||
|
// output. If not set, an error is printed on the stderr. This handler must
|
||||||
|
// be thread safe and non-blocking.
|
||||||
|
ErrorHandler func(err error)
|
||||||
|
|
||||||
|
// DefaultContextLogger is returned from Ctx() if there is no logger associated
|
||||||
|
// with the context.
|
||||||
|
DefaultContextLogger *Logger
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
gLevel = new(int32)
|
||||||
|
disableSampling = new(int32)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetGlobalLevel sets the global override for log level. If this
|
||||||
|
// values is raised, all Loggers will use at least this value.
|
||||||
|
//
|
||||||
|
// To globally disable logs, set GlobalLevel to Disabled.
|
||||||
|
func SetGlobalLevel(l Level) {
|
||||||
|
atomic.StoreInt32(gLevel, int32(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalLevel returns the current global log level
|
||||||
|
func GlobalLevel() Level {
|
||||||
|
return Level(atomic.LoadInt32(gLevel))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableSampling will disable sampling in all Loggers if true.
|
||||||
|
func DisableSampling(v bool) {
|
||||||
|
var i int32
|
||||||
|
if v {
|
||||||
|
i = 1
|
||||||
|
}
|
||||||
|
atomic.StoreInt32(disableSampling, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func samplingDisabled() bool {
|
||||||
|
return atomic.LoadInt32(disableSampling) == 1
|
||||||
|
}
|
7
server/vendor/github.com/rs/zerolog/go112.go
generated
vendored
Normal file
7
server/vendor/github.com/rs/zerolog/go112.go
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// +build go1.12
|
||||||
|
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
// Since go 1.12, some auto generated init functions are hidden from
|
||||||
|
// runtime.Caller.
|
||||||
|
const contextCallerSkipFrameCount = 2
|
64
server/vendor/github.com/rs/zerolog/hook.go
generated
vendored
Normal file
64
server/vendor/github.com/rs/zerolog/hook.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
// Hook defines an interface to a log hook.
|
||||||
|
type Hook interface {
|
||||||
|
// Run runs the hook with the event.
|
||||||
|
Run(e *Event, level Level, message string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HookFunc is an adaptor to allow the use of an ordinary function
|
||||||
|
// as a Hook.
|
||||||
|
type HookFunc func(e *Event, level Level, message string)
|
||||||
|
|
||||||
|
// Run implements the Hook interface.
|
||||||
|
func (h HookFunc) Run(e *Event, level Level, message string) {
|
||||||
|
h(e, level, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LevelHook applies a different hook for each level.
|
||||||
|
type LevelHook struct {
|
||||||
|
NoLevelHook, TraceHook, DebugHook, InfoHook, WarnHook, ErrorHook, FatalHook, PanicHook Hook
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run implements the Hook interface.
|
||||||
|
func (h LevelHook) Run(e *Event, level Level, message string) {
|
||||||
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
if h.TraceHook != nil {
|
||||||
|
h.TraceHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case DebugLevel:
|
||||||
|
if h.DebugHook != nil {
|
||||||
|
h.DebugHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case InfoLevel:
|
||||||
|
if h.InfoHook != nil {
|
||||||
|
h.InfoHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case WarnLevel:
|
||||||
|
if h.WarnHook != nil {
|
||||||
|
h.WarnHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case ErrorLevel:
|
||||||
|
if h.ErrorHook != nil {
|
||||||
|
h.ErrorHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case FatalLevel:
|
||||||
|
if h.FatalHook != nil {
|
||||||
|
h.FatalHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case PanicLevel:
|
||||||
|
if h.PanicHook != nil {
|
||||||
|
h.PanicHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
case NoLevel:
|
||||||
|
if h.NoLevelHook != nil {
|
||||||
|
h.NoLevelHook.Run(e, level, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLevelHook returns a new LevelHook.
|
||||||
|
func NewLevelHook() LevelHook {
|
||||||
|
return LevelHook{}
|
||||||
|
}
|
56
server/vendor/github.com/rs/zerolog/internal/cbor/README.md
generated
vendored
Normal file
56
server/vendor/github.com/rs/zerolog/internal/cbor/README.md
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
## Reference:
|
||||||
|
CBOR Encoding is described in [RFC7049](https://tools.ietf.org/html/rfc7049)
|
||||||
|
|
||||||
|
## Comparison of JSON vs CBOR
|
||||||
|
|
||||||
|
Two main areas of reduction are:
|
||||||
|
|
||||||
|
1. CPU usage to write a log msg
|
||||||
|
2. Size (in bytes) of log messages.
|
||||||
|
|
||||||
|
|
||||||
|
CPU Usage savings are below:
|
||||||
|
```
|
||||||
|
name JSON time/op CBOR time/op delta
|
||||||
|
Info-32 15.3ns ± 1% 11.7ns ± 3% -23.78% (p=0.000 n=9+10)
|
||||||
|
ContextFields-32 16.2ns ± 2% 12.3ns ± 3% -23.97% (p=0.000 n=9+9)
|
||||||
|
ContextAppend-32 6.70ns ± 0% 6.20ns ± 0% -7.44% (p=0.000 n=9+9)
|
||||||
|
LogFields-32 66.4ns ± 0% 24.6ns ± 2% -62.89% (p=0.000 n=10+9)
|
||||||
|
LogArrayObject-32 911ns ±11% 768ns ± 6% -15.64% (p=0.000 n=10+10)
|
||||||
|
LogFieldType/Floats-32 70.3ns ± 2% 29.5ns ± 1% -57.98% (p=0.000 n=10+10)
|
||||||
|
LogFieldType/Err-32 14.0ns ± 3% 12.1ns ± 8% -13.20% (p=0.000 n=8+10)
|
||||||
|
LogFieldType/Dur-32 17.2ns ± 2% 13.1ns ± 1% -24.27% (p=0.000 n=10+9)
|
||||||
|
LogFieldType/Object-32 54.3ns ±11% 52.3ns ± 7% ~ (p=0.239 n=10+10)
|
||||||
|
LogFieldType/Ints-32 20.3ns ± 2% 15.1ns ± 2% -25.50% (p=0.000 n=9+10)
|
||||||
|
LogFieldType/Interfaces-32 642ns ±11% 621ns ± 9% ~ (p=0.118 n=10+10)
|
||||||
|
LogFieldType/Interface(Objects)-32 635ns ±13% 632ns ± 9% ~ (p=0.592 n=10+10)
|
||||||
|
LogFieldType/Times-32 294ns ± 0% 27ns ± 1% -90.71% (p=0.000 n=10+9)
|
||||||
|
LogFieldType/Durs-32 121ns ± 0% 33ns ± 2% -72.44% (p=0.000 n=9+9)
|
||||||
|
LogFieldType/Interface(Object)-32 56.6ns ± 8% 52.3ns ± 8% -7.54% (p=0.007 n=10+10)
|
||||||
|
LogFieldType/Errs-32 17.8ns ± 3% 16.1ns ± 2% -9.71% (p=0.000 n=10+9)
|
||||||
|
LogFieldType/Time-32 40.5ns ± 1% 12.7ns ± 6% -68.66% (p=0.000 n=8+9)
|
||||||
|
LogFieldType/Bool-32 12.0ns ± 5% 10.2ns ± 2% -15.18% (p=0.000 n=10+8)
|
||||||
|
LogFieldType/Bools-32 17.2ns ± 2% 12.6ns ± 4% -26.63% (p=0.000 n=10+10)
|
||||||
|
LogFieldType/Int-32 12.3ns ± 2% 11.2ns ± 4% -9.27% (p=0.000 n=9+10)
|
||||||
|
LogFieldType/Float-32 16.7ns ± 1% 12.6ns ± 2% -24.42% (p=0.000 n=7+9)
|
||||||
|
LogFieldType/Str-32 12.7ns ± 7% 11.3ns ± 7% -10.88% (p=0.000 n=10+9)
|
||||||
|
LogFieldType/Strs-32 20.3ns ± 3% 18.2ns ± 3% -10.25% (p=0.000 n=9+10)
|
||||||
|
LogFieldType/Interface-32 183ns ±12% 175ns ± 9% ~ (p=0.078 n=10+10)
|
||||||
|
```
|
||||||
|
|
||||||
|
Log message size savings is greatly dependent on the number and type of fields in the log message.
|
||||||
|
Assuming this log message (with an Integer, timestamp and string, in addition to level).
|
||||||
|
|
||||||
|
`{"level":"error","Fault":41650,"time":"2018-04-01T15:18:19-07:00","message":"Some Message"}`
|
||||||
|
|
||||||
|
Two measurements were done for the log file sizes - one without any compression, second
|
||||||
|
using [compress/zlib](https://golang.org/pkg/compress/zlib/).
|
||||||
|
|
||||||
|
Results for 10,000 log messages:
|
||||||
|
|
||||||
|
| Log Format | Plain File Size (in KB) | Compressed File Size (in KB) |
|
||||||
|
| :--- | :---: | :---: |
|
||||||
|
| JSON | 920 | 28 |
|
||||||
|
| CBOR | 550 | 28 |
|
||||||
|
|
||||||
|
The example used to calculate the above data is available in [Examples](examples).
|
19
server/vendor/github.com/rs/zerolog/internal/cbor/base.go
generated
vendored
Normal file
19
server/vendor/github.com/rs/zerolog/internal/cbor/base.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package cbor
|
||||||
|
|
||||||
|
// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
|
||||||
|
// Making it package level instead of embedded in Encoder brings
|
||||||
|
// some extra efforts at importing, but avoids value copy when the functions
|
||||||
|
// of Encoder being invoked.
|
||||||
|
// DO REMEMBER to set this variable at importing, or
|
||||||
|
// you might get a nil pointer dereference panic at runtime.
|
||||||
|
var JSONMarshalFunc func(v interface{}) ([]byte, error)
|
||||||
|
|
||||||
|
type Encoder struct{}
|
||||||
|
|
||||||
|
// AppendKey adds a key (string) to the binary encoded log message
|
||||||
|
func (e Encoder) AppendKey(dst []byte, key string) []byte {
|
||||||
|
if len(dst) < 1 {
|
||||||
|
dst = e.AppendBeginMarker(dst)
|
||||||
|
}
|
||||||
|
return e.AppendString(dst, key)
|
||||||
|
}
|
100
server/vendor/github.com/rs/zerolog/internal/cbor/cbor.go
generated
vendored
Normal file
100
server/vendor/github.com/rs/zerolog/internal/cbor/cbor.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Package cbor provides primitives for storing different data
|
||||||
|
// in the CBOR (binary) format. CBOR is defined in RFC7049.
|
||||||
|
package cbor
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
const (
|
||||||
|
majorOffset = 5
|
||||||
|
additionalMax = 23
|
||||||
|
|
||||||
|
// Non Values.
|
||||||
|
additionalTypeBoolFalse byte = 20
|
||||||
|
additionalTypeBoolTrue byte = 21
|
||||||
|
additionalTypeNull byte = 22
|
||||||
|
|
||||||
|
// Integer (+ve and -ve) Sub-types.
|
||||||
|
additionalTypeIntUint8 byte = 24
|
||||||
|
additionalTypeIntUint16 byte = 25
|
||||||
|
additionalTypeIntUint32 byte = 26
|
||||||
|
additionalTypeIntUint64 byte = 27
|
||||||
|
|
||||||
|
// Float Sub-types.
|
||||||
|
additionalTypeFloat16 byte = 25
|
||||||
|
additionalTypeFloat32 byte = 26
|
||||||
|
additionalTypeFloat64 byte = 27
|
||||||
|
additionalTypeBreak byte = 31
|
||||||
|
|
||||||
|
// Tag Sub-types.
|
||||||
|
additionalTypeTimestamp byte = 01
|
||||||
|
|
||||||
|
// Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
|
||||||
|
additionalTypeTagNetworkAddr uint16 = 260
|
||||||
|
additionalTypeTagNetworkPrefix uint16 = 261
|
||||||
|
additionalTypeEmbeddedJSON uint16 = 262
|
||||||
|
additionalTypeTagHexString uint16 = 263
|
||||||
|
|
||||||
|
// Unspecified number of elements.
|
||||||
|
additionalTypeInfiniteCount byte = 31
|
||||||
|
)
|
||||||
|
const (
|
||||||
|
majorTypeUnsignedInt byte = iota << majorOffset // Major type 0
|
||||||
|
majorTypeNegativeInt // Major type 1
|
||||||
|
majorTypeByteString // Major type 2
|
||||||
|
majorTypeUtf8String // Major type 3
|
||||||
|
majorTypeArray // Major type 4
|
||||||
|
majorTypeMap // Major type 5
|
||||||
|
majorTypeTags // Major type 6
|
||||||
|
majorTypeSimpleAndFloat // Major type 7
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
maskOutAdditionalType byte = (7 << majorOffset)
|
||||||
|
maskOutMajorType byte = 31
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
float32Nan = "\xfa\x7f\xc0\x00\x00"
|
||||||
|
float32PosInfinity = "\xfa\x7f\x80\x00\x00"
|
||||||
|
float32NegInfinity = "\xfa\xff\x80\x00\x00"
|
||||||
|
float64Nan = "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00"
|
||||||
|
float64PosInfinity = "\xfb\x7f\xf0\x00\x00\x00\x00\x00\x00"
|
||||||
|
float64NegInfinity = "\xfb\xff\xf0\x00\x00\x00\x00\x00\x00"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IntegerTimeFieldFormat indicates the format of timestamp decoded
|
||||||
|
// from an integer (time in seconds).
|
||||||
|
var IntegerTimeFieldFormat = time.RFC3339
|
||||||
|
|
||||||
|
// NanoTimeFieldFormat indicates the format of timestamp decoded
|
||||||
|
// from a float value (time in seconds and nano seconds).
|
||||||
|
var NanoTimeFieldFormat = time.RFC3339Nano
|
||||||
|
|
||||||
|
func appendCborTypePrefix(dst []byte, major byte, number uint64) []byte {
|
||||||
|
byteCount := 8
|
||||||
|
var minor byte
|
||||||
|
switch {
|
||||||
|
case number < 256:
|
||||||
|
byteCount = 1
|
||||||
|
minor = additionalTypeIntUint8
|
||||||
|
|
||||||
|
case number < 65536:
|
||||||
|
byteCount = 2
|
||||||
|
minor = additionalTypeIntUint16
|
||||||
|
|
||||||
|
case number < 4294967296:
|
||||||
|
byteCount = 4
|
||||||
|
minor = additionalTypeIntUint32
|
||||||
|
|
||||||
|
default:
|
||||||
|
byteCount = 8
|
||||||
|
minor = additionalTypeIntUint64
|
||||||
|
|
||||||
|
}
|
||||||
|
dst = append(dst, byte(major|minor))
|
||||||
|
byteCount--
|
||||||
|
for ; byteCount >= 0; byteCount-- {
|
||||||
|
dst = append(dst, byte(number>>(uint(byteCount)*8)))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
614
server/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go
generated
vendored
Normal file
614
server/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go
generated
vendored
Normal file
|
@ -0,0 +1,614 @@
|
||||||
|
package cbor
|
||||||
|
|
||||||
|
// This file contains code to decode a stream of CBOR Data into JSON.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
var decodeTimeZone *time.Location
|
||||||
|
|
||||||
|
const hexTable = "0123456789abcdef"
|
||||||
|
|
||||||
|
const isFloat32 = 4
|
||||||
|
const isFloat64 = 8
|
||||||
|
|
||||||
|
func readNBytes(src *bufio.Reader, n int) []byte {
|
||||||
|
ret := make([]byte, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
ch, e := src.ReadByte()
|
||||||
|
if e != nil {
|
||||||
|
panic(fmt.Errorf("Tried to Read %d Bytes.. But hit end of file", n))
|
||||||
|
}
|
||||||
|
ret[i] = ch
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func readByte(src *bufio.Reader) byte {
|
||||||
|
b, e := src.ReadByte()
|
||||||
|
if e != nil {
|
||||||
|
panic(fmt.Errorf("Tried to Read 1 Byte.. But hit end of file"))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIntAdditonalType(src *bufio.Reader, minor byte) int64 {
|
||||||
|
val := int64(0)
|
||||||
|
if minor <= 23 {
|
||||||
|
val = int64(minor)
|
||||||
|
} else {
|
||||||
|
bytesToRead := 0
|
||||||
|
switch minor {
|
||||||
|
case additionalTypeIntUint8:
|
||||||
|
bytesToRead = 1
|
||||||
|
case additionalTypeIntUint16:
|
||||||
|
bytesToRead = 2
|
||||||
|
case additionalTypeIntUint32:
|
||||||
|
bytesToRead = 4
|
||||||
|
case additionalTypeIntUint64:
|
||||||
|
bytesToRead = 8
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("Invalid Additional Type: %d in decodeInteger (expected <28)", minor))
|
||||||
|
}
|
||||||
|
pb := readNBytes(src, bytesToRead)
|
||||||
|
for i := 0; i < bytesToRead; i++ {
|
||||||
|
val = val * 256
|
||||||
|
val += int64(pb[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeInteger(src *bufio.Reader) int64 {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeUnsignedInt && major != majorTypeNegativeInt {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in decodeInteger!! (expected 0 or 1)", major))
|
||||||
|
}
|
||||||
|
val := decodeIntAdditonalType(src, minor)
|
||||||
|
if major == 0 {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
return (-1 - val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeFloat(src *bufio.Reader) (float64, int) {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeSimpleAndFloat {
|
||||||
|
panic(fmt.Errorf("Incorrect Major type is: %d in decodeFloat", major))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch minor {
|
||||||
|
case additionalTypeFloat16:
|
||||||
|
panic(fmt.Errorf("float16 is not suppported in decodeFloat"))
|
||||||
|
|
||||||
|
case additionalTypeFloat32:
|
||||||
|
pb := readNBytes(src, 4)
|
||||||
|
switch string(pb) {
|
||||||
|
case float32Nan:
|
||||||
|
return math.NaN(), isFloat32
|
||||||
|
case float32PosInfinity:
|
||||||
|
return math.Inf(0), isFloat32
|
||||||
|
case float32NegInfinity:
|
||||||
|
return math.Inf(-1), isFloat32
|
||||||
|
}
|
||||||
|
n := uint32(0)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
n = n * 256
|
||||||
|
n += uint32(pb[i])
|
||||||
|
}
|
||||||
|
val := math.Float32frombits(n)
|
||||||
|
return float64(val), isFloat32
|
||||||
|
case additionalTypeFloat64:
|
||||||
|
pb := readNBytes(src, 8)
|
||||||
|
switch string(pb) {
|
||||||
|
case float64Nan:
|
||||||
|
return math.NaN(), isFloat64
|
||||||
|
case float64PosInfinity:
|
||||||
|
return math.Inf(0), isFloat64
|
||||||
|
case float64NegInfinity:
|
||||||
|
return math.Inf(-1), isFloat64
|
||||||
|
}
|
||||||
|
n := uint64(0)
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
n = n * 256
|
||||||
|
n += uint64(pb[i])
|
||||||
|
}
|
||||||
|
val := math.Float64frombits(n)
|
||||||
|
return val, isFloat64
|
||||||
|
}
|
||||||
|
panic(fmt.Errorf("Invalid Additional Type: %d in decodeFloat", minor))
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeStringComplex(dst []byte, s string, pos uint) []byte {
|
||||||
|
i := int(pos)
|
||||||
|
start := 0
|
||||||
|
|
||||||
|
for i < len(s) {
|
||||||
|
b := s[i]
|
||||||
|
if b >= utf8.RuneSelf {
|
||||||
|
r, size := utf8.DecodeRuneInString(s[i:])
|
||||||
|
if r == utf8.RuneError && size == 1 {
|
||||||
|
// In case of error, first append previous simple characters to
|
||||||
|
// the byte slice if any and append a replacement character code
|
||||||
|
// in place of the invalid sequence.
|
||||||
|
if start < i {
|
||||||
|
dst = append(dst, s[start:i]...)
|
||||||
|
}
|
||||||
|
dst = append(dst, `\ufffd`...)
|
||||||
|
i += size
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i += size
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if b >= 0x20 && b <= 0x7e && b != '\\' && b != '"' {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// We encountered a character that needs to be encoded.
|
||||||
|
// Let's append the previous simple characters to the byte slice
|
||||||
|
// and switch our operation to read and encode the remainder
|
||||||
|
// characters byte-by-byte.
|
||||||
|
if start < i {
|
||||||
|
dst = append(dst, s[start:i]...)
|
||||||
|
}
|
||||||
|
switch b {
|
||||||
|
case '"', '\\':
|
||||||
|
dst = append(dst, '\\', b)
|
||||||
|
case '\b':
|
||||||
|
dst = append(dst, '\\', 'b')
|
||||||
|
case '\f':
|
||||||
|
dst = append(dst, '\\', 'f')
|
||||||
|
case '\n':
|
||||||
|
dst = append(dst, '\\', 'n')
|
||||||
|
case '\r':
|
||||||
|
dst = append(dst, '\\', 'r')
|
||||||
|
case '\t':
|
||||||
|
dst = append(dst, '\\', 't')
|
||||||
|
default:
|
||||||
|
dst = append(dst, '\\', 'u', '0', '0', hexTable[b>>4], hexTable[b&0xF])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
}
|
||||||
|
if start < len(s) {
|
||||||
|
dst = append(dst, s[start:]...)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeString(src *bufio.Reader, noQuotes bool) []byte {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeByteString {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in decodeString", major))
|
||||||
|
}
|
||||||
|
result := []byte{}
|
||||||
|
if !noQuotes {
|
||||||
|
result = append(result, '"')
|
||||||
|
}
|
||||||
|
length := decodeIntAdditonalType(src, minor)
|
||||||
|
len := int(length)
|
||||||
|
pbs := readNBytes(src, len)
|
||||||
|
result = append(result, pbs...)
|
||||||
|
if noQuotes {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
return append(result, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeUTF8String(src *bufio.Reader) []byte {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeUtf8String {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in decodeUTF8String", major))
|
||||||
|
}
|
||||||
|
result := []byte{'"'}
|
||||||
|
length := decodeIntAdditonalType(src, minor)
|
||||||
|
len := int(length)
|
||||||
|
pbs := readNBytes(src, len)
|
||||||
|
|
||||||
|
for i := 0; i < len; i++ {
|
||||||
|
// Check if the character needs encoding. Control characters, slashes,
|
||||||
|
// and the double quote need json encoding. Bytes above the ascii
|
||||||
|
// boundary needs utf8 encoding.
|
||||||
|
if pbs[i] < 0x20 || pbs[i] > 0x7e || pbs[i] == '\\' || pbs[i] == '"' {
|
||||||
|
// We encountered a character that needs to be encoded. Switch
|
||||||
|
// to complex version of the algorithm.
|
||||||
|
dst := []byte{'"'}
|
||||||
|
dst = decodeStringComplex(dst, string(pbs), uint(i))
|
||||||
|
return append(dst, '"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The string has no need for encoding an therefore is directly
|
||||||
|
// appended to the byte slice.
|
||||||
|
result = append(result, pbs...)
|
||||||
|
return append(result, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
func array2Json(src *bufio.Reader, dst io.Writer) {
|
||||||
|
dst.Write([]byte{'['})
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeArray {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in array2Json", major))
|
||||||
|
}
|
||||||
|
len := 0
|
||||||
|
unSpecifiedCount := false
|
||||||
|
if minor == additionalTypeInfiniteCount {
|
||||||
|
unSpecifiedCount = true
|
||||||
|
} else {
|
||||||
|
length := decodeIntAdditonalType(src, minor)
|
||||||
|
len = int(length)
|
||||||
|
}
|
||||||
|
for i := 0; unSpecifiedCount || i < len; i++ {
|
||||||
|
if unSpecifiedCount {
|
||||||
|
pb, e := src.Peek(1)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
|
||||||
|
readByte(src)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cbor2JsonOneObject(src, dst)
|
||||||
|
if unSpecifiedCount {
|
||||||
|
pb, e := src.Peek(1)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
|
||||||
|
readByte(src)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dst.Write([]byte{','})
|
||||||
|
} else if i+1 < len {
|
||||||
|
dst.Write([]byte{','})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst.Write([]byte{']'})
|
||||||
|
}
|
||||||
|
|
||||||
|
func map2Json(src *bufio.Reader, dst io.Writer) {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeMap {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in map2Json", major))
|
||||||
|
}
|
||||||
|
len := 0
|
||||||
|
unSpecifiedCount := false
|
||||||
|
if minor == additionalTypeInfiniteCount {
|
||||||
|
unSpecifiedCount = true
|
||||||
|
} else {
|
||||||
|
length := decodeIntAdditonalType(src, minor)
|
||||||
|
len = int(length)
|
||||||
|
}
|
||||||
|
dst.Write([]byte{'{'})
|
||||||
|
for i := 0; unSpecifiedCount || i < len; i++ {
|
||||||
|
if unSpecifiedCount {
|
||||||
|
pb, e := src.Peek(1)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
|
||||||
|
readByte(src)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cbor2JsonOneObject(src, dst)
|
||||||
|
if i%2 == 0 {
|
||||||
|
// Even position values are keys.
|
||||||
|
dst.Write([]byte{':'})
|
||||||
|
} else {
|
||||||
|
if unSpecifiedCount {
|
||||||
|
pb, e := src.Peek(1)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
if pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
|
||||||
|
readByte(src)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dst.Write([]byte{','})
|
||||||
|
} else if i+1 < len {
|
||||||
|
dst.Write([]byte{','})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst.Write([]byte{'}'})
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeTagData(src *bufio.Reader) []byte {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeTags {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in decodeTagData", major))
|
||||||
|
}
|
||||||
|
switch minor {
|
||||||
|
case additionalTypeTimestamp:
|
||||||
|
return decodeTimeStamp(src)
|
||||||
|
|
||||||
|
// Tag value is larger than 256 (so uint16).
|
||||||
|
case additionalTypeIntUint16:
|
||||||
|
val := decodeIntAdditonalType(src, minor)
|
||||||
|
|
||||||
|
switch uint16(val) {
|
||||||
|
case additionalTypeEmbeddedJSON:
|
||||||
|
pb := readByte(src)
|
||||||
|
dataMajor := pb & maskOutAdditionalType
|
||||||
|
if dataMajor != majorTypeByteString {
|
||||||
|
panic(fmt.Errorf("Unsupported embedded Type: %d in decodeEmbeddedJSON", dataMajor))
|
||||||
|
}
|
||||||
|
src.UnreadByte()
|
||||||
|
return decodeString(src, true)
|
||||||
|
|
||||||
|
case additionalTypeTagNetworkAddr:
|
||||||
|
octets := decodeString(src, true)
|
||||||
|
ss := []byte{'"'}
|
||||||
|
switch len(octets) {
|
||||||
|
case 6: // MAC address.
|
||||||
|
ha := net.HardwareAddr(octets)
|
||||||
|
ss = append(append(ss, ha.String()...), '"')
|
||||||
|
case 4: // IPv4 address.
|
||||||
|
fallthrough
|
||||||
|
case 16: // IPv6 address.
|
||||||
|
ip := net.IP(octets)
|
||||||
|
ss = append(append(ss, ip.String()...), '"')
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("Unexpected Network Address length: %d (expected 4,6,16)", len(octets)))
|
||||||
|
}
|
||||||
|
return ss
|
||||||
|
|
||||||
|
case additionalTypeTagNetworkPrefix:
|
||||||
|
pb := readByte(src)
|
||||||
|
if pb != byte(majorTypeMap|0x1) {
|
||||||
|
panic(fmt.Errorf("IP Prefix is NOT of MAP of 1 elements as expected"))
|
||||||
|
}
|
||||||
|
octets := decodeString(src, true)
|
||||||
|
val := decodeInteger(src)
|
||||||
|
ip := net.IP(octets)
|
||||||
|
var mask net.IPMask
|
||||||
|
pfxLen := int(val)
|
||||||
|
if len(octets) == 4 {
|
||||||
|
mask = net.CIDRMask(pfxLen, 32)
|
||||||
|
} else {
|
||||||
|
mask = net.CIDRMask(pfxLen, 128)
|
||||||
|
}
|
||||||
|
ipPfx := net.IPNet{IP: ip, Mask: mask}
|
||||||
|
ss := []byte{'"'}
|
||||||
|
ss = append(append(ss, ipPfx.String()...), '"')
|
||||||
|
return ss
|
||||||
|
|
||||||
|
case additionalTypeTagHexString:
|
||||||
|
octets := decodeString(src, true)
|
||||||
|
ss := []byte{'"'}
|
||||||
|
for _, v := range octets {
|
||||||
|
ss = append(ss, hexTable[v>>4], hexTable[v&0x0f])
|
||||||
|
}
|
||||||
|
return append(ss, '"')
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("Unsupported Additional Tag Type: %d in decodeTagData", val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic(fmt.Errorf("Unsupported Additional Type: %d in decodeTagData", minor))
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeTimeStamp(src *bufio.Reader) []byte {
|
||||||
|
pb := readByte(src)
|
||||||
|
src.UnreadByte()
|
||||||
|
tsMajor := pb & maskOutAdditionalType
|
||||||
|
if tsMajor == majorTypeUnsignedInt || tsMajor == majorTypeNegativeInt {
|
||||||
|
n := decodeInteger(src)
|
||||||
|
t := time.Unix(n, 0)
|
||||||
|
if decodeTimeZone != nil {
|
||||||
|
t = t.In(decodeTimeZone)
|
||||||
|
} else {
|
||||||
|
t = t.In(time.UTC)
|
||||||
|
}
|
||||||
|
tsb := []byte{}
|
||||||
|
tsb = append(tsb, '"')
|
||||||
|
tsb = t.AppendFormat(tsb, IntegerTimeFieldFormat)
|
||||||
|
tsb = append(tsb, '"')
|
||||||
|
return tsb
|
||||||
|
} else if tsMajor == majorTypeSimpleAndFloat {
|
||||||
|
n, _ := decodeFloat(src)
|
||||||
|
secs := int64(n)
|
||||||
|
n -= float64(secs)
|
||||||
|
n *= float64(1e9)
|
||||||
|
t := time.Unix(secs, int64(n))
|
||||||
|
if decodeTimeZone != nil {
|
||||||
|
t = t.In(decodeTimeZone)
|
||||||
|
} else {
|
||||||
|
t = t.In(time.UTC)
|
||||||
|
}
|
||||||
|
tsb := []byte{}
|
||||||
|
tsb = append(tsb, '"')
|
||||||
|
tsb = t.AppendFormat(tsb, NanoTimeFieldFormat)
|
||||||
|
tsb = append(tsb, '"')
|
||||||
|
return tsb
|
||||||
|
}
|
||||||
|
panic(fmt.Errorf("TS format is neigther int nor float: %d", tsMajor))
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSimpleFloat(src *bufio.Reader) []byte {
|
||||||
|
pb := readByte(src)
|
||||||
|
major := pb & maskOutAdditionalType
|
||||||
|
minor := pb & maskOutMajorType
|
||||||
|
if major != majorTypeSimpleAndFloat {
|
||||||
|
panic(fmt.Errorf("Major type is: %d in decodeSimpleFloat", major))
|
||||||
|
}
|
||||||
|
switch minor {
|
||||||
|
case additionalTypeBoolTrue:
|
||||||
|
return []byte("true")
|
||||||
|
case additionalTypeBoolFalse:
|
||||||
|
return []byte("false")
|
||||||
|
case additionalTypeNull:
|
||||||
|
return []byte("null")
|
||||||
|
case additionalTypeFloat16:
|
||||||
|
fallthrough
|
||||||
|
case additionalTypeFloat32:
|
||||||
|
fallthrough
|
||||||
|
case additionalTypeFloat64:
|
||||||
|
src.UnreadByte()
|
||||||
|
v, bc := decodeFloat(src)
|
||||||
|
ba := []byte{}
|
||||||
|
switch {
|
||||||
|
case math.IsNaN(v):
|
||||||
|
return []byte("\"NaN\"")
|
||||||
|
case math.IsInf(v, 1):
|
||||||
|
return []byte("\"+Inf\"")
|
||||||
|
case math.IsInf(v, -1):
|
||||||
|
return []byte("\"-Inf\"")
|
||||||
|
}
|
||||||
|
if bc == isFloat32 {
|
||||||
|
ba = strconv.AppendFloat(ba, v, 'f', -1, 32)
|
||||||
|
} else if bc == isFloat64 {
|
||||||
|
ba = strconv.AppendFloat(ba, v, 'f', -1, 64)
|
||||||
|
} else {
|
||||||
|
panic(fmt.Errorf("Invalid Float precision from decodeFloat: %d", bc))
|
||||||
|
}
|
||||||
|
return ba
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("Invalid Additional Type: %d in decodeSimpleFloat", minor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cbor2JsonOneObject(src *bufio.Reader, dst io.Writer) {
|
||||||
|
pb, e := src.Peek(1)
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
major := (pb[0] & maskOutAdditionalType)
|
||||||
|
|
||||||
|
switch major {
|
||||||
|
case majorTypeUnsignedInt:
|
||||||
|
fallthrough
|
||||||
|
case majorTypeNegativeInt:
|
||||||
|
n := decodeInteger(src)
|
||||||
|
dst.Write([]byte(strconv.Itoa(int(n))))
|
||||||
|
|
||||||
|
case majorTypeByteString:
|
||||||
|
s := decodeString(src, false)
|
||||||
|
dst.Write(s)
|
||||||
|
|
||||||
|
case majorTypeUtf8String:
|
||||||
|
s := decodeUTF8String(src)
|
||||||
|
dst.Write(s)
|
||||||
|
|
||||||
|
case majorTypeArray:
|
||||||
|
array2Json(src, dst)
|
||||||
|
|
||||||
|
case majorTypeMap:
|
||||||
|
map2Json(src, dst)
|
||||||
|
|
||||||
|
case majorTypeTags:
|
||||||
|
s := decodeTagData(src)
|
||||||
|
dst.Write(s)
|
||||||
|
|
||||||
|
case majorTypeSimpleAndFloat:
|
||||||
|
s := decodeSimpleFloat(src)
|
||||||
|
dst.Write(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func moreBytesToRead(src *bufio.Reader) bool {
|
||||||
|
_, e := src.ReadByte()
|
||||||
|
if e == nil {
|
||||||
|
src.UnreadByte()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cbor2JsonManyObjects decodes all the CBOR Objects read from src
|
||||||
|
// reader. It keeps on decoding until reader returns EOF (error when reading).
|
||||||
|
// Decoded string is written to the dst. At the end of every CBOR Object
|
||||||
|
// newline is written to the output stream.
|
||||||
|
//
|
||||||
|
// Returns error (if any) that was encountered during decode.
|
||||||
|
// The child functions will generate a panic when error is encountered and
|
||||||
|
// this function will recover non-runtime Errors and return the reason as error.
|
||||||
|
func Cbor2JsonManyObjects(src io.Reader, dst io.Writer) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
if _, ok := r.(runtime.Error); ok {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
err = r.(error)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
bufRdr := bufio.NewReader(src)
|
||||||
|
for moreBytesToRead(bufRdr) {
|
||||||
|
cbor2JsonOneObject(bufRdr, dst)
|
||||||
|
dst.Write([]byte("\n"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect if the bytes to be printed is Binary or not.
|
||||||
|
func binaryFmt(p []byte) bool {
|
||||||
|
if len(p) > 0 && p[0] > 0x7F {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func getReader(str string) *bufio.Reader {
|
||||||
|
return bufio.NewReader(strings.NewReader(str))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeIfBinaryToString converts a binary formatted log msg to a
|
||||||
|
// JSON formatted String Log message - suitable for printing to Console/Syslog.
|
||||||
|
func DecodeIfBinaryToString(in []byte) string {
|
||||||
|
if binaryFmt(in) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
Cbor2JsonManyObjects(strings.NewReader(string(in)), &b)
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
return string(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeObjectToStr checks if the input is a binary format, if so,
|
||||||
|
// it will decode a single Object and return the decoded string.
|
||||||
|
func DecodeObjectToStr(in []byte) string {
|
||||||
|
if binaryFmt(in) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
cbor2JsonOneObject(getReader(string(in)), &b)
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
return string(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeIfBinaryToBytes checks if the input is a binary format, if so,
|
||||||
|
// it will decode all Objects and return the decoded string as byte array.
|
||||||
|
func DecodeIfBinaryToBytes(in []byte) []byte {
|
||||||
|
if binaryFmt(in) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
Cbor2JsonManyObjects(bytes.NewReader(in), &b)
|
||||||
|
return b.Bytes()
|
||||||
|
}
|
||||||
|
return in
|
||||||
|
}
|
68
server/vendor/github.com/rs/zerolog/internal/cbor/string.go
generated
vendored
Normal file
68
server/vendor/github.com/rs/zerolog/internal/cbor/string.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package cbor
|
||||||
|
|
||||||
|
// AppendStrings encodes and adds an array of strings to the dst byte array.
|
||||||
|
func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendString(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendString encodes and adds a string to the dst byte array.
|
||||||
|
func (Encoder) AppendString(dst []byte, s string) []byte {
|
||||||
|
major := majorTypeUtf8String
|
||||||
|
|
||||||
|
l := len(s)
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, majorTypeUtf8String, uint64(l))
|
||||||
|
}
|
||||||
|
return append(dst, s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBytes encodes and adds an array of bytes to the dst byte array.
|
||||||
|
func (Encoder) AppendBytes(dst, s []byte) []byte {
|
||||||
|
major := majorTypeByteString
|
||||||
|
|
||||||
|
l := len(s)
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
return append(dst, s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendEmbeddedJSON adds a tag and embeds input JSON as such.
|
||||||
|
func AppendEmbeddedJSON(dst, s []byte) []byte {
|
||||||
|
major := majorTypeTags
|
||||||
|
minor := additionalTypeEmbeddedJSON
|
||||||
|
|
||||||
|
// Append the TAG to indicate this is Embedded JSON.
|
||||||
|
dst = append(dst, byte(major|additionalTypeIntUint16))
|
||||||
|
dst = append(dst, byte(minor>>8))
|
||||||
|
dst = append(dst, byte(minor&0xff))
|
||||||
|
|
||||||
|
// Append the JSON Object as Byte String.
|
||||||
|
major = majorTypeByteString
|
||||||
|
|
||||||
|
l := len(s)
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
return append(dst, s...)
|
||||||
|
}
|
93
server/vendor/github.com/rs/zerolog/internal/cbor/time.go
generated
vendored
Normal file
93
server/vendor/github.com/rs/zerolog/internal/cbor/time.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
package cbor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func appendIntegerTimestamp(dst []byte, t time.Time) []byte {
|
||||||
|
major := majorTypeTags
|
||||||
|
minor := additionalTypeTimestamp
|
||||||
|
dst = append(dst, byte(major|minor))
|
||||||
|
secs := t.Unix()
|
||||||
|
var val uint64
|
||||||
|
if secs < 0 {
|
||||||
|
major = majorTypeNegativeInt
|
||||||
|
val = uint64(-secs - 1)
|
||||||
|
} else {
|
||||||
|
major = majorTypeUnsignedInt
|
||||||
|
val = uint64(secs)
|
||||||
|
}
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(val))
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Encoder) appendFloatTimestamp(dst []byte, t time.Time) []byte {
|
||||||
|
major := majorTypeTags
|
||||||
|
minor := additionalTypeTimestamp
|
||||||
|
dst = append(dst, byte(major|minor))
|
||||||
|
secs := t.Unix()
|
||||||
|
nanos := t.Nanosecond()
|
||||||
|
var val float64
|
||||||
|
val = float64(secs)*1.0 + float64(nanos)*1E-9
|
||||||
|
return e.AppendFloat64(dst, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendTime encodes and adds a timestamp to the dst byte array.
|
||||||
|
func (e Encoder) AppendTime(dst []byte, t time.Time, unused string) []byte {
|
||||||
|
utc := t.UTC()
|
||||||
|
if utc.Nanosecond() == 0 {
|
||||||
|
return appendIntegerTimestamp(dst, utc)
|
||||||
|
}
|
||||||
|
return e.appendFloatTimestamp(dst, utc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendTimes encodes and adds an array of timestamps to the dst byte array.
|
||||||
|
func (e Encoder) AppendTimes(dst []byte, vals []time.Time, unused string) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range vals {
|
||||||
|
dst = e.AppendTime(dst, t, unused)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendDuration encodes and adds a duration to the dst byte array.
|
||||||
|
// useInt field indicates whether to store the duration as seconds (integer) or
|
||||||
|
// as seconds+nanoseconds (float).
|
||||||
|
func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
|
||||||
|
if useInt {
|
||||||
|
return e.AppendInt64(dst, int64(d/unit))
|
||||||
|
}
|
||||||
|
return e.AppendFloat64(dst, float64(d)/float64(unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendDurations encodes and adds an array of durations to the dst byte array.
|
||||||
|
// useInt field indicates whether to store the duration as seconds (integer) or
|
||||||
|
// as seconds+nanoseconds (float).
|
||||||
|
func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, d := range vals {
|
||||||
|
dst = e.AppendDuration(dst, d, unit, useInt)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
477
server/vendor/github.com/rs/zerolog/internal/cbor/types.go
generated
vendored
Normal file
477
server/vendor/github.com/rs/zerolog/internal/cbor/types.go
generated
vendored
Normal file
|
@ -0,0 +1,477 @@
|
||||||
|
package cbor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AppendNil inserts a 'Nil' object into the dst byte array.
|
||||||
|
func (Encoder) AppendNil(dst []byte) []byte {
|
||||||
|
return append(dst, byte(majorTypeSimpleAndFloat|additionalTypeNull))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBeginMarker inserts a map start into the dst byte array.
|
||||||
|
func (Encoder) AppendBeginMarker(dst []byte) []byte {
|
||||||
|
return append(dst, byte(majorTypeMap|additionalTypeInfiniteCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendEndMarker inserts a map end into the dst byte array.
|
||||||
|
func (Encoder) AppendEndMarker(dst []byte) []byte {
|
||||||
|
return append(dst, byte(majorTypeSimpleAndFloat|additionalTypeBreak))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendObjectData takes an object in form of a byte array and appends to dst.
|
||||||
|
func (Encoder) AppendObjectData(dst []byte, o []byte) []byte {
|
||||||
|
// BeginMarker is present in the dst, which
|
||||||
|
// should not be copied when appending to existing data.
|
||||||
|
return append(dst, o[1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendArrayStart adds markers to indicate the start of an array.
|
||||||
|
func (Encoder) AppendArrayStart(dst []byte) []byte {
|
||||||
|
return append(dst, byte(majorTypeArray|additionalTypeInfiniteCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendArrayEnd adds markers to indicate the end of an array.
|
||||||
|
func (Encoder) AppendArrayEnd(dst []byte) []byte {
|
||||||
|
return append(dst, byte(majorTypeSimpleAndFloat|additionalTypeBreak))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendArrayDelim adds markers to indicate end of a particular array element.
|
||||||
|
func (Encoder) AppendArrayDelim(dst []byte) []byte {
|
||||||
|
//No delimiters needed in cbor
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendLineBreak is a noop that keep API compat with json encoder.
|
||||||
|
func (Encoder) AppendLineBreak(dst []byte) []byte {
|
||||||
|
// No line breaks needed in binary format.
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBool encodes and inserts a boolean value into the dst byte array.
|
||||||
|
func (Encoder) AppendBool(dst []byte, val bool) []byte {
|
||||||
|
b := additionalTypeBoolFalse
|
||||||
|
if val {
|
||||||
|
b = additionalTypeBoolTrue
|
||||||
|
}
|
||||||
|
return append(dst, byte(majorTypeSimpleAndFloat|b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBools encodes and inserts an array of boolean values into the dst byte array.
|
||||||
|
func (e Encoder) AppendBools(dst []byte, vals []bool) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendBool(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt encodes and inserts an integer value into the dst byte array.
|
||||||
|
func (Encoder) AppendInt(dst []byte, val int) []byte {
|
||||||
|
major := majorTypeUnsignedInt
|
||||||
|
contentVal := val
|
||||||
|
if val < 0 {
|
||||||
|
major = majorTypeNegativeInt
|
||||||
|
contentVal = -val - 1
|
||||||
|
}
|
||||||
|
if contentVal <= additionalMax {
|
||||||
|
lb := byte(contentVal)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(contentVal))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts encodes and inserts an array of integer values into the dst byte array.
|
||||||
|
func (e Encoder) AppendInts(dst []byte, vals []int) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendInt(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt8 encodes and inserts an int8 value into the dst byte array.
|
||||||
|
func (e Encoder) AppendInt8(dst []byte, val int8) []byte {
|
||||||
|
return e.AppendInt(dst, int(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts8 encodes and inserts an array of integer values into the dst byte array.
|
||||||
|
func (e Encoder) AppendInts8(dst []byte, vals []int8) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendInt(dst, int(v))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt16 encodes and inserts a int16 value into the dst byte array.
|
||||||
|
func (e Encoder) AppendInt16(dst []byte, val int16) []byte {
|
||||||
|
return e.AppendInt(dst, int(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts16 encodes and inserts an array of int16 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendInts16(dst []byte, vals []int16) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendInt(dst, int(v))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt32 encodes and inserts a int32 value into the dst byte array.
|
||||||
|
func (e Encoder) AppendInt32(dst []byte, val int32) []byte {
|
||||||
|
return e.AppendInt(dst, int(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts32 encodes and inserts an array of int32 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendInts32(dst []byte, vals []int32) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendInt(dst, int(v))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt64 encodes and inserts a int64 value into the dst byte array.
|
||||||
|
func (Encoder) AppendInt64(dst []byte, val int64) []byte {
|
||||||
|
major := majorTypeUnsignedInt
|
||||||
|
contentVal := val
|
||||||
|
if val < 0 {
|
||||||
|
major = majorTypeNegativeInt
|
||||||
|
contentVal = -val - 1
|
||||||
|
}
|
||||||
|
if contentVal <= additionalMax {
|
||||||
|
lb := byte(contentVal)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(contentVal))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts64 encodes and inserts an array of int64 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendInts64(dst []byte, vals []int64) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendInt64(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint encodes and inserts an unsigned integer value into the dst byte array.
|
||||||
|
func (e Encoder) AppendUint(dst []byte, val uint) []byte {
|
||||||
|
return e.AppendInt64(dst, int64(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints encodes and inserts an array of unsigned integer values into the dst byte array.
|
||||||
|
func (e Encoder) AppendUints(dst []byte, vals []uint) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendUint(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint8 encodes and inserts a unsigned int8 value into the dst byte array.
|
||||||
|
func (e Encoder) AppendUint8(dst []byte, val uint8) []byte {
|
||||||
|
return e.AppendUint(dst, uint(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints8 encodes and inserts an array of uint8 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendUints8(dst []byte, vals []uint8) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendUint8(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint16 encodes and inserts a uint16 value into the dst byte array.
|
||||||
|
func (e Encoder) AppendUint16(dst []byte, val uint16) []byte {
|
||||||
|
return e.AppendUint(dst, uint(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints16 encodes and inserts an array of uint16 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendUints16(dst []byte, vals []uint16) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendUint16(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint32 encodes and inserts a uint32 value into the dst byte array.
|
||||||
|
func (e Encoder) AppendUint32(dst []byte, val uint32) []byte {
|
||||||
|
return e.AppendUint(dst, uint(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints32 encodes and inserts an array of uint32 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendUints32(dst []byte, vals []uint32) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendUint32(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint64 encodes and inserts a uint64 value into the dst byte array.
|
||||||
|
func (Encoder) AppendUint64(dst []byte, val uint64) []byte {
|
||||||
|
major := majorTypeUnsignedInt
|
||||||
|
contentVal := val
|
||||||
|
if contentVal <= additionalMax {
|
||||||
|
lb := byte(contentVal)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(contentVal))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints64 encodes and inserts an array of uint64 values into the dst byte array.
|
||||||
|
func (e Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendUint64(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloat32 encodes and inserts a single precision float value into the dst byte array.
|
||||||
|
func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
|
||||||
|
switch {
|
||||||
|
case math.IsNaN(float64(val)):
|
||||||
|
return append(dst, "\xfa\x7f\xc0\x00\x00"...)
|
||||||
|
case math.IsInf(float64(val), 1):
|
||||||
|
return append(dst, "\xfa\x7f\x80\x00\x00"...)
|
||||||
|
case math.IsInf(float64(val), -1):
|
||||||
|
return append(dst, "\xfa\xff\x80\x00\x00"...)
|
||||||
|
}
|
||||||
|
major := majorTypeSimpleAndFloat
|
||||||
|
subType := additionalTypeFloat32
|
||||||
|
n := math.Float32bits(val)
|
||||||
|
var buf [4]byte
|
||||||
|
for i := uint(0); i < 4; i++ {
|
||||||
|
buf[i] = byte(n >> ((3 - i) * 8))
|
||||||
|
}
|
||||||
|
return append(append(dst, byte(major|subType)), buf[0], buf[1], buf[2], buf[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloats32 encodes and inserts an array of single precision float value into the dst byte array.
|
||||||
|
func (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendFloat32(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloat64 encodes and inserts a double precision float value into the dst byte array.
|
||||||
|
func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
|
||||||
|
switch {
|
||||||
|
case math.IsNaN(val):
|
||||||
|
return append(dst, "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00"...)
|
||||||
|
case math.IsInf(val, 1):
|
||||||
|
return append(dst, "\xfb\x7f\xf0\x00\x00\x00\x00\x00\x00"...)
|
||||||
|
case math.IsInf(val, -1):
|
||||||
|
return append(dst, "\xfb\xff\xf0\x00\x00\x00\x00\x00\x00"...)
|
||||||
|
}
|
||||||
|
major := majorTypeSimpleAndFloat
|
||||||
|
subType := additionalTypeFloat64
|
||||||
|
n := math.Float64bits(val)
|
||||||
|
dst = append(dst, byte(major|subType))
|
||||||
|
for i := uint(1); i <= 8; i++ {
|
||||||
|
b := byte(n >> ((8 - i) * 8))
|
||||||
|
dst = append(dst, b)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloats64 encodes and inserts an array of double precision float values into the dst byte array.
|
||||||
|
func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
|
||||||
|
major := majorTypeArray
|
||||||
|
l := len(vals)
|
||||||
|
if l == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
if l <= additionalMax {
|
||||||
|
lb := byte(l)
|
||||||
|
dst = append(dst, byte(major|lb))
|
||||||
|
} else {
|
||||||
|
dst = appendCborTypePrefix(dst, major, uint64(l))
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
dst = e.AppendFloat64(dst, v)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst.
|
||||||
|
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
|
||||||
|
marshaled, err := JSONMarshalFunc(i)
|
||||||
|
if err != nil {
|
||||||
|
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
||||||
|
}
|
||||||
|
return AppendEmbeddedJSON(dst, marshaled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendIPAddr encodes and inserts an IP Address (IPv4 or IPv6).
|
||||||
|
func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {
|
||||||
|
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))
|
||||||
|
dst = append(dst, byte(additionalTypeTagNetworkAddr>>8))
|
||||||
|
dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff))
|
||||||
|
return e.AppendBytes(dst, ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendIPPrefix encodes and inserts an IP Address Prefix (Address + Mask Length).
|
||||||
|
func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte {
|
||||||
|
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))
|
||||||
|
dst = append(dst, byte(additionalTypeTagNetworkPrefix>>8))
|
||||||
|
dst = append(dst, byte(additionalTypeTagNetworkPrefix&0xff))
|
||||||
|
|
||||||
|
// Prefix is a tuple (aka MAP of 1 pair of elements) -
|
||||||
|
// first element is prefix, second is mask length.
|
||||||
|
dst = append(dst, byte(majorTypeMap|0x1))
|
||||||
|
dst = e.AppendBytes(dst, pfx.IP)
|
||||||
|
maskLen, _ := pfx.Mask.Size()
|
||||||
|
return e.AppendUint8(dst, uint8(maskLen))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendMACAddr encodes and inserts an Hardware (MAC) address.
|
||||||
|
func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {
|
||||||
|
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))
|
||||||
|
dst = append(dst, byte(additionalTypeTagNetworkAddr>>8))
|
||||||
|
dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff))
|
||||||
|
return e.AppendBytes(dst, ha)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendHex adds a TAG and inserts a hex bytes as a string.
|
||||||
|
func (e Encoder) AppendHex(dst []byte, val []byte) []byte {
|
||||||
|
dst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))
|
||||||
|
dst = append(dst, byte(additionalTypeTagHexString>>8))
|
||||||
|
dst = append(dst, byte(additionalTypeTagHexString&0xff))
|
||||||
|
return e.AppendBytes(dst, val)
|
||||||
|
}
|
19
server/vendor/github.com/rs/zerolog/internal/json/base.go
generated
vendored
Normal file
19
server/vendor/github.com/rs/zerolog/internal/json/base.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
|
||||||
|
// Making it package level instead of embedded in Encoder brings
|
||||||
|
// some extra efforts at importing, but avoids value copy when the functions
|
||||||
|
// of Encoder being invoked.
|
||||||
|
// DO REMEMBER to set this variable at importing, or
|
||||||
|
// you might get a nil pointer dereference panic at runtime.
|
||||||
|
var JSONMarshalFunc func(v interface{}) ([]byte, error)
|
||||||
|
|
||||||
|
type Encoder struct{}
|
||||||
|
|
||||||
|
// AppendKey appends a new key to the output JSON.
|
||||||
|
func (e Encoder) AppendKey(dst []byte, key string) []byte {
|
||||||
|
if dst[len(dst)-1] != '{' {
|
||||||
|
dst = append(dst, ',')
|
||||||
|
}
|
||||||
|
return append(e.AppendString(dst, key), ':')
|
||||||
|
}
|
85
server/vendor/github.com/rs/zerolog/internal/json/bytes.go
generated
vendored
Normal file
85
server/vendor/github.com/rs/zerolog/internal/json/bytes.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// AppendBytes is a mirror of appendString with []byte arg
|
||||||
|
func (Encoder) AppendBytes(dst, s []byte) []byte {
|
||||||
|
dst = append(dst, '"')
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if !noEscapeTable[s[i]] {
|
||||||
|
dst = appendBytesComplex(dst, s, i)
|
||||||
|
return append(dst, '"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, s...)
|
||||||
|
return append(dst, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendHex encodes the input bytes to a hex string and appends
|
||||||
|
// the encoded string to the input byte slice.
|
||||||
|
//
|
||||||
|
// The operation loops though each byte and encodes it as hex using
|
||||||
|
// the hex lookup table.
|
||||||
|
func (Encoder) AppendHex(dst, s []byte) []byte {
|
||||||
|
dst = append(dst, '"')
|
||||||
|
for _, v := range s {
|
||||||
|
dst = append(dst, hex[v>>4], hex[v&0x0f])
|
||||||
|
}
|
||||||
|
return append(dst, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
// appendBytesComplex is a mirror of the appendStringComplex
|
||||||
|
// with []byte arg
|
||||||
|
func appendBytesComplex(dst, s []byte, i int) []byte {
|
||||||
|
start := 0
|
||||||
|
for i < len(s) {
|
||||||
|
b := s[i]
|
||||||
|
if b >= utf8.RuneSelf {
|
||||||
|
r, size := utf8.DecodeRune(s[i:])
|
||||||
|
if r == utf8.RuneError && size == 1 {
|
||||||
|
if start < i {
|
||||||
|
dst = append(dst, s[start:i]...)
|
||||||
|
}
|
||||||
|
dst = append(dst, `\ufffd`...)
|
||||||
|
i += size
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i += size
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if noEscapeTable[b] {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// We encountered a character that needs to be encoded.
|
||||||
|
// Let's append the previous simple characters to the byte slice
|
||||||
|
// and switch our operation to read and encode the remainder
|
||||||
|
// characters byte-by-byte.
|
||||||
|
if start < i {
|
||||||
|
dst = append(dst, s[start:i]...)
|
||||||
|
}
|
||||||
|
switch b {
|
||||||
|
case '"', '\\':
|
||||||
|
dst = append(dst, '\\', b)
|
||||||
|
case '\b':
|
||||||
|
dst = append(dst, '\\', 'b')
|
||||||
|
case '\f':
|
||||||
|
dst = append(dst, '\\', 'f')
|
||||||
|
case '\n':
|
||||||
|
dst = append(dst, '\\', 'n')
|
||||||
|
case '\r':
|
||||||
|
dst = append(dst, '\\', 'r')
|
||||||
|
case '\t':
|
||||||
|
dst = append(dst, '\\', 't')
|
||||||
|
default:
|
||||||
|
dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
}
|
||||||
|
if start < len(s) {
|
||||||
|
dst = append(dst, s[start:]...)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
121
server/vendor/github.com/rs/zerolog/internal/json/string.go
generated
vendored
Normal file
121
server/vendor/github.com/rs/zerolog/internal/json/string.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
const hex = "0123456789abcdef"
|
||||||
|
|
||||||
|
var noEscapeTable = [256]bool{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
for i := 0; i <= 0x7e; i++ {
|
||||||
|
noEscapeTable[i] = i >= 0x20 && i != '\\' && i != '"'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendStrings encodes the input strings to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = e.AppendString(dst, vals[0])
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = e.AppendString(append(dst, ','), val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendString encodes the input string to json and appends
|
||||||
|
// the encoded string to the input byte slice.
|
||||||
|
//
|
||||||
|
// The operation loops though each byte in the string looking
|
||||||
|
// for characters that need json or utf8 encoding. If the string
|
||||||
|
// does not need encoding, then the string is appended in it's
|
||||||
|
// entirety to the byte slice.
|
||||||
|
// If we encounter a byte that does need encoding, switch up
|
||||||
|
// the operation and perform a byte-by-byte read-encode-append.
|
||||||
|
func (Encoder) AppendString(dst []byte, s string) []byte {
|
||||||
|
// Start with a double quote.
|
||||||
|
dst = append(dst, '"')
|
||||||
|
// Loop through each character in the string.
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
// Check if the character needs encoding. Control characters, slashes,
|
||||||
|
// and the double quote need json encoding. Bytes above the ascii
|
||||||
|
// boundary needs utf8 encoding.
|
||||||
|
if !noEscapeTable[s[i]] {
|
||||||
|
// We encountered a character that needs to be encoded. Switch
|
||||||
|
// to complex version of the algorithm.
|
||||||
|
dst = appendStringComplex(dst, s, i)
|
||||||
|
return append(dst, '"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The string has no need for encoding an therefore is directly
|
||||||
|
// appended to the byte slice.
|
||||||
|
dst = append(dst, s...)
|
||||||
|
// End with a double quote
|
||||||
|
return append(dst, '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
// appendStringComplex is used by appendString to take over an in
|
||||||
|
// progress JSON string encoding that encountered a character that needs
|
||||||
|
// to be encoded.
|
||||||
|
func appendStringComplex(dst []byte, s string, i int) []byte {
|
||||||
|
start := 0
|
||||||
|
for i < len(s) {
|
||||||
|
b := s[i]
|
||||||
|
if b >= utf8.RuneSelf {
|
||||||
|
r, size := utf8.DecodeRuneInString(s[i:])
|
||||||
|
if r == utf8.RuneError && size == 1 {
|
||||||
|
// In case of error, first append previous simple characters to
|
||||||
|
// the byte slice if any and append a remplacement character code
|
||||||
|
// in place of the invalid sequence.
|
||||||
|
if start < i {
|
||||||
|
dst = append(dst, s[start:i]...)
|
||||||
|
}
|
||||||
|
dst = append(dst, `\ufffd`...)
|
||||||
|
i += size
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i += size
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if noEscapeTable[b] {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// We encountered a character that needs to be encoded.
|
||||||
|
// Let's append the previous simple characters to the byte slice
|
||||||
|
// and switch our operation to read and encode the remainder
|
||||||
|
// characters byte-by-byte.
|
||||||
|
if start < i {
|
||||||
|
dst = append(dst, s[start:i]...)
|
||||||
|
}
|
||||||
|
switch b {
|
||||||
|
case '"', '\\':
|
||||||
|
dst = append(dst, '\\', b)
|
||||||
|
case '\b':
|
||||||
|
dst = append(dst, '\\', 'b')
|
||||||
|
case '\f':
|
||||||
|
dst = append(dst, '\\', 'f')
|
||||||
|
case '\n':
|
||||||
|
dst = append(dst, '\\', 'n')
|
||||||
|
case '\r':
|
||||||
|
dst = append(dst, '\\', 'r')
|
||||||
|
case '\t':
|
||||||
|
dst = append(dst, '\\', 't')
|
||||||
|
default:
|
||||||
|
dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
}
|
||||||
|
if start < len(s) {
|
||||||
|
dst = append(dst, s[start:]...)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
106
server/vendor/github.com/rs/zerolog/internal/json/time.go
generated
vendored
Normal file
106
server/vendor/github.com/rs/zerolog/internal/json/time.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Import from zerolog/global.go
|
||||||
|
timeFormatUnix = ""
|
||||||
|
timeFormatUnixMs = "UNIXMS"
|
||||||
|
timeFormatUnixMicro = "UNIXMICRO"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AppendTime formats the input time with the given format
|
||||||
|
// and appends the encoded string to the input byte slice.
|
||||||
|
func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte {
|
||||||
|
switch format {
|
||||||
|
case timeFormatUnix:
|
||||||
|
return e.AppendInt64(dst, t.Unix())
|
||||||
|
case timeFormatUnixMs:
|
||||||
|
return e.AppendInt64(dst, t.UnixNano()/1000000)
|
||||||
|
case timeFormatUnixMicro:
|
||||||
|
return e.AppendInt64(dst, t.UnixNano()/1000)
|
||||||
|
}
|
||||||
|
return append(t.AppendFormat(append(dst, '"'), format), '"')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendTimes converts the input times with the given format
|
||||||
|
// and appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte {
|
||||||
|
switch format {
|
||||||
|
case timeFormatUnix:
|
||||||
|
return appendUnixTimes(dst, vals)
|
||||||
|
case timeFormatUnixMs:
|
||||||
|
return appendUnixMsTimes(dst, vals)
|
||||||
|
}
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = append(vals[0].AppendFormat(append(dst, '"'), format), '"')
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, t := range vals[1:] {
|
||||||
|
dst = append(t.AppendFormat(append(dst, ',', '"'), format), '"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUnixTimes(dst []byte, vals []time.Time) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, vals[0].Unix(), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, t := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), t.Unix(), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUnixMsTimes(dst []byte, vals []time.Time) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, vals[0].UnixNano()/1000000, 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, t := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), t.UnixNano()/1000000, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendDuration formats the input duration with the given unit & format
|
||||||
|
// and appends the encoded string to the input byte slice.
|
||||||
|
func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
|
||||||
|
if useInt {
|
||||||
|
return strconv.AppendInt(dst, int64(d/unit), 10)
|
||||||
|
}
|
||||||
|
return e.AppendFloat64(dst, float64(d)/float64(unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendDurations formats the input durations with the given unit & format
|
||||||
|
// and appends the encoded string list to the input byte slice.
|
||||||
|
func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = e.AppendDuration(dst, vals[0], unit, useInt)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, d := range vals[1:] {
|
||||||
|
dst = e.AppendDuration(append(dst, ','), d, unit, useInt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
405
server/vendor/github.com/rs/zerolog/internal/json/types.go
generated
vendored
Normal file
405
server/vendor/github.com/rs/zerolog/internal/json/types.go
generated
vendored
Normal file
|
@ -0,0 +1,405 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AppendNil inserts a 'Nil' object into the dst byte array.
|
||||||
|
func (Encoder) AppendNil(dst []byte) []byte {
|
||||||
|
return append(dst, "null"...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBeginMarker inserts a map start into the dst byte array.
|
||||||
|
func (Encoder) AppendBeginMarker(dst []byte) []byte {
|
||||||
|
return append(dst, '{')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendEndMarker inserts a map end into the dst byte array.
|
||||||
|
func (Encoder) AppendEndMarker(dst []byte) []byte {
|
||||||
|
return append(dst, '}')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendLineBreak appends a line break.
|
||||||
|
func (Encoder) AppendLineBreak(dst []byte) []byte {
|
||||||
|
return append(dst, '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendArrayStart adds markers to indicate the start of an array.
|
||||||
|
func (Encoder) AppendArrayStart(dst []byte) []byte {
|
||||||
|
return append(dst, '[')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendArrayEnd adds markers to indicate the end of an array.
|
||||||
|
func (Encoder) AppendArrayEnd(dst []byte) []byte {
|
||||||
|
return append(dst, ']')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendArrayDelim adds markers to indicate end of a particular array element.
|
||||||
|
func (Encoder) AppendArrayDelim(dst []byte) []byte {
|
||||||
|
if len(dst) > 0 {
|
||||||
|
return append(dst, ',')
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBool converts the input bool to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendBool(dst []byte, val bool) []byte {
|
||||||
|
return strconv.AppendBool(dst, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendBools encodes the input bools to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendBools(dst []byte, vals []bool) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendBool(dst, vals[0])
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendBool(append(dst, ','), val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt converts the input int to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendInt(dst []byte, val int) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts encodes the input ints to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendInts(dst []byte, vals []int) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt8 converts the input []int8 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendInt8(dst []byte, val int8) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts8 encodes the input int8s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendInts8(dst []byte, vals []int8) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt16 converts the input int16 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendInt16(dst []byte, val int16) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts16 encodes the input int16s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendInts16(dst []byte, vals []int16) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt32 converts the input int32 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendInt32(dst []byte, val int32) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts32 encodes the input int32s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendInts32(dst []byte, vals []int32) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, int64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInt64 converts the input int64 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendInt64(dst []byte, val int64) []byte {
|
||||||
|
return strconv.AppendInt(dst, val, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInts64 encodes the input int64s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendInts64(dst []byte, vals []int64) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendInt(dst, vals[0], 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendInt(append(dst, ','), val, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint converts the input uint to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendUint(dst []byte, val uint) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints encodes the input uints to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendUints(dst []byte, vals []uint) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint8 converts the input uint8 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendUint8(dst []byte, val uint8) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints8 encodes the input uint8s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendUints8(dst []byte, vals []uint8) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint16 converts the input uint16 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendUint16(dst []byte, val uint16) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints16 encodes the input uint16s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendUints16(dst []byte, vals []uint16) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint32 converts the input uint32 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendUint32(dst []byte, val uint32) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints32 encodes the input uint32s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendUints32(dst []byte, vals []uint32) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUint64 converts the input uint64 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendUint64(dst []byte, val uint64) []byte {
|
||||||
|
return strconv.AppendUint(dst, uint64(val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUints64 encodes the input uint64s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = strconv.AppendUint(dst, vals[0], 10)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = strconv.AppendUint(append(dst, ','), val, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendFloat(dst []byte, val float64, bitSize int) []byte {
|
||||||
|
// JSON does not permit NaN or Infinity. A typical JSON encoder would fail
|
||||||
|
// with an error, but a logging library wants the data to get thru so we
|
||||||
|
// make a tradeoff and store those types as string.
|
||||||
|
switch {
|
||||||
|
case math.IsNaN(val):
|
||||||
|
return append(dst, `"NaN"`...)
|
||||||
|
case math.IsInf(val, 1):
|
||||||
|
return append(dst, `"+Inf"`...)
|
||||||
|
case math.IsInf(val, -1):
|
||||||
|
return append(dst, `"-Inf"`...)
|
||||||
|
}
|
||||||
|
return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloat32 converts the input float32 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
|
||||||
|
return appendFloat(dst, float64(val), 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloats32 encodes the input float32s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = appendFloat(dst, float64(vals[0]), 32)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = appendFloat(append(dst, ','), float64(val), 32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloat64 converts the input float64 to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
|
||||||
|
return appendFloat(dst, val, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendFloats64 encodes the input float64s to json and
|
||||||
|
// appends the encoded string list to the input byte slice.
|
||||||
|
func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = appendFloat(dst, vals[0], 64)
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = appendFloat(append(dst, ','), val, 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst = append(dst, ']')
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendInterface marshals the input interface to a string and
|
||||||
|
// appends the encoded string to the input byte slice.
|
||||||
|
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
|
||||||
|
marshaled, err := JSONMarshalFunc(i)
|
||||||
|
if err != nil {
|
||||||
|
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
||||||
|
}
|
||||||
|
return append(dst, marshaled...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendObjectData takes in an object that is already in a byte array
|
||||||
|
// and adds it to the dst.
|
||||||
|
func (Encoder) AppendObjectData(dst []byte, o []byte) []byte {
|
||||||
|
// Three conditions apply here:
|
||||||
|
// 1. new content starts with '{' - which should be dropped OR
|
||||||
|
// 2. new content starts with '{' - which should be replaced with ','
|
||||||
|
// to separate with existing content OR
|
||||||
|
// 3. existing content has already other fields
|
||||||
|
if o[0] == '{' {
|
||||||
|
if len(dst) > 1 {
|
||||||
|
dst = append(dst, ',')
|
||||||
|
}
|
||||||
|
o = o[1:]
|
||||||
|
} else if len(dst) > 1 {
|
||||||
|
dst = append(dst, ',')
|
||||||
|
}
|
||||||
|
return append(dst, o...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendIPAddr adds IPv4 or IPv6 address to dst.
|
||||||
|
func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {
|
||||||
|
return e.AppendString(dst, ip.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendIPPrefix adds IPv4 or IPv6 Prefix (address & mask) to dst.
|
||||||
|
func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte {
|
||||||
|
return e.AppendString(dst, pfx.String())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendMACAddr adds MAC address to dst.
|
||||||
|
func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {
|
||||||
|
return e.AppendString(dst, ha.String())
|
||||||
|
}
|
457
server/vendor/github.com/rs/zerolog/log.go
generated
vendored
Normal file
457
server/vendor/github.com/rs/zerolog/log.go
generated
vendored
Normal file
|
@ -0,0 +1,457 @@
|
||||||
|
// Package zerolog provides a lightweight logging library dedicated to JSON logging.
|
||||||
|
//
|
||||||
|
// A global Logger can be use for simple logging:
|
||||||
|
//
|
||||||
|
// import "github.com/rs/zerolog/log"
|
||||||
|
//
|
||||||
|
// log.Info().Msg("hello world")
|
||||||
|
// // Output: {"time":1494567715,"level":"info","message":"hello world"}
|
||||||
|
//
|
||||||
|
// NOTE: To import the global logger, import the "log" subpackage "github.com/rs/zerolog/log".
|
||||||
|
//
|
||||||
|
// Fields can be added to log messages:
|
||||||
|
//
|
||||||
|
// log.Info().Str("foo", "bar").Msg("hello world")
|
||||||
|
// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"}
|
||||||
|
//
|
||||||
|
// Create logger instance to manage different outputs:
|
||||||
|
//
|
||||||
|
// logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
// logger.Info().
|
||||||
|
// Str("foo", "bar").
|
||||||
|
// Msg("hello world")
|
||||||
|
// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"}
|
||||||
|
//
|
||||||
|
// Sub-loggers let you chain loggers with additional context:
|
||||||
|
//
|
||||||
|
// sublogger := log.With().Str("component": "foo").Logger()
|
||||||
|
// sublogger.Info().Msg("hello world")
|
||||||
|
// // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"}
|
||||||
|
//
|
||||||
|
// Level logging
|
||||||
|
//
|
||||||
|
// zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||||
|
//
|
||||||
|
// log.Debug().Msg("filtered out message")
|
||||||
|
// log.Info().Msg("routed message")
|
||||||
|
//
|
||||||
|
// if e := log.Debug(); e.Enabled() {
|
||||||
|
// // Compute log output only if enabled.
|
||||||
|
// value := compute()
|
||||||
|
// e.Str("foo": value).Msg("some debug message")
|
||||||
|
// }
|
||||||
|
// // Output: {"level":"info","time":1494567715,"routed message"}
|
||||||
|
//
|
||||||
|
// Customize automatic field names:
|
||||||
|
//
|
||||||
|
// log.TimestampFieldName = "t"
|
||||||
|
// log.LevelFieldName = "p"
|
||||||
|
// log.MessageFieldName = "m"
|
||||||
|
//
|
||||||
|
// log.Info().Msg("hello world")
|
||||||
|
// // Output: {"t":1494567715,"p":"info","m":"hello world"}
|
||||||
|
//
|
||||||
|
// Log with no level and message:
|
||||||
|
//
|
||||||
|
// log.Log().Str("foo","bar").Msg("")
|
||||||
|
// // Output: {"time":1494567715,"foo":"bar"}
|
||||||
|
//
|
||||||
|
// Add contextual fields to global Logger:
|
||||||
|
//
|
||||||
|
// log.Logger = log.With().Str("foo", "bar").Logger()
|
||||||
|
//
|
||||||
|
// Sample logs:
|
||||||
|
//
|
||||||
|
// sampled := log.Sample(&zerolog.BasicSampler{N: 10})
|
||||||
|
// sampled.Info().Msg("will be logged every 10 messages")
|
||||||
|
//
|
||||||
|
// Log with contextual hooks:
|
||||||
|
//
|
||||||
|
// // Create the hook:
|
||||||
|
// type SeverityHook struct{}
|
||||||
|
//
|
||||||
|
// func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
|
||||||
|
// if level != zerolog.NoLevel {
|
||||||
|
// e.Str("severity", level.String())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // And use it:
|
||||||
|
// var h SeverityHook
|
||||||
|
// log := zerolog.New(os.Stdout).Hook(h)
|
||||||
|
// log.Warn().Msg("")
|
||||||
|
// // Output: {"level":"warn","severity":"warn"}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Caveats
|
||||||
|
//
|
||||||
|
// There is no fields deduplication out-of-the-box.
|
||||||
|
// Using the same key multiple times creates new key in final JSON each time.
|
||||||
|
//
|
||||||
|
// logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
// logger.Info().
|
||||||
|
// Timestamp().
|
||||||
|
// Msg("dup")
|
||||||
|
// // Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"}
|
||||||
|
//
|
||||||
|
// In this case, many consumers will take the last value,
|
||||||
|
// but this is not guaranteed; check yours if in doubt.
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Level defines log levels.
|
||||||
|
type Level int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DebugLevel defines debug log level.
|
||||||
|
DebugLevel Level = iota
|
||||||
|
// InfoLevel defines info log level.
|
||||||
|
InfoLevel
|
||||||
|
// WarnLevel defines warn log level.
|
||||||
|
WarnLevel
|
||||||
|
// ErrorLevel defines error log level.
|
||||||
|
ErrorLevel
|
||||||
|
// FatalLevel defines fatal log level.
|
||||||
|
FatalLevel
|
||||||
|
// PanicLevel defines panic log level.
|
||||||
|
PanicLevel
|
||||||
|
// NoLevel defines an absent log level.
|
||||||
|
NoLevel
|
||||||
|
// Disabled disables the logger.
|
||||||
|
Disabled
|
||||||
|
|
||||||
|
// TraceLevel defines trace log level.
|
||||||
|
TraceLevel Level = -1
|
||||||
|
// Values less than TraceLevel are handled as numbers.
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l Level) String() string {
|
||||||
|
switch l {
|
||||||
|
case TraceLevel:
|
||||||
|
return LevelTraceValue
|
||||||
|
case DebugLevel:
|
||||||
|
return LevelDebugValue
|
||||||
|
case InfoLevel:
|
||||||
|
return LevelInfoValue
|
||||||
|
case WarnLevel:
|
||||||
|
return LevelWarnValue
|
||||||
|
case ErrorLevel:
|
||||||
|
return LevelErrorValue
|
||||||
|
case FatalLevel:
|
||||||
|
return LevelFatalValue
|
||||||
|
case PanicLevel:
|
||||||
|
return LevelPanicValue
|
||||||
|
case Disabled:
|
||||||
|
return "disabled"
|
||||||
|
case NoLevel:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseLevel converts a level string into a zerolog Level value.
|
||||||
|
// returns an error if the input string does not match known values.
|
||||||
|
func ParseLevel(levelStr string) (Level, error) {
|
||||||
|
switch levelStr {
|
||||||
|
case LevelFieldMarshalFunc(TraceLevel):
|
||||||
|
return TraceLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(DebugLevel):
|
||||||
|
return DebugLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(InfoLevel):
|
||||||
|
return InfoLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(WarnLevel):
|
||||||
|
return WarnLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(ErrorLevel):
|
||||||
|
return ErrorLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(FatalLevel):
|
||||||
|
return FatalLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(PanicLevel):
|
||||||
|
return PanicLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(Disabled):
|
||||||
|
return Disabled, nil
|
||||||
|
case LevelFieldMarshalFunc(NoLevel):
|
||||||
|
return NoLevel, nil
|
||||||
|
}
|
||||||
|
i, err := strconv.Atoi(levelStr)
|
||||||
|
if err != nil {
|
||||||
|
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
|
||||||
|
}
|
||||||
|
if i > 127 || i < -128 {
|
||||||
|
return NoLevel, fmt.Errorf("Out-Of-Bounds Level: '%d', defaulting to NoLevel", i)
|
||||||
|
}
|
||||||
|
return Level(i), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Logger represents an active logging object that generates lines
|
||||||
|
// of JSON output to an io.Writer. Each logging operation makes a single
|
||||||
|
// call to the Writer's Write method. There is no guarantee on access
|
||||||
|
// serialization to the Writer. If your Writer is not thread safe,
|
||||||
|
// you may consider a sync wrapper.
|
||||||
|
type Logger struct {
|
||||||
|
w LevelWriter
|
||||||
|
level Level
|
||||||
|
sampler Sampler
|
||||||
|
context []byte
|
||||||
|
hooks []Hook
|
||||||
|
stack bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a root logger with given output writer. If the output writer implements
|
||||||
|
// the LevelWriter interface, the WriteLevel method will be called instead of the Write
|
||||||
|
// one.
|
||||||
|
//
|
||||||
|
// Each logging operation makes a single call to the Writer's Write method. There is no
|
||||||
|
// guarantee on access serialization to the Writer. If your Writer is not thread safe,
|
||||||
|
// you may consider using sync wrapper.
|
||||||
|
func New(w io.Writer) Logger {
|
||||||
|
if w == nil {
|
||||||
|
w = ioutil.Discard
|
||||||
|
}
|
||||||
|
lw, ok := w.(LevelWriter)
|
||||||
|
if !ok {
|
||||||
|
lw = levelWriterAdapter{w}
|
||||||
|
}
|
||||||
|
return Logger{w: lw, level: TraceLevel}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nop returns a disabled logger for which all operation are no-op.
|
||||||
|
func Nop() Logger {
|
||||||
|
return New(nil).Level(Disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output duplicates the current logger and sets w as its output.
|
||||||
|
func (l Logger) Output(w io.Writer) Logger {
|
||||||
|
l2 := New(w)
|
||||||
|
l2.level = l.level
|
||||||
|
l2.sampler = l.sampler
|
||||||
|
l2.stack = l.stack
|
||||||
|
if len(l.hooks) > 0 {
|
||||||
|
l2.hooks = append(l2.hooks, l.hooks...)
|
||||||
|
}
|
||||||
|
if l.context != nil {
|
||||||
|
l2.context = make([]byte, len(l.context), cap(l.context))
|
||||||
|
copy(l2.context, l.context)
|
||||||
|
}
|
||||||
|
return l2
|
||||||
|
}
|
||||||
|
|
||||||
|
// With creates a child logger with the field added to its context.
|
||||||
|
func (l Logger) With() Context {
|
||||||
|
context := l.context
|
||||||
|
l.context = make([]byte, 0, 500)
|
||||||
|
if context != nil {
|
||||||
|
l.context = append(l.context, context...)
|
||||||
|
} else {
|
||||||
|
// This is needed for AppendKey to not check len of input
|
||||||
|
// thus making it inlinable
|
||||||
|
l.context = enc.AppendBeginMarker(l.context)
|
||||||
|
}
|
||||||
|
return Context{l}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateContext updates the internal logger's context.
|
||||||
|
//
|
||||||
|
// Use this method with caution. If unsure, prefer the With method.
|
||||||
|
func (l *Logger) UpdateContext(update func(c Context) Context) {
|
||||||
|
if l == disabledLogger {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cap(l.context) == 0 {
|
||||||
|
l.context = make([]byte, 0, 500)
|
||||||
|
}
|
||||||
|
if len(l.context) == 0 {
|
||||||
|
l.context = enc.AppendBeginMarker(l.context)
|
||||||
|
}
|
||||||
|
c := update(Context{*l})
|
||||||
|
l.context = c.l.context
|
||||||
|
}
|
||||||
|
|
||||||
|
// Level creates a child logger with the minimum accepted level set to level.
|
||||||
|
func (l Logger) Level(lvl Level) Logger {
|
||||||
|
l.level = lvl
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLevel returns the current Level of l.
|
||||||
|
func (l Logger) GetLevel() Level {
|
||||||
|
return l.level
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample returns a logger with the s sampler.
|
||||||
|
func (l Logger) Sample(s Sampler) Logger {
|
||||||
|
l.sampler = s
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook returns a logger with the h Hook.
|
||||||
|
func (l Logger) Hook(h Hook) Logger {
|
||||||
|
l.hooks = append(l.hooks, h)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace starts a new message with trace level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Trace() *Event {
|
||||||
|
return l.newEvent(TraceLevel, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug starts a new message with debug level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Debug() *Event {
|
||||||
|
return l.newEvent(DebugLevel, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info starts a new message with info level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Info() *Event {
|
||||||
|
return l.newEvent(InfoLevel, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn starts a new message with warn level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Warn() *Event {
|
||||||
|
return l.newEvent(WarnLevel, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error starts a new message with error level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Error() *Event {
|
||||||
|
return l.newEvent(ErrorLevel, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err starts a new message with error level with err as a field if not nil or
|
||||||
|
// with info level if err is nil.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Err(err error) *Event {
|
||||||
|
if err != nil {
|
||||||
|
return l.Error().Err(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.Info()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal starts a new message with fatal level. The os.Exit(1) function
|
||||||
|
// is called by the Msg method, which terminates the program immediately.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Fatal() *Event {
|
||||||
|
return l.newEvent(FatalLevel, func(msg string) { os.Exit(1) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panic starts a new message with panic level. The panic() function
|
||||||
|
// is called by the Msg method, which stops the ordinary flow of a goroutine.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Panic() *Event {
|
||||||
|
return l.newEvent(PanicLevel, func(msg string) { panic(msg) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLevel starts a new message with level. Unlike Fatal and Panic
|
||||||
|
// methods, WithLevel does not terminate the program or stop the ordinary
|
||||||
|
// flow of a gourotine when used with their respective levels.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) WithLevel(level Level) *Event {
|
||||||
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
return l.Trace()
|
||||||
|
case DebugLevel:
|
||||||
|
return l.Debug()
|
||||||
|
case InfoLevel:
|
||||||
|
return l.Info()
|
||||||
|
case WarnLevel:
|
||||||
|
return l.Warn()
|
||||||
|
case ErrorLevel:
|
||||||
|
return l.Error()
|
||||||
|
case FatalLevel:
|
||||||
|
return l.newEvent(FatalLevel, nil)
|
||||||
|
case PanicLevel:
|
||||||
|
return l.newEvent(PanicLevel, nil)
|
||||||
|
case NoLevel:
|
||||||
|
return l.Log()
|
||||||
|
case Disabled:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return l.newEvent(level, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log starts a new message with no level. Setting GlobalLevel to Disabled
|
||||||
|
// will still disable events produced by this method.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func (l *Logger) Log() *Event {
|
||||||
|
return l.newEvent(NoLevel, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print sends a log event using debug level and no extra field.
|
||||||
|
// Arguments are handled in the manner of fmt.Print.
|
||||||
|
func (l *Logger) Print(v ...interface{}) {
|
||||||
|
if e := l.Debug(); e.Enabled() {
|
||||||
|
e.CallerSkipFrame(1).Msg(fmt.Sprint(v...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf sends a log event using debug level and no extra field.
|
||||||
|
// Arguments are handled in the manner of fmt.Printf.
|
||||||
|
func (l *Logger) Printf(format string, v ...interface{}) {
|
||||||
|
if e := l.Debug(); e.Enabled() {
|
||||||
|
e.CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements the io.Writer interface. This is useful to set as a writer
|
||||||
|
// for the standard library log.
|
||||||
|
func (l Logger) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
|
if n > 0 && p[n-1] == '\n' {
|
||||||
|
// Trim CR added by stdlog.
|
||||||
|
p = p[0 : n-1]
|
||||||
|
}
|
||||||
|
l.Log().CallerSkipFrame(1).Msg(string(p))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) newEvent(level Level, done func(string)) *Event {
|
||||||
|
enabled := l.should(level)
|
||||||
|
if !enabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
e := newEvent(l.w, level)
|
||||||
|
e.done = done
|
||||||
|
e.ch = l.hooks
|
||||||
|
if level != NoLevel && LevelFieldName != "" {
|
||||||
|
e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
|
||||||
|
}
|
||||||
|
if l.context != nil && len(l.context) > 1 {
|
||||||
|
e.buf = enc.AppendObjectData(e.buf, l.context)
|
||||||
|
}
|
||||||
|
if l.stack {
|
||||||
|
e.Stack()
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// should returns true if the log event should be logged.
|
||||||
|
func (l *Logger) should(lvl Level) bool {
|
||||||
|
if lvl < l.level || lvl < GlobalLevel() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if l.sampler != nil && !samplingDisabled() {
|
||||||
|
return l.sampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
131
server/vendor/github.com/rs/zerolog/log/log.go
generated
vendored
Normal file
131
server/vendor/github.com/rs/zerolog/log/log.go
generated
vendored
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
// Package log provides a global logger for zerolog.
|
||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Logger is the global logger.
|
||||||
|
var Logger = zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
|
||||||
|
// Output duplicates the global logger and sets w as its output.
|
||||||
|
func Output(w io.Writer) zerolog.Logger {
|
||||||
|
return Logger.Output(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// With creates a child logger with the field added to its context.
|
||||||
|
func With() zerolog.Context {
|
||||||
|
return Logger.With()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Level creates a child logger with the minimum accepted level set to level.
|
||||||
|
func Level(level zerolog.Level) zerolog.Logger {
|
||||||
|
return Logger.Level(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample returns a logger with the s sampler.
|
||||||
|
func Sample(s zerolog.Sampler) zerolog.Logger {
|
||||||
|
return Logger.Sample(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook returns a logger with the h Hook.
|
||||||
|
func Hook(h zerolog.Hook) zerolog.Logger {
|
||||||
|
return Logger.Hook(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err starts a new message with error level with err as a field if not nil or
|
||||||
|
// with info level if err is nil.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Err(err error) *zerolog.Event {
|
||||||
|
return Logger.Err(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace starts a new message with trace level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Trace() *zerolog.Event {
|
||||||
|
return Logger.Trace()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug starts a new message with debug level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Debug() *zerolog.Event {
|
||||||
|
return Logger.Debug()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info starts a new message with info level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Info() *zerolog.Event {
|
||||||
|
return Logger.Info()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn starts a new message with warn level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Warn() *zerolog.Event {
|
||||||
|
return Logger.Warn()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error starts a new message with error level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Error() *zerolog.Event {
|
||||||
|
return Logger.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal starts a new message with fatal level. The os.Exit(1) function
|
||||||
|
// is called by the Msg method.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Fatal() *zerolog.Event {
|
||||||
|
return Logger.Fatal()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panic starts a new message with panic level. The message is also sent
|
||||||
|
// to the panic function.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Panic() *zerolog.Event {
|
||||||
|
return Logger.Panic()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLevel starts a new message with level.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func WithLevel(level zerolog.Level) *zerolog.Event {
|
||||||
|
return Logger.WithLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log starts a new message with no level. Setting zerolog.GlobalLevel to
|
||||||
|
// zerolog.Disabled will still disable events produced by this method.
|
||||||
|
//
|
||||||
|
// You must call Msg on the returned event in order to send the event.
|
||||||
|
func Log() *zerolog.Event {
|
||||||
|
return Logger.Log()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print sends a log event using debug level and no extra field.
|
||||||
|
// Arguments are handled in the manner of fmt.Print.
|
||||||
|
func Print(v ...interface{}) {
|
||||||
|
Logger.Debug().CallerSkipFrame(1).Msg(fmt.Sprint(v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf sends a log event using debug level and no extra field.
|
||||||
|
// Arguments are handled in the manner of fmt.Printf.
|
||||||
|
func Printf(format string, v ...interface{}) {
|
||||||
|
Logger.Debug().CallerSkipFrame(1).Msgf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ctx returns the Logger associated with the ctx. If no logger
|
||||||
|
// is associated, a disabled logger is returned.
|
||||||
|
func Ctx(ctx context.Context) *zerolog.Logger {
|
||||||
|
return zerolog.Ctx(ctx)
|
||||||
|
}
|
5
server/vendor/github.com/rs/zerolog/not_go112.go
generated
vendored
Normal file
5
server/vendor/github.com/rs/zerolog/not_go112.go
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// +build !go1.12
|
||||||
|
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
const contextCallerSkipFrameCount = 3
|
BIN
server/vendor/github.com/rs/zerolog/pretty.png
generated
vendored
Normal file
BIN
server/vendor/github.com/rs/zerolog/pretty.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
134
server/vendor/github.com/rs/zerolog/sampler.go
generated
vendored
Normal file
134
server/vendor/github.com/rs/zerolog/sampler.go
generated
vendored
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Often samples log every ~ 10 events.
|
||||||
|
Often = RandomSampler(10)
|
||||||
|
// Sometimes samples log every ~ 100 events.
|
||||||
|
Sometimes = RandomSampler(100)
|
||||||
|
// Rarely samples log every ~ 1000 events.
|
||||||
|
Rarely = RandomSampler(1000)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sampler defines an interface to a log sampler.
|
||||||
|
type Sampler interface {
|
||||||
|
// Sample returns true if the event should be part of the sample, false if
|
||||||
|
// the event should be dropped.
|
||||||
|
Sample(lvl Level) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandomSampler use a PRNG to randomly sample an event out of N events,
|
||||||
|
// regardless of their level.
|
||||||
|
type RandomSampler uint32
|
||||||
|
|
||||||
|
// Sample implements the Sampler interface.
|
||||||
|
func (s RandomSampler) Sample(lvl Level) bool {
|
||||||
|
if s <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if rand.Intn(int(s)) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// BasicSampler is a sampler that will send every Nth events, regardless of
|
||||||
|
// their level.
|
||||||
|
type BasicSampler struct {
|
||||||
|
N uint32
|
||||||
|
counter uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample implements the Sampler interface.
|
||||||
|
func (s *BasicSampler) Sample(lvl Level) bool {
|
||||||
|
n := s.N
|
||||||
|
if n == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
c := atomic.AddUint32(&s.counter, 1)
|
||||||
|
return c%n == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// BurstSampler lets Burst events pass per Period then pass the decision to
|
||||||
|
// NextSampler. If Sampler is not set, all subsequent events are rejected.
|
||||||
|
type BurstSampler struct {
|
||||||
|
// Burst is the maximum number of event per period allowed before calling
|
||||||
|
// NextSampler.
|
||||||
|
Burst uint32
|
||||||
|
// Period defines the burst period. If 0, NextSampler is always called.
|
||||||
|
Period time.Duration
|
||||||
|
// NextSampler is the sampler used after the burst is reached. If nil,
|
||||||
|
// events are always rejected after the burst.
|
||||||
|
NextSampler Sampler
|
||||||
|
|
||||||
|
counter uint32
|
||||||
|
resetAt int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample implements the Sampler interface.
|
||||||
|
func (s *BurstSampler) Sample(lvl Level) bool {
|
||||||
|
if s.Burst > 0 && s.Period > 0 {
|
||||||
|
if s.inc() <= s.Burst {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.NextSampler == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return s.NextSampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *BurstSampler) inc() uint32 {
|
||||||
|
now := time.Now().UnixNano()
|
||||||
|
resetAt := atomic.LoadInt64(&s.resetAt)
|
||||||
|
var c uint32
|
||||||
|
if now > resetAt {
|
||||||
|
c = 1
|
||||||
|
atomic.StoreUint32(&s.counter, c)
|
||||||
|
newResetAt := now + s.Period.Nanoseconds()
|
||||||
|
reset := atomic.CompareAndSwapInt64(&s.resetAt, resetAt, newResetAt)
|
||||||
|
if !reset {
|
||||||
|
// Lost the race with another goroutine trying to reset.
|
||||||
|
c = atomic.AddUint32(&s.counter, 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c = atomic.AddUint32(&s.counter, 1)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// LevelSampler applies a different sampler for each level.
|
||||||
|
type LevelSampler struct {
|
||||||
|
TraceSampler, DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s LevelSampler) Sample(lvl Level) bool {
|
||||||
|
switch lvl {
|
||||||
|
case TraceLevel:
|
||||||
|
if s.TraceSampler != nil {
|
||||||
|
return s.TraceSampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
case DebugLevel:
|
||||||
|
if s.DebugSampler != nil {
|
||||||
|
return s.DebugSampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
case InfoLevel:
|
||||||
|
if s.InfoSampler != nil {
|
||||||
|
return s.InfoSampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
case WarnLevel:
|
||||||
|
if s.WarnSampler != nil {
|
||||||
|
return s.WarnSampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
case ErrorLevel:
|
||||||
|
if s.ErrorSampler != nil {
|
||||||
|
return s.ErrorSampler.Sample(lvl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
80
server/vendor/github.com/rs/zerolog/syslog.go
generated
vendored
Normal file
80
server/vendor/github.com/rs/zerolog/syslog.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// +build !windows
|
||||||
|
// +build !binary_log
|
||||||
|
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// See http://cee.mitre.org/language/1.0-beta1/clt.html#syslog
|
||||||
|
// or https://www.rsyslog.com/json-elasticsearch/
|
||||||
|
const ceePrefix = "@cee:"
|
||||||
|
|
||||||
|
// SyslogWriter is an interface matching a syslog.Writer struct.
|
||||||
|
type SyslogWriter interface {
|
||||||
|
io.Writer
|
||||||
|
Debug(m string) error
|
||||||
|
Info(m string) error
|
||||||
|
Warning(m string) error
|
||||||
|
Err(m string) error
|
||||||
|
Emerg(m string) error
|
||||||
|
Crit(m string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type syslogWriter struct {
|
||||||
|
w SyslogWriter
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level
|
||||||
|
// method matching the zerolog level.
|
||||||
|
func SyslogLevelWriter(w SyslogWriter) LevelWriter {
|
||||||
|
return syslogWriter{w, ""}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyslogCEEWriter wraps a SyslogWriter with a SyslogLevelWriter that adds a
|
||||||
|
// MITRE CEE prefix for JSON syslog entries, compatible with rsyslog
|
||||||
|
// and syslog-ng JSON logging support.
|
||||||
|
// See https://www.rsyslog.com/json-elasticsearch/
|
||||||
|
func SyslogCEEWriter(w SyslogWriter) LevelWriter {
|
||||||
|
return syslogWriter{w, ceePrefix}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sw syslogWriter) Write(p []byte) (n int, err error) {
|
||||||
|
var pn int
|
||||||
|
if sw.prefix != "" {
|
||||||
|
pn, err = sw.w.Write([]byte(sw.prefix))
|
||||||
|
if err != nil {
|
||||||
|
return pn, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err = sw.w.Write(p)
|
||||||
|
return pn + n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteLevel implements LevelWriter interface.
|
||||||
|
func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
|
||||||
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
case DebugLevel:
|
||||||
|
err = sw.w.Debug(sw.prefix + string(p))
|
||||||
|
case InfoLevel:
|
||||||
|
err = sw.w.Info(sw.prefix + string(p))
|
||||||
|
case WarnLevel:
|
||||||
|
err = sw.w.Warning(sw.prefix + string(p))
|
||||||
|
case ErrorLevel:
|
||||||
|
err = sw.w.Err(sw.prefix + string(p))
|
||||||
|
case FatalLevel:
|
||||||
|
err = sw.w.Emerg(sw.prefix + string(p))
|
||||||
|
case PanicLevel:
|
||||||
|
err = sw.w.Crit(sw.prefix + string(p))
|
||||||
|
case NoLevel:
|
||||||
|
err = sw.w.Info(sw.prefix + string(p))
|
||||||
|
default:
|
||||||
|
panic("invalid level")
|
||||||
|
}
|
||||||
|
// Any CEE prefix is not part of the message, so we don't include its length
|
||||||
|
n = len(p)
|
||||||
|
return
|
||||||
|
}
|
98
server/vendor/github.com/rs/zerolog/writer.go
generated
vendored
Normal file
98
server/vendor/github.com/rs/zerolog/writer.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
package zerolog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LevelWriter defines as interface a writer may implement in order
|
||||||
|
// to receive level information with payload.
|
||||||
|
type LevelWriter interface {
|
||||||
|
io.Writer
|
||||||
|
WriteLevel(level Level, p []byte) (n int, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type levelWriterAdapter struct {
|
||||||
|
io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lw levelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) {
|
||||||
|
return lw.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
type syncWriter struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
lw LevelWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyncWriter wraps w so that each call to Write is synchronized with a mutex.
|
||||||
|
// This syncer can be used to wrap the call to writer's Write method if it is
|
||||||
|
// not thread safe. Note that you do not need this wrapper for os.File Write
|
||||||
|
// operations on POSIX and Windows systems as they are already thread-safe.
|
||||||
|
func SyncWriter(w io.Writer) io.Writer {
|
||||||
|
if lw, ok := w.(LevelWriter); ok {
|
||||||
|
return &syncWriter{lw: lw}
|
||||||
|
}
|
||||||
|
return &syncWriter{lw: levelWriterAdapter{w}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements the io.Writer interface.
|
||||||
|
func (s *syncWriter) Write(p []byte) (n int, err error) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
return s.lw.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteLevel implements the LevelWriter interface.
|
||||||
|
func (s *syncWriter) WriteLevel(l Level, p []byte) (n int, err error) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
return s.lw.WriteLevel(l, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
type multiLevelWriter struct {
|
||||||
|
writers []LevelWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t multiLevelWriter) Write(p []byte) (n int, err error) {
|
||||||
|
for _, w := range t.writers {
|
||||||
|
if _n, _err := w.Write(p); err == nil {
|
||||||
|
n = _n
|
||||||
|
if _err != nil {
|
||||||
|
err = _err
|
||||||
|
} else if _n != len(p) {
|
||||||
|
err = io.ErrShortWrite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {
|
||||||
|
for _, w := range t.writers {
|
||||||
|
if _n, _err := w.WriteLevel(l, p); err == nil {
|
||||||
|
n = _n
|
||||||
|
if _err != nil {
|
||||||
|
err = _err
|
||||||
|
} else if _n != len(p) {
|
||||||
|
err = io.ErrShortWrite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiLevelWriter creates a writer that duplicates its writes to all the
|
||||||
|
// provided writers, similar to the Unix tee(1) command. If some writers
|
||||||
|
// implement LevelWriter, their WriteLevel method will be used instead of Write.
|
||||||
|
func MultiLevelWriter(writers ...io.Writer) LevelWriter {
|
||||||
|
lwriters := make([]LevelWriter, 0, len(writers))
|
||||||
|
for _, w := range writers {
|
||||||
|
if lw, ok := w.(LevelWriter); ok {
|
||||||
|
lwriters = append(lwriters, lw)
|
||||||
|
} else {
|
||||||
|
lwriters = append(lwriters, levelWriterAdapter{w})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return multiLevelWriter{lwriters}
|
||||||
|
}
|
3
server/vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
3
server/vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at https://tip.golang.org/AUTHORS.
|
3
server/vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
3
server/vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at https://tip.golang.org/CONTRIBUTORS.
|
27
server/vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
27
server/vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
server/vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
22
server/vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
35
server/vendor/golang.org/x/crypto/bcrypt/base64.go
generated
vendored
Normal file
35
server/vendor/golang.org/x/crypto/bcrypt/base64.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bcrypt
|
||||||
|
|
||||||
|
import "encoding/base64"
|
||||||
|
|
||||||
|
const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
|
|
||||||
|
var bcEncoding = base64.NewEncoding(alphabet)
|
||||||
|
|
||||||
|
func base64Encode(src []byte) []byte {
|
||||||
|
n := bcEncoding.EncodedLen(len(src))
|
||||||
|
dst := make([]byte, n)
|
||||||
|
bcEncoding.Encode(dst, src)
|
||||||
|
for dst[n-1] == '=' {
|
||||||
|
n--
|
||||||
|
}
|
||||||
|
return dst[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
func base64Decode(src []byte) ([]byte, error) {
|
||||||
|
numOfEquals := 4 - (len(src) % 4)
|
||||||
|
for i := 0; i < numOfEquals; i++ {
|
||||||
|
src = append(src, '=')
|
||||||
|
}
|
||||||
|
|
||||||
|
dst := make([]byte, bcEncoding.DecodedLen(len(src)))
|
||||||
|
n, err := bcEncoding.Decode(dst, src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dst[:n], nil
|
||||||
|
}
|
295
server/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
Normal file
295
server/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
|
||||||
|
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
|
||||||
|
package bcrypt // import "golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
// The code is a port of Provos and Mazières's C implementation.
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/subtle"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/blowfish"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
|
||||||
|
MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
|
||||||
|
DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
|
||||||
|
)
|
||||||
|
|
||||||
|
// The error returned from CompareHashAndPassword when a password and hash do
|
||||||
|
// not match.
|
||||||
|
var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
|
||||||
|
|
||||||
|
// The error returned from CompareHashAndPassword when a hash is too short to
|
||||||
|
// be a bcrypt hash.
|
||||||
|
var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
|
||||||
|
|
||||||
|
// The error returned from CompareHashAndPassword when a hash was created with
|
||||||
|
// a bcrypt algorithm newer than this implementation.
|
||||||
|
type HashVersionTooNewError byte
|
||||||
|
|
||||||
|
func (hv HashVersionTooNewError) Error() string {
|
||||||
|
return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
|
||||||
|
type InvalidHashPrefixError byte
|
||||||
|
|
||||||
|
func (ih InvalidHashPrefixError) Error() string {
|
||||||
|
return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
|
||||||
|
}
|
||||||
|
|
||||||
|
type InvalidCostError int
|
||||||
|
|
||||||
|
func (ic InvalidCostError) Error() string {
|
||||||
|
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
majorVersion = '2'
|
||||||
|
minorVersion = 'a'
|
||||||
|
maxSaltSize = 16
|
||||||
|
maxCryptedHashSize = 23
|
||||||
|
encodedSaltSize = 22
|
||||||
|
encodedHashSize = 31
|
||||||
|
minHashSize = 59
|
||||||
|
)
|
||||||
|
|
||||||
|
// magicCipherData is an IV for the 64 Blowfish encryption calls in
|
||||||
|
// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
|
||||||
|
var magicCipherData = []byte{
|
||||||
|
0x4f, 0x72, 0x70, 0x68,
|
||||||
|
0x65, 0x61, 0x6e, 0x42,
|
||||||
|
0x65, 0x68, 0x6f, 0x6c,
|
||||||
|
0x64, 0x65, 0x72, 0x53,
|
||||||
|
0x63, 0x72, 0x79, 0x44,
|
||||||
|
0x6f, 0x75, 0x62, 0x74,
|
||||||
|
}
|
||||||
|
|
||||||
|
type hashed struct {
|
||||||
|
hash []byte
|
||||||
|
salt []byte
|
||||||
|
cost int // allowed range is MinCost to MaxCost
|
||||||
|
major byte
|
||||||
|
minor byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateFromPassword returns the bcrypt hash of the password at the given
|
||||||
|
// cost. If the cost given is less than MinCost, the cost will be set to
|
||||||
|
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
|
||||||
|
// to compare the returned hashed password with its cleartext version.
|
||||||
|
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
|
||||||
|
p, err := newFromPassword(password, cost)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return p.Hash(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompareHashAndPassword compares a bcrypt hashed password with its possible
|
||||||
|
// plaintext equivalent. Returns nil on success, or an error on failure.
|
||||||
|
func CompareHashAndPassword(hashedPassword, password []byte) error {
|
||||||
|
p, err := newFromHash(hashedPassword)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
otherHash, err := bcrypt(password, p.cost, p.salt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
|
||||||
|
if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrMismatchedHashAndPassword
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cost returns the hashing cost used to create the given hashed
|
||||||
|
// password. When, in the future, the hashing cost of a password system needs
|
||||||
|
// to be increased in order to adjust for greater computational power, this
|
||||||
|
// function allows one to establish which passwords need to be updated.
|
||||||
|
func Cost(hashedPassword []byte) (int, error) {
|
||||||
|
p, err := newFromHash(hashedPassword)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return p.cost, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFromPassword(password []byte, cost int) (*hashed, error) {
|
||||||
|
if cost < MinCost {
|
||||||
|
cost = DefaultCost
|
||||||
|
}
|
||||||
|
p := new(hashed)
|
||||||
|
p.major = majorVersion
|
||||||
|
p.minor = minorVersion
|
||||||
|
|
||||||
|
err := checkCost(cost)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.cost = cost
|
||||||
|
|
||||||
|
unencodedSalt := make([]byte, maxSaltSize)
|
||||||
|
_, err = io.ReadFull(rand.Reader, unencodedSalt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p.salt = base64Encode(unencodedSalt)
|
||||||
|
hash, err := bcrypt(password, p.cost, p.salt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.hash = hash
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFromHash(hashedSecret []byte) (*hashed, error) {
|
||||||
|
if len(hashedSecret) < minHashSize {
|
||||||
|
return nil, ErrHashTooShort
|
||||||
|
}
|
||||||
|
p := new(hashed)
|
||||||
|
n, err := p.decodeVersion(hashedSecret)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hashedSecret = hashedSecret[n:]
|
||||||
|
n, err = p.decodeCost(hashedSecret)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hashedSecret = hashedSecret[n:]
|
||||||
|
|
||||||
|
// The "+2" is here because we'll have to append at most 2 '=' to the salt
|
||||||
|
// when base64 decoding it in expensiveBlowfishSetup().
|
||||||
|
p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
|
||||||
|
copy(p.salt, hashedSecret[:encodedSaltSize])
|
||||||
|
|
||||||
|
hashedSecret = hashedSecret[encodedSaltSize:]
|
||||||
|
p.hash = make([]byte, len(hashedSecret))
|
||||||
|
copy(p.hash, hashedSecret)
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
|
||||||
|
cipherData := make([]byte, len(magicCipherData))
|
||||||
|
copy(cipherData, magicCipherData)
|
||||||
|
|
||||||
|
c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 24; i += 8 {
|
||||||
|
for j := 0; j < 64; j++ {
|
||||||
|
c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug compatibility with C bcrypt implementations. We only encode 23 of
|
||||||
|
// the 24 bytes encrypted.
|
||||||
|
hsh := base64Encode(cipherData[:maxCryptedHashSize])
|
||||||
|
return hsh, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
|
||||||
|
csalt, err := base64Decode(salt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug compatibility with C bcrypt implementations. They use the trailing
|
||||||
|
// NULL in the key string during expansion.
|
||||||
|
// We copy the key to prevent changing the underlying array.
|
||||||
|
ckey := append(key[:len(key):len(key)], 0)
|
||||||
|
|
||||||
|
c, err := blowfish.NewSaltedCipher(ckey, csalt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var i, rounds uint64
|
||||||
|
rounds = 1 << cost
|
||||||
|
for i = 0; i < rounds; i++ {
|
||||||
|
blowfish.ExpandKey(ckey, c)
|
||||||
|
blowfish.ExpandKey(csalt, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *hashed) Hash() []byte {
|
||||||
|
arr := make([]byte, 60)
|
||||||
|
arr[0] = '$'
|
||||||
|
arr[1] = p.major
|
||||||
|
n := 2
|
||||||
|
if p.minor != 0 {
|
||||||
|
arr[2] = p.minor
|
||||||
|
n = 3
|
||||||
|
}
|
||||||
|
arr[n] = '$'
|
||||||
|
n++
|
||||||
|
copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
|
||||||
|
n += 2
|
||||||
|
arr[n] = '$'
|
||||||
|
n++
|
||||||
|
copy(arr[n:], p.salt)
|
||||||
|
n += encodedSaltSize
|
||||||
|
copy(arr[n:], p.hash)
|
||||||
|
n += encodedHashSize
|
||||||
|
return arr[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
|
||||||
|
if sbytes[0] != '$' {
|
||||||
|
return -1, InvalidHashPrefixError(sbytes[0])
|
||||||
|
}
|
||||||
|
if sbytes[1] > majorVersion {
|
||||||
|
return -1, HashVersionTooNewError(sbytes[1])
|
||||||
|
}
|
||||||
|
p.major = sbytes[1]
|
||||||
|
n := 3
|
||||||
|
if sbytes[2] != '$' {
|
||||||
|
p.minor = sbytes[2]
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// sbytes should begin where decodeVersion left off.
|
||||||
|
func (p *hashed) decodeCost(sbytes []byte) (int, error) {
|
||||||
|
cost, err := strconv.Atoi(string(sbytes[0:2]))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
err = checkCost(cost)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
p.cost = cost
|
||||||
|
return 3, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *hashed) String() string {
|
||||||
|
return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkCost(cost int) error {
|
||||||
|
if cost < MinCost || cost > MaxCost {
|
||||||
|
return InvalidCostError(cost)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
159
server/vendor/golang.org/x/crypto/blowfish/block.go
generated
vendored
Normal file
159
server/vendor/golang.org/x/crypto/blowfish/block.go
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package blowfish
|
||||||
|
|
||||||
|
// getNextWord returns the next big-endian uint32 value from the byte slice
|
||||||
|
// at the given position in a circular manner, updating the position.
|
||||||
|
func getNextWord(b []byte, pos *int) uint32 {
|
||||||
|
var w uint32
|
||||||
|
j := *pos
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
w = w<<8 | uint32(b[j])
|
||||||
|
j++
|
||||||
|
if j >= len(b) {
|
||||||
|
j = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pos = j
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
|
||||||
|
// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
|
||||||
|
// pi and substitution tables for calls to Encrypt. This is used, primarily,
|
||||||
|
// by the bcrypt package to reuse the Blowfish key schedule during its
|
||||||
|
// set up. It's unlikely that you need to use this directly.
|
||||||
|
func ExpandKey(key []byte, c *Cipher) {
|
||||||
|
j := 0
|
||||||
|
for i := 0; i < 18; i++ {
|
||||||
|
// Using inlined getNextWord for performance.
|
||||||
|
var d uint32
|
||||||
|
for k := 0; k < 4; k++ {
|
||||||
|
d = d<<8 | uint32(key[j])
|
||||||
|
j++
|
||||||
|
if j >= len(key) {
|
||||||
|
j = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.p[i] ^= d
|
||||||
|
}
|
||||||
|
|
||||||
|
var l, r uint32
|
||||||
|
for i := 0; i < 18; i += 2 {
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.p[i], c.p[i+1] = l, r
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s0[i], c.s0[i+1] = l, r
|
||||||
|
}
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s1[i], c.s1[i+1] = l, r
|
||||||
|
}
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s2[i], c.s2[i+1] = l, r
|
||||||
|
}
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s3[i], c.s3[i+1] = l, r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is similar to ExpandKey, but folds the salt during the key
|
||||||
|
// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
|
||||||
|
// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
|
||||||
|
// and specializing it here is useful.
|
||||||
|
func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
|
||||||
|
j := 0
|
||||||
|
for i := 0; i < 18; i++ {
|
||||||
|
c.p[i] ^= getNextWord(key, &j)
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 0
|
||||||
|
var l, r uint32
|
||||||
|
for i := 0; i < 18; i += 2 {
|
||||||
|
l ^= getNextWord(salt, &j)
|
||||||
|
r ^= getNextWord(salt, &j)
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.p[i], c.p[i+1] = l, r
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l ^= getNextWord(salt, &j)
|
||||||
|
r ^= getNextWord(salt, &j)
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s0[i], c.s0[i+1] = l, r
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l ^= getNextWord(salt, &j)
|
||||||
|
r ^= getNextWord(salt, &j)
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s1[i], c.s1[i+1] = l, r
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l ^= getNextWord(salt, &j)
|
||||||
|
r ^= getNextWord(salt, &j)
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s2[i], c.s2[i+1] = l, r
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 256; i += 2 {
|
||||||
|
l ^= getNextWord(salt, &j)
|
||||||
|
r ^= getNextWord(salt, &j)
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
c.s3[i], c.s3[i+1] = l, r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
|
||||||
|
xl, xr := l, r
|
||||||
|
xl ^= c.p[0]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
|
||||||
|
xr ^= c.p[17]
|
||||||
|
return xr, xl
|
||||||
|
}
|
||||||
|
|
||||||
|
func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
|
||||||
|
xl, xr := l, r
|
||||||
|
xl ^= c.p[17]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
|
||||||
|
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
|
||||||
|
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
|
||||||
|
xr ^= c.p[0]
|
||||||
|
return xr, xl
|
||||||
|
}
|
99
server/vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
Normal file
99
server/vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
|
||||||
|
//
|
||||||
|
// Blowfish is a legacy cipher and its short block size makes it vulnerable to
|
||||||
|
// birthday bound attacks (see https://sweet32.info). It should only be used
|
||||||
|
// where compatibility with legacy systems, not security, is the goal.
|
||||||
|
//
|
||||||
|
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
|
||||||
|
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
|
||||||
|
// golang.org/x/crypto/chacha20poly1305).
|
||||||
|
package blowfish // import "golang.org/x/crypto/blowfish"
|
||||||
|
|
||||||
|
// The code is a port of Bruce Schneier's C implementation.
|
||||||
|
// See https://www.schneier.com/blowfish.html.
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
// The Blowfish block size in bytes.
|
||||||
|
const BlockSize = 8
|
||||||
|
|
||||||
|
// A Cipher is an instance of Blowfish encryption using a particular key.
|
||||||
|
type Cipher struct {
|
||||||
|
p [18]uint32
|
||||||
|
s0, s1, s2, s3 [256]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeySizeError int
|
||||||
|
|
||||||
|
func (k KeySizeError) Error() string {
|
||||||
|
return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCipher creates and returns a Cipher.
|
||||||
|
// The key argument should be the Blowfish key, from 1 to 56 bytes.
|
||||||
|
func NewCipher(key []byte) (*Cipher, error) {
|
||||||
|
var result Cipher
|
||||||
|
if k := len(key); k < 1 || k > 56 {
|
||||||
|
return nil, KeySizeError(k)
|
||||||
|
}
|
||||||
|
initCipher(&result)
|
||||||
|
ExpandKey(key, &result)
|
||||||
|
return &result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
|
||||||
|
// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
|
||||||
|
// sufficient and desirable. For bcrypt compatibility, the key can be over 56
|
||||||
|
// bytes.
|
||||||
|
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
|
||||||
|
if len(salt) == 0 {
|
||||||
|
return NewCipher(key)
|
||||||
|
}
|
||||||
|
var result Cipher
|
||||||
|
if k := len(key); k < 1 {
|
||||||
|
return nil, KeySizeError(k)
|
||||||
|
}
|
||||||
|
initCipher(&result)
|
||||||
|
expandKeyWithSalt(key, salt, &result)
|
||||||
|
return &result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockSize returns the Blowfish block size, 8 bytes.
|
||||||
|
// It is necessary to satisfy the Block interface in the
|
||||||
|
// package "crypto/cipher".
|
||||||
|
func (c *Cipher) BlockSize() int { return BlockSize }
|
||||||
|
|
||||||
|
// Encrypt encrypts the 8-byte buffer src using the key k
|
||||||
|
// and stores the result in dst.
|
||||||
|
// Note that for amounts of data larger than a block,
|
||||||
|
// it is not safe to just call Encrypt on successive blocks;
|
||||||
|
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
|
||||||
|
func (c *Cipher) Encrypt(dst, src []byte) {
|
||||||
|
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||||
|
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||||
|
l, r = encryptBlock(l, r, c)
|
||||||
|
dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||||
|
dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt decrypts the 8-byte buffer src using the key k
|
||||||
|
// and stores the result in dst.
|
||||||
|
func (c *Cipher) Decrypt(dst, src []byte) {
|
||||||
|
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||||
|
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||||
|
l, r = decryptBlock(l, r, c)
|
||||||
|
dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||||
|
dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initCipher(c *Cipher) {
|
||||||
|
copy(c.p[0:], p[0:])
|
||||||
|
copy(c.s0[0:], s0[0:])
|
||||||
|
copy(c.s1[0:], s1[0:])
|
||||||
|
copy(c.s2[0:], s2[0:])
|
||||||
|
copy(c.s3[0:], s3[0:])
|
||||||
|
}
|
199
server/vendor/golang.org/x/crypto/blowfish/const.go
generated
vendored
Normal file
199
server/vendor/golang.org/x/crypto/blowfish/const.go
generated
vendored
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// The startup permutation array and substitution boxes.
|
||||||
|
// They are the hexadecimal digits of PI; see:
|
||||||
|
// https://www.schneier.com/code/constants.txt.
|
||||||
|
|
||||||
|
package blowfish
|
||||||
|
|
||||||
|
var s0 = [256]uint32{
|
||||||
|
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
||||||
|
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||||
|
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
|
||||||
|
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||||
|
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
|
||||||
|
0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||||
|
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
|
||||||
|
0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||||
|
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
|
||||||
|
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||||
|
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
|
||||||
|
0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||||
|
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
|
||||||
|
0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||||
|
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
|
||||||
|
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||||
|
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
|
||||||
|
0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||||
|
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
|
||||||
|
0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||||
|
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
|
||||||
|
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||||
|
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
|
||||||
|
0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||||
|
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
|
||||||
|
0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||||
|
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
|
||||||
|
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||||
|
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
|
||||||
|
0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||||
|
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
|
||||||
|
0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||||
|
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
|
||||||
|
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||||
|
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
|
||||||
|
0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||||
|
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
|
||||||
|
0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||||
|
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
|
||||||
|
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||||
|
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
|
||||||
|
0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||||
|
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
||||||
|
}
|
||||||
|
|
||||||
|
var s1 = [256]uint32{
|
||||||
|
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
|
||||||
|
0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||||
|
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
|
||||||
|
0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||||
|
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
|
||||||
|
0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||||
|
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
|
||||||
|
0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||||
|
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
|
||||||
|
0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||||
|
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
|
||||||
|
0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||||
|
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
|
||||||
|
0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||||
|
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
|
||||||
|
0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||||
|
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
|
||||||
|
0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||||
|
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
|
||||||
|
0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||||
|
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
|
||||||
|
0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||||
|
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
|
||||||
|
0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||||
|
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
|
||||||
|
0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||||
|
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
|
||||||
|
0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||||
|
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
|
||||||
|
0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||||
|
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
|
||||||
|
0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||||
|
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
|
||||||
|
0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||||
|
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
|
||||||
|
0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||||
|
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
|
||||||
|
0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||||
|
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
|
||||||
|
0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||||
|
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
|
||||||
|
0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||||
|
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
||||||
|
}
|
||||||
|
|
||||||
|
var s2 = [256]uint32{
|
||||||
|
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
|
||||||
|
0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||||
|
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
|
||||||
|
0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||||
|
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
|
||||||
|
0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||||
|
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
|
||||||
|
0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||||
|
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
|
||||||
|
0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||||
|
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
|
||||||
|
0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||||
|
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
|
||||||
|
0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||||
|
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
|
||||||
|
0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||||
|
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
|
||||||
|
0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||||
|
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
|
||||||
|
0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||||
|
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
|
||||||
|
0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||||
|
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
|
||||||
|
0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||||
|
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
|
||||||
|
0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||||
|
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
|
||||||
|
0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||||
|
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
|
||||||
|
0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||||
|
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
|
||||||
|
0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||||
|
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
|
||||||
|
0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||||
|
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
|
||||||
|
0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||||
|
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
|
||||||
|
0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||||
|
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
|
||||||
|
0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||||
|
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
|
||||||
|
0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||||
|
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
||||||
|
}
|
||||||
|
|
||||||
|
var s3 = [256]uint32{
|
||||||
|
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
|
||||||
|
0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||||
|
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
|
||||||
|
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||||
|
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
|
||||||
|
0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||||
|
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
|
||||||
|
0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||||
|
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
|
||||||
|
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||||
|
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
|
||||||
|
0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||||
|
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
|
||||||
|
0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||||
|
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
|
||||||
|
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||||
|
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
|
||||||
|
0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||||
|
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
|
||||||
|
0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||||
|
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
|
||||||
|
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||||
|
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
|
||||||
|
0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||||
|
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
|
||||||
|
0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||||
|
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
|
||||||
|
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||||
|
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
|
||||||
|
0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||||
|
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
|
||||||
|
0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||||
|
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
|
||||||
|
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||||
|
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
|
||||||
|
0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||||
|
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
|
||||||
|
0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||||
|
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
|
||||||
|
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||||
|
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
|
||||||
|
0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||||
|
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
|
||||||
|
}
|
||||||
|
|
||||||
|
var p = [18]uint32{
|
||||||
|
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
|
||||||
|
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||||
|
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
|
||||||
|
}
|
13
server/vendor/modules.txt
vendored
13
server/vendor/modules.txt
vendored
|
@ -7,6 +7,9 @@ github.com/corpix/uarand
|
||||||
# github.com/davecgh/go-spew v1.1.1
|
# github.com/davecgh/go-spew v1.1.1
|
||||||
## explicit
|
## explicit
|
||||||
github.com/davecgh/go-spew/spew
|
github.com/davecgh/go-spew/spew
|
||||||
|
# github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
|
## explicit
|
||||||
|
github.com/dgrijalva/jwt-go
|
||||||
# github.com/felixge/httpsnoop v1.0.2
|
# github.com/felixge/httpsnoop v1.0.2
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/felixge/httpsnoop
|
github.com/felixge/httpsnoop
|
||||||
|
@ -34,10 +37,20 @@ github.com/mattn/go-sqlite3
|
||||||
# github.com/pmezard/go-difflib v1.0.0
|
# github.com/pmezard/go-difflib v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/pmezard/go-difflib/difflib
|
github.com/pmezard/go-difflib/difflib
|
||||||
|
# github.com/rs/zerolog v1.25.0
|
||||||
|
## explicit; go 1.15
|
||||||
|
github.com/rs/zerolog
|
||||||
|
github.com/rs/zerolog/internal/cbor
|
||||||
|
github.com/rs/zerolog/internal/json
|
||||||
|
github.com/rs/zerolog/log
|
||||||
# github.com/stretchr/testify v1.7.0
|
# github.com/stretchr/testify v1.7.0
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/stretchr/testify/assert
|
github.com/stretchr/testify/assert
|
||||||
github.com/stretchr/testify/require
|
github.com/stretchr/testify/require
|
||||||
|
# golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
|
## explicit; go 1.17
|
||||||
|
golang.org/x/crypto/bcrypt
|
||||||
|
golang.org/x/crypto/blowfish
|
||||||
# gopkg.in/yaml.v2 v2.4.0
|
# gopkg.in/yaml.v2 v2.4.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.15
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed static/*
|
//go:embed static/*
|
||||||
|
@ -36,9 +37,8 @@ func (w *WebServer) RegisterRoutes(api *api.API) {
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
apiRouter := r.PathPrefix("/api").Subrouter()
|
apiRouter := r.PathPrefix("/api").Subrouter()
|
||||||
|
|
||||||
apiRouter.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
|
apiRouter.HandleFunc("/login", api.Login).Methods("POST")
|
||||||
fmt.Fprintf(w, "SAMPLE TOKEN")
|
apiRouter.HandleFunc("/user", api.CreateUser).Methods("POST")
|
||||||
}).Methods("POST")
|
|
||||||
|
|
||||||
staticFSSub, _ := fs.Sub(staticFS, "static")
|
staticFSSub, _ := fs.Sub(staticFS, "static")
|
||||||
staticFSHandler := StaticFSHandler{http.FileServer(http.FS(staticFSSub))}
|
staticFSHandler := StaticFSHandler{http.FileServer(http.FS(staticFSSub))}
|
||||||
|
@ -52,6 +52,7 @@ func (w *WebServer) RegisterRoutes(api *api.API) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebServer) Start() error {
|
func (w *WebServer) Start() error {
|
||||||
|
log.Debug().Msg("starting webserver")
|
||||||
if err := w.Server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := w.Server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -59,5 +60,6 @@ func (w *WebServer) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebServer) Close() error {
|
func (w *WebServer) Close() error {
|
||||||
|
log.Debug().Msg("closing webserver")
|
||||||
return w.Server.Close()
|
return w.Server.Close()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue