Compare commits
No commits in common. "master" and "1.1.4" have entirely different histories.
71
.drone.yml
71
.drone.yml
@ -13,9 +13,9 @@ environment:
|
|||||||
steps:
|
steps:
|
||||||
- name: build
|
- name: build
|
||||||
image: golang
|
image: golang
|
||||||
environment:
|
|
||||||
VERSION: dev
|
|
||||||
commands:
|
commands:
|
||||||
|
- apt-get update -y
|
||||||
|
- apt-get install libczmq-dev -y
|
||||||
- go generate $SRCFILES
|
- go generate $SRCFILES
|
||||||
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
||||||
when:
|
when:
|
||||||
@ -39,71 +39,8 @@ steps:
|
|||||||
- name: build
|
- name: build
|
||||||
image: golang
|
image: golang
|
||||||
commands:
|
commands:
|
||||||
- export VERSION=$DRONE_TAG
|
- apt-get update -y
|
||||||
- go generate $SRCFILES
|
- apt-get install libczmq-dev -y
|
||||||
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
|
||||||
- tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
|
|
||||||
- echo $PROJECTNAME $DRONE_TAG > VERSION
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- tag
|
|
||||||
- name: release
|
|
||||||
image: plugins/gitea-release
|
|
||||||
settings:
|
|
||||||
base_url: https://git.paulbsd.com
|
|
||||||
api_key:
|
|
||||||
from_secret: gitea_token
|
|
||||||
files: "*.tar.gz"
|
|
||||||
checksum:
|
|
||||||
- sha256
|
|
||||||
- sha512
|
|
||||||
title: VERSION
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- tag
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: build-linux-arm64
|
|
||||||
|
|
||||||
environment:
|
|
||||||
GOOS: linux
|
|
||||||
GOARCH: arm64
|
|
||||||
GOOPTIONS: -mod=vendor
|
|
||||||
SRCFILES: cmd/ipbl/*.go
|
|
||||||
PROJECTNAME: ipbl
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
image: golang
|
|
||||||
environment:
|
|
||||||
VERSION: dev
|
|
||||||
commands:
|
|
||||||
- go generate $SRCFILES
|
|
||||||
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- tag
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: gitea-release-linux-arm64
|
|
||||||
|
|
||||||
environment:
|
|
||||||
GOOS: linux
|
|
||||||
GOARCH: arm64
|
|
||||||
GOOPTIONS: -mod=vendor
|
|
||||||
SRCFILES: cmd/ipbl/*.go
|
|
||||||
PROJECTNAME: ipbl
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
image: golang
|
|
||||||
commands:
|
|
||||||
- export VERSION=$DRONE_TAG
|
|
||||||
- go generate $SRCFILES
|
- go generate $SRCFILES
|
||||||
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
||||||
- tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
|
- tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,5 +2,4 @@
|
|||||||
*.ini
|
*.ini
|
||||||
*.swp
|
*.swp
|
||||||
/test
|
/test
|
||||||
/old
|
|
||||||
version.go
|
version.go
|
@ -11,8 +11,7 @@ ipbl is a webservice collecting / storing / distributing abuse IP addresses
|
|||||||
### Build
|
### Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go generate cmd/ipbl/*.go
|
make
|
||||||
go build cmd/ipbl/*.go
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sample config in ipbl.ini
|
### Sample config in ipbl.ini
|
||||||
@ -23,19 +22,19 @@ db_hostname="hostname"
|
|||||||
db_name="database"
|
db_name="database"
|
||||||
db_username="username"
|
db_username="username"
|
||||||
db_password="password"
|
db_password="password"
|
||||||
db_table="ipbl"
|
db_table="ipbl_test"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run
|
### Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./ipbl -configfile ipbl.ini -port 8099
|
./ipbl -configfile ipbl.ini -port 8080
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Copyright (c) 2021, 2022, 2023 PaulBSD
|
Copyright (c) 2020, 2021 PaulBSD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -6,14 +6,11 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"net/http"
|
|
||||||
_ "net/http/pprof"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/database"
|
"git.paulbsd.com/paulbsd/ipbl/src/database"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/routers"
|
"git.paulbsd.com/paulbsd/ipbl/src/routers"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/ws"
|
"git.paulbsd.com/paulbsd/ipbl/src/zmqrouter"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/utils"
|
"git.paulbsd.com/paulbsd/ipbl/utils"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
)
|
)
|
||||||
@ -36,17 +33,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer cfg.Db.Close()
|
defer cfg.Db.Close()
|
||||||
|
|
||||||
if cfg.Options.ScanIP {
|
go models.ScanIP(&cfg)
|
||||||
go models.ScanIP(&cfg)
|
go zmqrouter.Init(&cfg)
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Options.Debug {
|
|
||||||
go func() {
|
|
||||||
log.Println(http.ListenAndServe("localhost:6060", nil))
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.Init(&cfg)
|
|
||||||
go func() { err = routers.RunServer(&ctx, &cfg) }()
|
go func() { err = routers.RunServer(&ctx, &cfg) }()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
|
36
go.mod
36
go.mod
@ -1,32 +1,32 @@
|
|||||||
module git.paulbsd.com/paulbsd/ipbl
|
module git.paulbsd.com/paulbsd/ipbl
|
||||||
|
|
||||||
go 1.23
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/labstack/echo/v4 v4.12.0
|
github.com/labstack/echo/v4 v4.7.0
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.4
|
||||||
golang.org/x/net v0.28.0
|
gopkg.in/ini.v1 v1.66.4
|
||||||
gopkg.in/ini.v1 v1.67.0
|
gopkg.in/zeromq/goczmq.v4 v4.1.0
|
||||||
xorm.io/xorm v1.3.9
|
xorm.io/xorm v1.2.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/goccy/go-json v0.10.3 // indirect
|
github.com/goccy/go-json v0.9.5 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/labstack/gommon v0.4.2 // indirect
|
github.com/labstack/gommon v0.3.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
github.com/onsi/ginkgo v1.16.4 // indirect
|
||||||
github.com/onsi/gomega v1.22.1 // indirect
|
github.com/onsi/gomega v1.14.0 // indirect
|
||||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||||
golang.org/x/crypto v0.26.0 // indirect
|
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 // indirect
|
||||||
golang.org/x/sys v0.24.0 // indirect
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||||
golang.org/x/text v0.17.0 // indirect
|
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
|
||||||
xorm.io/builder v0.3.13 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
xorm.io/builder v0.3.9 // indirect
|
||||||
)
|
)
|
||||||
|
613
go.sum
613
go.sum
@ -1,180 +1,631 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||||
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
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/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||||
|
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.9.4 h1:L8MLKG2mvVXiQu07qB6hmfqeSYQdOnqPot2GhsIwIaI=
|
||||||
|
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/goccy/go-json v0.9.5 h1:ooSMW526ZjK+EaL5elrSyN2EzIfi/3V0m4+HJEDYLik=
|
||||||
|
github.com/goccy/go-json v0.9.5/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||||
|
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
|
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||||
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
|
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||||
|
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||||
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
|
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||||
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
|
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||||
|
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
|
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
|
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||||
|
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||||
|
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||||
|
github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
|
||||||
|
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
|
||||||
|
github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
|
||||||
|
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||||
|
github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g=
|
||||||
|
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||||
|
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||||
|
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
|
||||||
|
github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
|
||||||
|
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
|
||||||
|
github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE=
|
||||||
|
github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||||
|
github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
|
||||||
|
github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
|
||||||
|
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
|
||||||
|
github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc=
|
||||||
|
github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60=
|
||||||
|
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/labstack/echo/v4 v4.6.3 h1:VhPuIZYxsbPmo4m9KAkMU/el2442eB7EBFFhNTTT9ac=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
github.com/labstack/echo/v4 v4.7.0 h1:8wHgZhoE9OT1NSLw6sfrX7ZGpWMtO5Zlfr68+BIo180=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/labstack/echo/v4 v4.7.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||||
|
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||||
|
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||||
|
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||||
|
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||||
|
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||||
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
|
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||||
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
|
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||||
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
|
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||||
|
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||||
|
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||||
|
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
|
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
|
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||||
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
|
github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
|
||||||
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
|
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||||
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||||
|
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||||
|
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||||
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
|
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
|
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||||
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/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||||
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
|
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||||
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
|
||||||
|
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 h1:syTAU9FwmvzEoIYMqcPHOcVm4H3U5u90WsvuYgwpETU=
|
||||||
|
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
|
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||||
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
|
||||||
|
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
|
||||||
|
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
|
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||||
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
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/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||||
|
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
|
||||||
|
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
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=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
gopkg.in/zeromq/goczmq.v4 v4.1.0 h1:CE+FE81mGVs2aSlnbfLuS1oAwdcVywyMM2AC1g33imI=
|
||||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
gopkg.in/zeromq/goczmq.v4 v4.1.0/go.mod h1:h4IlfePEYMpFdywGr5gAwKhBBj+hiBl/nF4VoSE4k+0=
|
||||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
modernc.org/cc/v3 v3.33.6 h1:r63dgSzVzRxUpAJFPQWHy1QeZeY1ydNENUDaBx1GqYc=
|
||||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
modernc.org/ccgo/v3 v3.9.5 h1:dEuUSf8WN51rDkprFuAqjfchKEzN0WttP/Py3enBwjk=
|
||||||
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
||||||
modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
modernc.org/libc v1.9.11 h1:QUxZMs48Ahg2F7SN41aERvMfGLY2HU/ADnB9DC4Yts8=
|
||||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
||||||
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
|
modernc.org/mathutil v1.4.0 h1:GCjoRaBew8ECCKINQA2nYjzvufFW9YiEuuB+rQ9bn2E=
|
||||||
xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
|
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
|
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
||||||
|
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||||
|
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||||
|
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||||
|
modernc.org/sqlite v1.11.2 h1:ShWQpeD3ag/bmx6TqidBlIWonWmQaSQKls3aenCbt+w=
|
||||||
|
modernc.org/sqlite v1.11.2/go.mod h1:+mhs/P1ONd+6G7hcAs6irwDi/bjTQ7nLW6LHRBsEa3A=
|
||||||
|
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||||
|
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||||
|
modernc.org/tcl v1.5.5/go.mod h1:ADkaTUuwukkrlhqwERyq0SM8OvyXo7+TjFz7yAF56EI=
|
||||||
|
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||||
|
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
|
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||||
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
|
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||||
|
xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc=
|
||||||
|
xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
|
xorm.io/xorm v1.2.5 h1:tqN7OhN8P9xi52qBb76I8m5maAJMz/SSbgK2RGPCPbo=
|
||||||
|
xorm.io/xorm v1.2.5/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0=
|
||||||
|
@ -10,28 +10,28 @@ import (
|
|||||||
|
|
||||||
func (cfg *Config) GetConfig() error {
|
func (cfg *Config) GetConfig() error {
|
||||||
var configfile string
|
var configfile string
|
||||||
|
var debug bool
|
||||||
var drop bool
|
var drop bool
|
||||||
var init bool
|
var init bool
|
||||||
var port int
|
var port int
|
||||||
var version bool
|
var version bool
|
||||||
var migrate bool
|
|
||||||
|
|
||||||
flag.Usage = utils.Usage
|
flag.Usage = utils.Usage
|
||||||
|
|
||||||
flag.StringVar(&configfile, "configfile", "ipbl.ini", "Configuration file to use with ipbl section")
|
flag.StringVar(&configfile, "configfile", "ipbl.ini", "Configuration file to use with ipbl section")
|
||||||
flag.IntVar(&port, "port", 8099, "Web service port to use")
|
flag.IntVar(&port, "port", 8099, "Web service port to use")
|
||||||
|
flag.BoolVar(&debug, "debug", false, "If debug logging must be enabled")
|
||||||
flag.BoolVar(&drop, "drop", false, "If dropping tables must occur")
|
flag.BoolVar(&drop, "drop", false, "If dropping tables must occur")
|
||||||
flag.BoolVar(&init, "init", false, "If init of database must be done")
|
flag.BoolVar(&init, "init", false, "If init of database must be done")
|
||||||
flag.BoolVar(&version, "version", false, "Show version")
|
flag.BoolVar(&version, "version", false, "Show version")
|
||||||
flag.BoolVar(&migrate, "migrate", false, "Do migrations on version changes")
|
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
cfg.Switchs.Debug = debug
|
||||||
cfg.Switchs.Drop = drop
|
cfg.Switchs.Drop = drop
|
||||||
cfg.Switchs.Init = init
|
cfg.Switchs.Init = init
|
||||||
cfg.Switchs.Port = port
|
cfg.Switchs.Port = port
|
||||||
cfg.Switchs.Version = version
|
cfg.Switchs.Version = version
|
||||||
cfg.Switchs.Migrate = migrate
|
|
||||||
|
|
||||||
var inicfg, err = ini.Load(configfile)
|
var inicfg, err = ini.Load(configfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -44,36 +44,31 @@ func (cfg *Config) GetConfig() error {
|
|||||||
cfg.DbParams.DbUsername = ipblsection.Key("username").MustString("username")
|
cfg.DbParams.DbUsername = ipblsection.Key("username").MustString("username")
|
||||||
cfg.DbParams.DbPassword = ipblsection.Key("password").MustString("password")
|
cfg.DbParams.DbPassword = ipblsection.Key("password").MustString("password")
|
||||||
cfg.DbParams.DbDatabase = ipblsection.Key("database").MustString("database")
|
cfg.DbParams.DbDatabase = ipblsection.Key("database").MustString("database")
|
||||||
|
cfg.Options.ZMQChannel = "ipbl"
|
||||||
cfg.Options.SocketChannel = "ipbl"
|
|
||||||
cfg.Options.HideBanner = ipblsection.Key("hidebanner").MustBool(false)
|
cfg.Options.HideBanner = ipblsection.Key("hidebanner").MustBool(false)
|
||||||
cfg.Options.Debug = ipblsection.Key("debug").MustBool(false)
|
|
||||||
cfg.Options.ScanIP = ipblsection.Key("scanip").MustBool(false)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Db *xorm.Engine
|
Db *xorm.Engine `json:"-"`
|
||||||
DbParams struct {
|
DbParams struct {
|
||||||
DbHostname string
|
DbHostname string `json:"dbhostname"`
|
||||||
DbUsername string
|
DbUsername string `json:"dbusername"`
|
||||||
DbPassword string
|
DbPassword string `json:"dbpassword"`
|
||||||
DbDatabase string
|
DbDatabase string `json:"dbdatabase"`
|
||||||
}
|
} `json:"dbparams"`
|
||||||
Options struct {
|
Options struct {
|
||||||
Version string
|
Version string `json:"version"`
|
||||||
HideBanner bool
|
HideBanner bool `json:"hidebanner"`
|
||||||
SocketChannel string
|
ZMQChannel string `json:"zmqchannel"`
|
||||||
Debug bool
|
} `json:"-"`
|
||||||
ScanIP bool
|
|
||||||
}
|
|
||||||
Switchs struct {
|
Switchs struct {
|
||||||
Port int
|
Port int `json:"port"`
|
||||||
NoFeed bool
|
NoFeed bool `json:"nofeed"`
|
||||||
Drop bool
|
Debug bool `json:"debug"`
|
||||||
Init bool
|
Drop bool `json:"drop"`
|
||||||
Version bool
|
Init bool `json:"init"`
|
||||||
Migrate bool
|
Version bool `json:"version"`
|
||||||
}
|
} `json:"-"`
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,22 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
"xorm.io/xorm/dialects"
|
|
||||||
"xorm.io/xorm/names"
|
"xorm.io/xorm/names"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Initialize(ctx *context.Context, cfg *config.Config) (err error) {
|
func Initialize(ctx *context.Context, cfg *config.Config) (err error) {
|
||||||
var databaseEngine = "postgres"
|
var databaseEngine = "postgres"
|
||||||
//cacher := caches.NewLRUCacher(caches.NewMemoryStore(), 10)
|
var tables = []interface{}{models.IP{},
|
||||||
|
models.Cfg{},
|
||||||
|
models.Src{},
|
||||||
|
models.CfgSet{},
|
||||||
|
models.CfgTrustlist{},
|
||||||
|
models.CfgZMQ{}}
|
||||||
|
|
||||||
cfg.Db, err = xorm.NewEngine(databaseEngine,
|
cfg.Db, err = xorm.NewEngine(databaseEngine,
|
||||||
fmt.Sprintf("%s://%s:%s@%s/%s",
|
fmt.Sprintf("%s://%s:%s@%s/%s",
|
||||||
@ -30,48 +33,18 @@ func Initialize(ctx *context.Context, cfg *config.Config) (err error) {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
cfg.Db.SetMapper(names.GonicMapper{})
|
cfg.Db.SetMapper(names.GonicMapper{})
|
||||||
cfg.Db.SetQuotePolicy(dialects.QuotePolicyReserved)
|
cfg.Db.ShowSQL(cfg.Switchs.Debug)
|
||||||
cfg.Db.ShowSQL(cfg.Options.Debug)
|
|
||||||
|
|
||||||
//cfg.Db.SetDefaultCacher(cacher)
|
|
||||||
|
|
||||||
if cfg.Switchs.Drop {
|
if cfg.Switchs.Drop {
|
||||||
log.Println("Dropping tables")
|
log.Println("Dropping tables")
|
||||||
models.DropTables(ctx, cfg)
|
cfg.Db.DropTables(tables)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Syncing tables")
|
log.Println("Syncing tables")
|
||||||
err = models.NewEngine(ctx, cfg)
|
for _, table := range tables {
|
||||||
|
cfg.Db.CreateTables(table)
|
||||||
if cfg.Switchs.Migrate {
|
err = cfg.Db.Sync2(table)
|
||||||
migrate(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func migrate(cfg *config.Config) (err error) {
|
|
||||||
var cfgsets []models.CfgSet
|
|
||||||
num, err := cfg.Db.FindAndCount(&cfgsets)
|
|
||||||
fmt.Printf("%d sets found\n", num)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
for _, cfgset := range cfgsets {
|
|
||||||
var reg = cfgset.Regex
|
|
||||||
reg = strings.Trim(reg, "()")
|
|
||||||
rs := strings.Split(reg, "|")
|
|
||||||
for _, v := range rs {
|
|
||||||
if v != "" {
|
|
||||||
n := models.CfgExpr{
|
|
||||||
Expr: v,
|
|
||||||
Set: &cfgset,
|
|
||||||
Enabled: true,
|
|
||||||
}
|
|
||||||
cfg.Db.Insert(&n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (as *AutonomousSystem) GetOrCreate(session *xorm.Session) (apias *APIAutonomousSystem, err error) {
|
|
||||||
has, err := session.Get(as)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
session.Insert(as)
|
|
||||||
} else {
|
|
||||||
session.ID(as.ID).Update(as)
|
|
||||||
}
|
|
||||||
as.Get(session)
|
|
||||||
apias = as.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (as *AutonomousSystem) Get(session *xorm.Session) (apias *APIAutonomousSystem, err error) {
|
|
||||||
has, err := session.Get(as)
|
|
||||||
if !has || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apias = as.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (as *AutonomousSystem) APIFormat() *APIAutonomousSystem {
|
|
||||||
if as == nil {
|
|
||||||
return &APIAutonomousSystem{}
|
|
||||||
}
|
|
||||||
return &APIAutonomousSystem{
|
|
||||||
ASID: as.ASID,
|
|
||||||
ASName: as.ASName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (as *AutonomousSystem) APIParse(apias APIAutonomousSystem) (err error) {
|
|
||||||
*as = AutonomousSystem{
|
|
||||||
ASID: apias.ASID,
|
|
||||||
ASName: apias.ASName}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type AutonomousSystem struct {
|
|
||||||
ID int `xorm:"pk autoincr"`
|
|
||||||
ASID int `xorm:"integer unique(asindex) as_id"`
|
|
||||||
ASName string `xorm:"text unique(asindex) as_name"`
|
|
||||||
Created time.Time `xorm:"created notnull"`
|
|
||||||
Updated time.Time `xorm:"updated notnull"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APIAutonomousSystem struct {
|
|
||||||
ID int `json:"-"`
|
|
||||||
ASID int `json:"as_id"`
|
|
||||||
ASName string `json:"as_name"`
|
|
||||||
}
|
|
@ -10,42 +10,40 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ipv4_cidr_regex = `^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|)){4}\/([1-3])?([0-9])?$)`
|
//var ipv4_regex = `^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})/`
|
||||||
|
var ipv4_cidr_regex = `^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|)){4}\/([1-3])?([0-9])?$)`
|
||||||
|
|
||||||
func GetTrustlists(cfg *config.Config) (res []string, err error) {
|
func GetTrustlists(cfg config.Config) (res []string, err error) {
|
||||||
var ctl []CfgTrustlist
|
var w []CfgTrustlist
|
||||||
err = cfg.Db.Find(&ctl)
|
err = cfg.Db.Find(&w)
|
||||||
|
if len(w) > 0 {
|
||||||
if len(ctl) > 0 {
|
for _, a := range w {
|
||||||
for _, a := range ctl {
|
|
||||||
res = append(res, a.IP)
|
res = append(res, a.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tl CfgTrustlist) InsertOrUpdate(cfg *config.Config) (err error) {
|
func (wl CfgTrustlist) InsertOrUpdate(cfg config.Config) (err error) {
|
||||||
var w = Cfg{Key: "trustlist"}
|
var w = Cfg{Key: "trustlist"}
|
||||||
exists, _ := cfg.Db.Get(&w)
|
exists, _ := cfg.Db.Get(&w)
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
existing, _ := GetTrustlists(cfg)
|
existing, _ := GetTrustlists(cfg)
|
||||||
for _, j := range existing {
|
for _, j := range existing {
|
||||||
if j == tl.IP {
|
if j == wl.IP {
|
||||||
return fmt.Errorf("ip %s already in config", j)
|
return fmt.Errorf("ip %s already in config", j)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
existing = append(existing, tl.IP)
|
existing = append(existing, wl.IP)
|
||||||
w.Value = strings.Join(existing, ",")
|
w.Value = strings.Join(existing, ",")
|
||||||
cfg.Db.ID(w.ID).Update(&w)
|
cfg.Db.ID(w.ID).Update(&w)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("no trustlist updated")
|
return fmt.Errorf("no trustlist updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tl CfgTrustlist) Delete(cfg *config.Config, ip string) (affected int64, err error) {
|
func (wl CfgTrustlist) Delete(cfg config.Config, ip string) (affected int64, err error) {
|
||||||
var w = CfgTrustlist{IP: ip}
|
var w = CfgTrustlist{IP: ip}
|
||||||
exists, _ := cfg.Db.Get(&w)
|
exists, _ := cfg.Db.Get(&w)
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
affected, err = cfg.Db.ID(w.ID).Update(&w)
|
affected, err = cfg.Db.ID(w.ID).Update(&w)
|
||||||
return
|
return
|
||||||
@ -53,79 +51,21 @@ func (tl CfgTrustlist) Delete(cfg *config.Config, ip string) (affected int64, er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tl CfgTrustlist) Verify() bool {
|
func (wl CfgTrustlist) Verify() bool {
|
||||||
reg := regexp.MustCompile(ipv4_cidr_regex)
|
reg := regexp.MustCompile(ipv4_cidr_regex)
|
||||||
return reg.MatchString(tl.IP)
|
return reg.MatchString(wl.IP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfgset *CfgSet) BuildRegex(cfg *config.Config) {
|
func GetSets(cfg config.Config) (res []CfgSet, err error) {
|
||||||
var rr []CfgExpr
|
|
||||||
err := cfg.Db.Where("cfgset_id = $1 AND enabled", cfgset.ID).OrderBy("expr").Find(&rr)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
regs := []string{}
|
|
||||||
for _, v := range rr {
|
|
||||||
regs = append(regs, v.Expr)
|
|
||||||
}
|
|
||||||
cfgset.Regex = fmt.Sprintf("(%s)", strings.Join(regs, "|"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetSets(cfg *config.Config) (res []CfgSet, err error) {
|
|
||||||
var w = []CfgSet{}
|
var w = []CfgSet{}
|
||||||
|
|
||||||
if err := cfg.Db.Where("enabled").Find(&w); err == nil {
|
|
||||||
return w, err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetGlobalConfig(cfg *config.Config) (res []Cfg, err error) {
|
|
||||||
var w = []Cfg{}
|
|
||||||
|
|
||||||
if err := cfg.Db.Find(&w); err == nil {
|
if err := cfg.Db.Find(&w); err == nil {
|
||||||
return w, err
|
return w, err
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllConfigv2(cfg *config.Config) (res CfgAllv2, err error) {
|
func InsertOrUpdateSets(cfg config.Config, folders []CfgSet) (res string, err error) {
|
||||||
var c = make(map[string]string)
|
|
||||||
var tmpcfg = []Cfg{}
|
|
||||||
if err := cfg.Db.Find(&tmpcfg); err == nil {
|
|
||||||
for _, v := range tmpcfg {
|
|
||||||
c[v.Key] = v.Value
|
|
||||||
}
|
|
||||||
res.Cfg = c
|
|
||||||
}
|
|
||||||
|
|
||||||
var sets = []CfgSet{}
|
|
||||||
if err := cfg.Db.Find(&sets); err == nil {
|
|
||||||
for i, _ := range sets {
|
|
||||||
sets[i].BuildRegex(cfg)
|
|
||||||
}
|
|
||||||
res.Sets = sets
|
|
||||||
}
|
|
||||||
|
|
||||||
var tl = []CfgTrustlist{}
|
|
||||||
if err := cfg.Db.Find(&tl); err == nil {
|
|
||||||
for _, v := range tl {
|
|
||||||
res.Trustlists = append(res.Trustlists, v.IP)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var ws = []CfgWS{}
|
|
||||||
if err := cfg.Db.Find(&ws); err == nil {
|
|
||||||
res.WS = ws
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func InsertOrUpdateSets(cfg *config.Config, folders []CfgSet) (res string, err error) {
|
|
||||||
var w = Cfg{Key: "folders"}
|
var w = Cfg{Key: "folders"}
|
||||||
|
|
||||||
if exists, _ := cfg.Db.Get(&w); exists {
|
if exists, _ := cfg.Db.Get(&w); exists {
|
||||||
resbytes, err := json.Marshal(folders)
|
resbytes, err := json.Marshal(folders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -140,16 +80,15 @@ func InsertOrUpdateSets(cfg *config.Config, folders []CfgSet) (res string, err e
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetWS(cfg *config.Config) (res []CfgWS, err error) {
|
func GetZMQ(cfg config.Config) (res []CfgZMQ, err error) {
|
||||||
var w = []CfgWS{}
|
var w = []CfgZMQ{}
|
||||||
|
|
||||||
if err = cfg.Db.Find(&w); err == nil {
|
if err = cfg.Db.Find(&w); err == nil {
|
||||||
return w, err
|
return w, err
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func DiscoverURLS(cfg *config.Config, routes []*echo.Route) (Discovery, error) {
|
func DiscoverURLS(cfg config.Config, routes []*echo.Route) (Discovery, error) {
|
||||||
var disc Discovery
|
var disc Discovery
|
||||||
var urls = make(map[string]Url)
|
var urls = make(map[string]Url)
|
||||||
for _, j := range routes {
|
for _, j := range routes {
|
||||||
@ -164,11 +103,25 @@ func DiscoverURLS(cfg *config.Config, routes []*echo.Route) (Discovery, error) {
|
|||||||
return disc, nil
|
return disc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CfgAllv2 struct {
|
type CfgTrustlist struct {
|
||||||
Cfg map[string]string `json:"cfg"`
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
Sets []CfgSet `json:"sets"`
|
IP string `xorm:"text notnull" json:"ip"`
|
||||||
Trustlists []string `json:"trustlists"`
|
}
|
||||||
WS []CfgWS `json:"ws"`
|
type CfgZMQ struct {
|
||||||
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
|
Type string `xorm:"text notnull" json:"type"`
|
||||||
|
Hostname string `xorm:"text notnull" json:"hostname"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Subscription string `json:"subscription"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CfgSet struct {
|
||||||
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
|
Path string `xorm:"text notnull default" json:"path"`
|
||||||
|
Type string `xorm:"text notnull" json:"type"`
|
||||||
|
Filename string `xorm:"text notnull" json:"filename"`
|
||||||
|
Regex string `xorm:"text notnull" json:"regex"`
|
||||||
|
Enabled bool `xorm:"notnull default true" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Cfg struct {
|
type Cfg struct {
|
||||||
@ -177,36 +130,6 @@ type Cfg struct {
|
|||||||
Value string `xorm:"text default" json:"value"`
|
Value string `xorm:"text default" json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CfgSet struct {
|
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
|
||||||
Path string `xorm:"text notnull default" json:"path"`
|
|
||||||
Src string `xorm:"text notnull" json:"src"`
|
|
||||||
Filename string `xorm:"text notnull" json:"filename"`
|
|
||||||
Regex string `xorm:"-" json:"regex"`
|
|
||||||
Blocktime int64 `xorm:"notnull default 60" json:"blocktime"`
|
|
||||||
TryFail int64 `xorm:"notnull default 5" json:"tryfail"`
|
|
||||||
Enabled bool `xorm:"notnull default true" json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CfgExpr struct {
|
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
|
||||||
Expr string `xorm:"text notnull unique(exprindex) index default ''"`
|
|
||||||
Enabled bool `xorm:"notnull default true" json:"-"`
|
|
||||||
Set *CfgSet `xorm:"cfgset_id int unique(exprindex) default null"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CfgTrustlist struct {
|
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
|
||||||
IP string `xorm:"text notnull" json:"ip"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CfgWS struct {
|
|
||||||
ID int `xorm:"pk autoincr" json:"-"`
|
|
||||||
Type string `xorm:"text notnull" json:"type"`
|
|
||||||
Endpoint string `xorm:"text notnull" json:"endpoint"`
|
|
||||||
Subscription string `json:"subscription"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Discovery struct {
|
type Discovery struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
URLs map[string]Url `json:"urls"`
|
URLs map[string]Url `json:"urls"`
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (city *City) GetOrCreate(session *xorm.Session) (apicity *APICity, err error) {
|
|
||||||
has, err := session.Get(city)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
session.Insert(city)
|
|
||||||
} else {
|
|
||||||
session.ID(city.ID).Update(city)
|
|
||||||
}
|
|
||||||
city.Get(session)
|
|
||||||
apicity = city.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (city *City) Get(session *xorm.Session) (apicity *APICity, err error) {
|
|
||||||
has, err := session.Get(city)
|
|
||||||
if !has || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apicity = city.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (city *City) APIFormat() *APICity {
|
|
||||||
if city == nil {
|
|
||||||
return &APICity{}
|
|
||||||
}
|
|
||||||
return &APICity{
|
|
||||||
CityName: city.CityName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (city *City) APIParse(apicity APICity) (err error) {
|
|
||||||
*city = City{
|
|
||||||
CityName: apicity.CityName}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type City struct {
|
|
||||||
ID int `xorm:"pk autoincr"`
|
|
||||||
CityName string `xorm:"text unique(cityindex) city_name" json:"city_name"`
|
|
||||||
Created time.Time `xorm:"created notnull"`
|
|
||||||
Updated time.Time `xorm:"updated notnull"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APICity struct {
|
|
||||||
ID int `json:"-"`
|
|
||||||
CityName string `json:"city_name"`
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (country *Country) GetOrCreate(session *xorm.Session) (apicountry *APICountry, err error) {
|
|
||||||
has, err := session.Get(country)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
session.Insert(country)
|
|
||||||
} else {
|
|
||||||
session.ID(country.ID).Update(country)
|
|
||||||
}
|
|
||||||
apicountry = country.APIFormat()
|
|
||||||
country.Get(session)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (country *Country) Get(session *xorm.Session) (apicountry *APICountry, err error) {
|
|
||||||
has, err := session.Get(country)
|
|
||||||
if !has || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apicountry = country.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (country *Country) APIFormat() *APICountry {
|
|
||||||
if country == nil {
|
|
||||||
return &APICountry{}
|
|
||||||
}
|
|
||||||
return &APICountry{
|
|
||||||
CountryName: country.CountryName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (country *Country) APIParse(apicountry APICountry) (err error) {
|
|
||||||
*country = Country{
|
|
||||||
CountryName: apicountry.CountryName}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Country struct {
|
|
||||||
ID int `xorm:"pk autoincr"`
|
|
||||||
CountryName string `xorm:"text unique(countryindex) country_name" json:"country_name"`
|
|
||||||
Created time.Time `xorm:"created notnull"`
|
|
||||||
Updated time.Time `xorm:"updated notnull"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APICountry struct {
|
|
||||||
ID int `json:"-"`
|
|
||||||
CountryName string `json:"country_name"`
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (event *Event) Insert(cfg *config.Config) (err error) {
|
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
defer session.Close()
|
|
||||||
_, err = session.Insert(event)
|
|
||||||
err = session.Commit()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (event *Event) APIParse(session *xorm.Session, apievent APIEvent) (err error) {
|
|
||||||
*event = Event{
|
|
||||||
IP: &IP{IP: apievent.IPData.IP},
|
|
||||||
Host: &Host{Host: apievent.IPData.Hostname},
|
|
||||||
Src: &Src{Src: apievent.IPData.Src},
|
|
||||||
}
|
|
||||||
event.IP.GetOrCreate(session)
|
|
||||||
event.Host.GetOrCreate(session)
|
|
||||||
event.Src.GetOrCreate(session)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Event struct {
|
|
||||||
ID int `xorm:"pk autoincr"`
|
|
||||||
Src *Src `xorm:"int src_id index"`
|
|
||||||
Host *Host `xorm:"int host_id index"`
|
|
||||||
IP *IP `xorm:"int ip_id index"`
|
|
||||||
Created time.Time `xorm:"created notnull index"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APIEvent struct {
|
|
||||||
MsgType string `json:"msgtype"`
|
|
||||||
Mode string `json:"mode"`
|
|
||||||
Hostname string `json:"hostname"`
|
|
||||||
IPData struct {
|
|
||||||
IP string `json:"ip"`
|
|
||||||
Type int `json:"t"`
|
|
||||||
Src string `json:"src"`
|
|
||||||
Hostname string `json:"hostname"`
|
|
||||||
Date string `json:"date"`
|
|
||||||
Created string `json:"created"`
|
|
||||||
} `json:"ipdata"`
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (host *Host) GetOrCreate(session *xorm.Session) (apihost *APIHost, err error) {
|
|
||||||
has, err := session.Get(host)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
session.Insert(host)
|
|
||||||
} else {
|
|
||||||
session.ID(host.ID).Update(host)
|
|
||||||
}
|
|
||||||
host.Get(session)
|
|
||||||
apihost = host.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (host *Host) Get(session *xorm.Session) (apihost *APIHost, err error) {
|
|
||||||
has, err := session.Get(host)
|
|
||||||
if !has || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apihost = host.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (host *Host) APIFormat() *APIHost {
|
|
||||||
if host == nil {
|
|
||||||
return &APIHost{}
|
|
||||||
}
|
|
||||||
return &APIHost{
|
|
||||||
Host: host.Host,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (host *Host) APIParse(apihost APIHost) (err error) {
|
|
||||||
*host = Host{
|
|
||||||
Host: apihost.Host}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Host struct {
|
|
||||||
ID int `xorm:"pk autoincr"`
|
|
||||||
Host string `xorm:"text unique host" json:"host"`
|
|
||||||
Created time.Time `xorm:"created notnull"`
|
|
||||||
Updated time.Time `xorm:"updated notnull"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APIHost struct {
|
|
||||||
ID int `json:"-"`
|
|
||||||
Host string `json:"host"`
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetIPsWithoutHostInfo(ctx *context.Context, config *config.Config) (apiips []string, err error) {
|
|
||||||
res, err := config.Db.Query(`
|
|
||||||
SELECT ip
|
|
||||||
FROM ip
|
|
||||||
WHERE ip NOT IN (
|
|
||||||
SELECT ip FROM host_info)
|
|
||||||
ORDER BY RANDOM()
|
|
||||||
LIMIT 10;`)
|
|
||||||
for _, r := range res {
|
|
||||||
apiips = append(apiips, string(r["ip"]))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProcessHostInfo(cfg *config.Config, hostinfos []HostInfo) (err error) {
|
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
defer session.Close()
|
|
||||||
for _, hi := range hostinfos {
|
|
||||||
var i IP = HostInfoToIP(session, &hi)
|
|
||||||
i.GetOrCreate(session)
|
|
||||||
}
|
|
||||||
session.Commit()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func HostInfoToIP(session *xorm.Session, hi *HostInfo) (ip IP) {
|
|
||||||
ip = IP{
|
|
||||||
IP: hi.IP,
|
|
||||||
Rdns: sql.NullString{
|
|
||||||
String: hi.Rdns,
|
|
||||||
Valid: true},
|
|
||||||
City: &City{CityName: hi.City},
|
|
||||||
Country: &Country{CountryName: hi.Country},
|
|
||||||
AutonomousSystem: &AutonomousSystem{ID: 0},
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type HostInfo struct {
|
|
||||||
IP string `json:"ip"`
|
|
||||||
Whois string `json:"whois"`
|
|
||||||
Rdns string `json:"rdns"`
|
|
||||||
City string `json:"city"`
|
|
||||||
Country string `json:"country"`
|
|
||||||
}
|
|
301
src/models/ip.go
301
src/models/ip.go
@ -3,24 +3,15 @@ package models
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net"
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const SCANLIMIT = 100
|
//var lastday = time.Now().Add(-(time.Hour * 24))
|
||||||
|
|
||||||
const IPINFO_WS = "https://ip.paulbsd.com"
|
|
||||||
|
|
||||||
var lastday = time.Now().Add(-(time.Hour * 24))
|
|
||||||
|
|
||||||
func GetIPs(ctx *context.Context, config *config.Config, limit int) (apiips []*APIIP, err error) {
|
func GetIPs(ctx *context.Context, config *config.Config, limit int) (apiips []*APIIP, err error) {
|
||||||
var ips []IP
|
var ips []IP
|
||||||
@ -31,263 +22,135 @@ func GetIPs(ctx *context.Context, config *config.Config, limit int) (apiips []*A
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetIPsLast(ctx *context.Context, config *config.Config, interval string) (apiips []string, err error) {
|
func GetIPsLast(ctx *context.Context, config *config.Config, interval string) (apiips []*APIIP, err error) {
|
||||||
var ips []IP
|
var ips []IP
|
||||||
err = config.Db.Where("updated >= (now()-?::interval)", interval).GroupBy("ip").Find(&ips)
|
err = config.Db.Where("updated >= (now()-?::interval)", interval).GroupBy("ip").Find(&ips)
|
||||||
for _, ml := range ips {
|
for _, ml := range ips {
|
||||||
apiips = append(apiips, ml.IP)
|
apiips = append(apiips, ml.APIFormat())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ip *IP) GetOrCreate(session *xorm.Session) (apiip *APIIP, err error) {
|
func GetIP(ctx *context.Context, config *config.Config, ipquery interface{}) (apiip *APIIP, err error) {
|
||||||
ip.City.GetOrCreate(session)
|
var ip IP
|
||||||
ip.Country.GetOrCreate(session)
|
has, err := config.Db.Where("ip = ?", ipquery).Get(&ip)
|
||||||
ip.AutonomousSystem.GetOrCreate(session)
|
|
||||||
session.Commit()
|
|
||||||
|
|
||||||
var tmpip *IP
|
|
||||||
if ip.ID != 0 {
|
|
||||||
tmpip = &IP{ID: ip.ID, IP: ip.IP}
|
|
||||||
} else {
|
|
||||||
tmpip = &IP{IP: ip.IP}
|
|
||||||
}
|
|
||||||
has, err := session.Get(tmpip)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
if !has {
|
if !has {
|
||||||
session.Insert(ip)
|
|
||||||
} else {
|
|
||||||
ip.ID = tmpip.ID
|
|
||||||
session.ID(ip.ID).AllCols().Update(ip)
|
|
||||||
session.ID(ip.ID).Cols("city_id", "country_id", "as_id").Update(ip)
|
|
||||||
}
|
|
||||||
session.Commit()
|
|
||||||
|
|
||||||
ip.Get(session)
|
|
||||||
apiip = ip.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ip *IP) Get(session *xorm.Session) (apiip *APIIP, err error) {
|
|
||||||
has, err := session.Get(ip)
|
|
||||||
if !has || err != nil {
|
|
||||||
err = fmt.Errorf("not found")
|
err = fmt.Errorf("not found")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
apiip = ip.APIFormat()
|
apiip = ip.APIFormat()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ip *IP) InsertOrUpdate(session *xorm.Session) (numinsert int64, numupdate int64, err error) {
|
func (i *IP) UpdateRDNS() (result string, err error) {
|
||||||
has, err := session.Get(ip)
|
res, err := net.LookupAddr(i.IP)
|
||||||
if has {
|
if err != nil {
|
||||||
session.ID(ip.ID).Update(&IP{})
|
result = ""
|
||||||
|
} else {
|
||||||
|
result = res[0]
|
||||||
}
|
}
|
||||||
session.Commit()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func InsertIPBulk(session *xorm.Session, ips *[]IP) (numinsert int64, numupdate int64, err error) {
|
func (i *IP) InsertIP(cfg *config.Config) (num int64, err error) {
|
||||||
|
num, err = cfg.Db.Insert(i)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func InsertIPBulk(cfg *config.Config, ips *[]IP) (numinserts int64, numupdates int64, numfail int64, err error) {
|
||||||
|
var iplist []string
|
||||||
|
hostname := (*ips)[0].Hostname
|
||||||
for _, ip := range *ips {
|
for _, ip := range *ips {
|
||||||
numinsert, numupdate, err = ip.InsertOrUpdate(session)
|
iplist = append(iplist, ip.IP)
|
||||||
}
|
}
|
||||||
Cleanup(session)
|
|
||||||
|
var searchips []IP
|
||||||
|
cfg.Db.In("ip", iplist).Where("hostname = ?", hostname).Find(&searchips)
|
||||||
|
|
||||||
|
var toupdateips []string
|
||||||
|
for _, ip := range searchips {
|
||||||
|
toupdateips = append(toupdateips, ip.IP)
|
||||||
|
}
|
||||||
|
numupdates, _ = cfg.Db.In("ip", toupdateips).Where("hostname = ?", hostname).Cols("updated").Update(&IP{})
|
||||||
|
|
||||||
|
var toinsertip, _ = differ(*ips, searchips)
|
||||||
|
numinserts, err = cfg.Db.Insert(toinsertip)
|
||||||
|
|
||||||
|
Cleanup(cfg)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ScanIP(cfg *config.Config) (err error) {
|
func ScanIP(cfg *config.Config) (err error) {
|
||||||
var numthreads int = runtime.NumCPU() / 2
|
|
||||||
for {
|
for {
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
orphans := []IP{}
|
orphans := []IP{}
|
||||||
err = session.Where(`
|
if cfg.Db.Where("rdns IS NULL").Asc("ip").Find(&orphans); len(orphans) > 0 {
|
||||||
(
|
for _, i := range orphans {
|
||||||
(
|
reverse, _ := i.UpdateRDNS()
|
||||||
as_id IS NULL
|
log.Printf("%s -> \"%s\"\n", i.IP, reverse)
|
||||||
OR country_id IS NULL
|
i.Rdns.String = reverse
|
||||||
OR city_id IS NULL
|
i.Rdns.Valid = true
|
||||||
OR rdns = ''
|
_, err = cfg.Db.ID(i.ID).Cols("rdns").Update(&i)
|
||||||
OR rdns IS NULL
|
if err != nil {
|
||||||
)
|
log.Println(err)
|
||||||
AND updated < now()-'1d'::interval
|
}
|
||||||
)
|
|
||||||
OR
|
|
||||||
(
|
|
||||||
as_id IS NULL
|
|
||||||
AND country_id IS NULL
|
|
||||||
AND city_id IS NULL
|
|
||||||
AND rdns IS NULL
|
|
||||||
)
|
|
||||||
`).Desc("updated").Limit(SCANLIMIT).Find(&orphans)
|
|
||||||
session.Close()
|
|
||||||
|
|
||||||
if err == nil && len(orphans) > 0 {
|
|
||||||
orphanchan := make(chan IP)
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
for thr := range make([]int, numthreads) {
|
|
||||||
go ScanOrphan(&wg, orphanchan, thr, cfg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, orphan := range orphans {
|
|
||||||
orphanchan <- orphan
|
|
||||||
}
|
|
||||||
|
|
||||||
close(orphanchan)
|
|
||||||
wg.Wait()
|
|
||||||
} else {
|
} else {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ScanOrphan(wg *sync.WaitGroup, orphans chan IP, thr int, cfg *config.Config) (err error) {
|
func Cleanup(cfg *config.Config) (err error) {
|
||||||
wg.Add(1)
|
results, _ := cfg.Db.Query("select * from ip where ip in (select ip from ip group by ip having count(ip) > 1) and hostname is null order by updated desc;")
|
||||||
|
if len(results) > 0 {
|
||||||
session := cfg.Db.NewSession()
|
_, err := cfg.Db.Query("delete from ip where ip in (select ip from ip group by ip having count(ip) > 1) and hostname is null;")
|
||||||
defer session.Close()
|
if err != nil {
|
||||||
queryclient := http.Client{}
|
log.Println("error deleting orphans")
|
||||||
|
|
||||||
for {
|
|
||||||
orphan, more := <-orphans
|
|
||||||
if more {
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
var query QueryIP
|
|
||||||
query, err := QueryInfo(cfg, &queryclient, orphan.IP)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
time.Sleep(1 * time.Minute)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var as = AutonomousSystem{ASID: query.APIAS.Number, ASName: query.APIAS.Org}
|
|
||||||
orphan.AutonomousSystem = &as
|
|
||||||
|
|
||||||
if query.APICity != "" {
|
|
||||||
var city = City{CityName: query.APICity}
|
|
||||||
orphan.City = &city
|
|
||||||
}
|
|
||||||
|
|
||||||
if query.APICountry != "" {
|
|
||||||
var country = Country{CountryName: query.APICountry}
|
|
||||||
orphan.Country = &country
|
|
||||||
}
|
|
||||||
|
|
||||||
orphan.Rdns = sql.NullString{String: query.Rdns, Valid: true}
|
|
||||||
if cfg.Options.Debug {
|
|
||||||
log.Printf("t%d: %s -> \"%s\"\n", thr, orphan.IP, query.Rdns)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = orphan.GetOrCreate(session)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.Printf("All orphan migrated on thread num %d\n", thr)
|
|
||||||
wg.Done()
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = session.Commit()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func QueryInfo(cfg *config.Config, client *http.Client, ip string) (query QueryIP, err error) {
|
|
||||||
var url = fmt.Sprintf("%s/%s", IPINFO_WS, ip)
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
req.Header.Add("Accept", "*/*")
|
|
||||||
req.Header.Add("User-Agent", fmt.Sprintf("ipbl %s", cfg.Options.Version))
|
|
||||||
res, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data, err := io.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(data, &query)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Cleanup(session *xorm.Session) (err error) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ip *IP) APIFormat() *APIIP {
|
func (ip *IP) APIFormat() *APIIP {
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return &APIIP{}
|
return nil
|
||||||
}
|
}
|
||||||
return &APIIP{
|
return &APIIP{
|
||||||
IP: ip.IP,
|
IP: ip.IP,
|
||||||
Rdns: ip.Rdns.String,
|
Rdns: ip.Rdns.String,
|
||||||
APIAS: *ip.AutonomousSystem.APIFormat(),
|
Src: ip.Src,
|
||||||
APICity: ip.City.APIFormat().CityName,
|
Hostname: ip.Hostname.String,
|
||||||
APICountry: ip.Country.APIFormat().CountryName,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (ip *APIIP) APIConvert() *IP {
|
||||||
func (ip *IP) APIParse(apiip APIIP) (err error) {
|
if ip == nil {
|
||||||
*ip = IP{
|
return nil
|
||||||
IP: apiip.IP,
|
}
|
||||||
Rdns: sql.NullString{
|
return &IP{
|
||||||
String: apiip.Rdns,
|
IP: ip.IP,
|
||||||
Valid: true},
|
Rdns: sql.NullString{String: ip.Rdns, Valid: true},
|
||||||
AutonomousSystem: &AutonomousSystem{
|
Src: ip.Src,
|
||||||
ASID: apiip.APIAS.ASID,
|
Hostname: sql.NullString{String: ip.Hostname, Valid: true},
|
||||||
ASName: apiip.APIAS.ASName,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ip *APIIP) BeforeInsert() (err error) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IP struct {
|
type IP struct {
|
||||||
ID int `xorm:"pk autoincr"`
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
IP string `xorm:"text notnull unique"`
|
IP string `xorm:"text notnull unique(ipsrc)" json:"ip"`
|
||||||
Rdns sql.NullString `xorm:"text index default ''"`
|
Rdns sql.NullString `xorm:"text default" json:"rdns"`
|
||||||
AutonomousSystem *AutonomousSystem `xorm:"as_id int index default null"`
|
Src string `xorm:"text notnull unique(ipsrc)" json:"src"`
|
||||||
City *City `xorm:"city_id int index default null"`
|
Hostname sql.NullString `xorm:"text default '' unique(ipsrc)" json:"hostname"`
|
||||||
Country *Country `xorm:"country_id int index default null"`
|
Created time.Time `xorm:"created notnull" json:"-"`
|
||||||
Created time.Time `xorm:"created notnull"`
|
Updated time.Time `xorm:"updated notnull" json:"-"`
|
||||||
Updated time.Time `xorm:"updated index notnull"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIIP struct {
|
type APIIP struct {
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Rdns string `json:"rdns"`
|
Rdns string `json:"rdns"`
|
||||||
APIAS APIAutonomousSystem `json:"as"`
|
Src string `json:"src"`
|
||||||
APICity string `json:"city"`
|
Hostname string `json:"hostname"`
|
||||||
APICountry string `json:"country"`
|
|
||||||
APIWhois string `json:"whois"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryIP struct {
|
|
||||||
IP string `json:"ip"`
|
|
||||||
Rdns string `json:"hostname"`
|
|
||||||
APIAS QueryAutonomousSystem `json:"as"`
|
|
||||||
APICity string `json:"city"`
|
|
||||||
APICountry string `json:"country"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryAutonomousSystem struct {
|
|
||||||
Number int `json:"number"`
|
|
||||||
Org string `json:"org"`
|
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
"xorm.io/xorm/names"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
tables []interface{}
|
|
||||||
HasEngine bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
tables = append(tables,
|
|
||||||
new(AutonomousSystem),
|
|
||||||
new(Cfg),
|
|
||||||
new(CfgSet),
|
|
||||||
new(CfgExpr),
|
|
||||||
new(CfgTrustlist),
|
|
||||||
new(CfgWS),
|
|
||||||
new(City),
|
|
||||||
new(Country),
|
|
||||||
new(Event),
|
|
||||||
new(IP),
|
|
||||||
new(Src),
|
|
||||||
new(Host),
|
|
||||||
)
|
|
||||||
for _, name := range []string{"SSL", "UID"} {
|
|
||||||
names.LintGonicMapper[name] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEngine initializes a new xorm.Engine
|
|
||||||
func NewEngine(ctx *context.Context, config *config.Config) (err error) {
|
|
||||||
var x = config.Db
|
|
||||||
|
|
||||||
if err = x.Ping(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = x.Sync2(tables...); err != nil {
|
|
||||||
return fmt.Errorf("sync database struct error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DropTables initializes a new xorm.Engine
|
|
||||||
func DropTables(ctx *context.Context, config *config.Config) (err error) {
|
|
||||||
var x = config.Db
|
|
||||||
|
|
||||||
if err = x.Ping(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = x.Sync2(tables...); err != nil {
|
|
||||||
return fmt.Errorf("sync database struct error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (sr *ScanResult) GetOrCreate(cfg *config.Config) (apisr *APIScanResult, err error) {
|
|
||||||
has, err := cfg.Db.Get(sr)
|
|
||||||
if !has {
|
|
||||||
cfg.Db.Insert(sr)
|
|
||||||
} else {
|
|
||||||
cfg.Db.ID(sr.ID).Update(sr)
|
|
||||||
}
|
|
||||||
sr.Get(cfg)
|
|
||||||
apisr = sr.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *ScanResult) Get(cfg *config.Config) (apisr *APIScanResult, err error) {
|
|
||||||
has, err := cfg.Db.Get(sr)
|
|
||||||
if !has || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apisr = sr.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *ScanResult) APIFormat() *APIScanResult {
|
|
||||||
if sr == nil {
|
|
||||||
return &APIScanResult{}
|
|
||||||
}
|
|
||||||
return &APIScanResult{
|
|
||||||
Protocol: sr.Protocol,
|
|
||||||
PortID: sr.PortID,
|
|
||||||
State: sr.State,
|
|
||||||
ServiceName: sr.ServiceName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *ScanResult) APIParse(apisr APIScanResult) (err error) {
|
|
||||||
*sr = ScanResult{
|
|
||||||
Protocol: apisr.Protocol,
|
|
||||||
PortID: apisr.PortID}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type ScanResult struct {
|
|
||||||
ID int `xorm:"pk autoincr"`
|
|
||||||
Protocol string `xorm:"text default ''"`
|
|
||||||
PortID int `xorm:"default ''"`
|
|
||||||
State string `xorm:"text default ''"`
|
|
||||||
ServiceName string `xorm:"text default ''"`
|
|
||||||
Created time.Time `xorm:"created notnull"`
|
|
||||||
Updated time.Time `xorm:"updated notnull"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APIScanResult struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Protocol string `json:"proto"`
|
|
||||||
PortID int `json:"port_id"`
|
|
||||||
State string `json:"state"`
|
|
||||||
ServiceName string `json:"service"`
|
|
||||||
}
|
|
@ -1,58 +1,6 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (src *Src) GetOrCreate(session *xorm.Session) (apisrc *APISrc, err error) {
|
|
||||||
has, err := session.Get(src)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
session.Insert(src)
|
|
||||||
} else {
|
|
||||||
session.ID(src.ID).Update(src)
|
|
||||||
}
|
|
||||||
src.Get(session)
|
|
||||||
apisrc = src.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (src *Src) Get(session *xorm.Session) (apisrc *APISrc, err error) {
|
|
||||||
has, err := session.Get(src)
|
|
||||||
if !has || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apisrc = src.APIFormat()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (src *Src) APIFormat() *APISrc {
|
|
||||||
if src == nil {
|
|
||||||
return &APISrc{}
|
|
||||||
}
|
|
||||||
return &APISrc{
|
|
||||||
Src: src.Src,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (src *Src) APIParse(apisrc APISrc) (err error) {
|
|
||||||
*src = Src{
|
|
||||||
Src: apisrc.Src}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Src struct {
|
type Src struct {
|
||||||
ID int `xorm:"pk autoincr"`
|
ID int `xorm:"pk autoincr" json:"-"`
|
||||||
Src string `xorm:"text unique(srcindex) src" json:"src"`
|
Src string `xorm:"text notnull unique" json:"src"`
|
||||||
Created time.Time `xorm:"created notnull"`
|
|
||||||
Updated time.Time `xorm:"updated notnull"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type APISrc struct {
|
|
||||||
ID int `json:"-"`
|
|
||||||
Src string `json:"src"`
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package models
|
|||||||
|
|
||||||
import "reflect"
|
import "reflect"
|
||||||
|
|
||||||
func Differ(sl1 []IP, sl2 []IP) (toinsert []IP, err error) {
|
//const keyname string = "id"
|
||||||
|
|
||||||
|
func differ(sl1 []IP, sl2 []IP) (toinsert []IP, err error) {
|
||||||
var m = make(map[string]IPDiffer)
|
var m = make(map[string]IPDiffer)
|
||||||
longslice := append(sl1, sl2...)
|
longslice := append(sl1, sl2...)
|
||||||
|
|
||||||
@ -11,7 +13,7 @@ func Differ(sl1 []IP, sl2 []IP) (toinsert []IP, err error) {
|
|||||||
m[v2.IP] = IPDiffer{IP: v2, Num: 1}
|
m[v2.IP] = IPDiffer{IP: v2, Num: 1}
|
||||||
} else {
|
} else {
|
||||||
if this, ok := m[v2.IP]; ok {
|
if this, ok := m[v2.IP]; ok {
|
||||||
this.Num++
|
this.Num += 1
|
||||||
m[v2.IP] = this
|
m[v2.IP] = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,53 +3,44 @@ package routers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/ws"
|
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
||||||
e.GET("/", func(c echo.Context) error {
|
e.GET("/", func(c echo.Context) error {
|
||||||
return c.HTML(http.StatusOK, `
|
return c.HTML(http.StatusOK, `<html>
|
||||||
<html>
|
<body>
|
||||||
<head></head>
|
<p>Welcome to ipbl software (<a href="https://git.paulbsd.com/paulbsd/ipbl">https://git.paulbsd.com/paulbsd/ipbl</a>)</p>
|
||||||
<body>
|
</body>
|
||||||
<p>Welcome to ipbl software (<a href="https://git.paulbsd.com/paulbsd/ipbl">https://git.paulbsd.com/paulbsd/ipbl</a>)</p>
|
</html>`)
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
|
|
||||||
e.GET("/health", func(c echo.Context) error {
|
|
||||||
return c.HTML(http.StatusOK, `OK`)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
e.GET("/ip/:ip", func(c echo.Context) (err error) {
|
e.GET("/ip/:ip", func(c echo.Context) (err error) {
|
||||||
session := cfg.Db.NewSession()
|
ret, err := models.GetIP(ctx, cfg, c.Param("ip"))
|
||||||
defer session.Close()
|
|
||||||
var ip = models.IP{IP: c.Param("ip")}
|
|
||||||
ret, err := ip.Get(session)
|
|
||||||
return Result(c, err, ret)
|
return Result(c, err, ret)
|
||||||
})
|
})
|
||||||
e.POST("/ip", func(c echo.Context) (err error) {
|
e.POST("/ip", func(c echo.Context) (err error) {
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
var apiip = new(models.APIIP)
|
|
||||||
var ip = new(models.IP)
|
var ip = new(models.IP)
|
||||||
var msg = "No IP inserted"
|
var msg = "No IP inserted"
|
||||||
err = c.Bind(apiip)
|
err = c.Bind(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Result(c, fmt.Errorf("error when parsing body"), "")
|
return Result(c, fmt.Errorf("error when parsing body"), "")
|
||||||
}
|
}
|
||||||
ip.APIParse(*apiip)
|
num, err := ip.InsertIP(cfg)
|
||||||
_, err = ip.GetOrCreate(session)
|
fmt.Println(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Result(c, err, "")
|
return Result(c, err, "")
|
||||||
}
|
}
|
||||||
|
if num > 0 {
|
||||||
|
msg = fmt.Sprintf("Inserted %d IP", num)
|
||||||
|
}
|
||||||
return Result(c, err, msg)
|
return Result(c, err, msg)
|
||||||
})
|
})
|
||||||
e.GET("/ips", func(c echo.Context) (err error) {
|
e.GET("/ips", func(c echo.Context) (err error) {
|
||||||
@ -61,20 +52,14 @@ func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
|||||||
return Result(c, err, ret)
|
return Result(c, err, ret)
|
||||||
})
|
})
|
||||||
e.GET("/ips/last", func(c echo.Context) (err error) {
|
e.GET("/ips/last", func(c echo.Context) (err error) {
|
||||||
interval := "30m"
|
interval := "30 minutes"
|
||||||
if c.QueryParam("interval") != "" {
|
if c.QueryParam("interval") != "" {
|
||||||
interval = c.QueryParam("interval")
|
interval = c.QueryParam("interval")
|
||||||
}
|
}
|
||||||
ret, err := models.GetIPsLast(ctx, cfg, interval)
|
ret, err := models.GetIPsLast(ctx, cfg, interval)
|
||||||
return Result(c, err, ret)
|
return Result(c, err, ret)
|
||||||
})
|
})
|
||||||
e.GET("/ips/withouthostinfo", func(c echo.Context) (err error) {
|
|
||||||
ret, err := models.GetIPsWithoutHostInfo(ctx, cfg)
|
|
||||||
return Result(c, err, ret)
|
|
||||||
})
|
|
||||||
e.POST("/ips", func(c echo.Context) (err error) {
|
e.POST("/ips", func(c echo.Context) (err error) {
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
defer session.Close()
|
|
||||||
var apiips = []models.APIIP{}
|
var apiips = []models.APIIP{}
|
||||||
var ips = []models.IP{}
|
var ips = []models.IP{}
|
||||||
var msg string
|
var msg string
|
||||||
@ -82,53 +67,33 @@ func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return Result(c, err, apiips)
|
return Result(c, err, apiips)
|
||||||
}
|
}
|
||||||
for _, apiip := range apiips {
|
for _, v := range apiips {
|
||||||
var ip = new(models.IP)
|
ips = append(ips, *v.APIConvert())
|
||||||
ip.APIParse(apiip)
|
}
|
||||||
ips = append(ips, *ip)
|
numinsert, numupdate, _, _ := models.InsertIPBulk(cfg, &ips)
|
||||||
|
if numinsert > 0 {
|
||||||
|
msg = fmt.Sprintf("inserted %d IP", numinsert)
|
||||||
|
log.Println(msg)
|
||||||
|
}
|
||||||
|
if numupdate > 0 {
|
||||||
|
if len(msg) > 0 {
|
||||||
|
msg = fmt.Sprintf("%s, updated %d IP", msg, numupdate)
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintf("updated %d IP", numupdate)
|
||||||
|
}
|
||||||
|
log.Println(msg)
|
||||||
}
|
}
|
||||||
numinsert, numupdate, _ := models.InsertIPBulk(session, &ips)
|
|
||||||
msg = fmt.Sprintf("Inserted %d IP, Updated %d IP", numinsert, numupdate)
|
|
||||||
return Result(c, err, msg)
|
return Result(c, err, msg)
|
||||||
})
|
})
|
||||||
e.POST("/event", func(c echo.Context) (err error) {
|
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
defer session.Close()
|
|
||||||
var apievent = new(models.APIEvent)
|
|
||||||
var event = new(models.Event)
|
|
||||||
err = c.Bind(apievent)
|
|
||||||
if err != nil {
|
|
||||||
return Result(c, fmt.Errorf("error when parsing body"), "")
|
|
||||||
}
|
|
||||||
event.APIParse(session, *apievent)
|
|
||||||
err = event.Insert(cfg)
|
|
||||||
if err != nil {
|
|
||||||
return Result(c, err, "")
|
|
||||||
}
|
|
||||||
return Result(c, err, "OK")
|
|
||||||
})
|
|
||||||
e.POST("/hostinfo", func(c echo.Context) (err error) {
|
|
||||||
var hostinfos = []models.HostInfo{}
|
|
||||||
err = c.Bind(&hostinfos)
|
|
||||||
if err != nil {
|
|
||||||
return Result(c, err, hostinfos)
|
|
||||||
}
|
|
||||||
models.ProcessHostInfo(cfg, hostinfos)
|
|
||||||
return Result(c, err, "")
|
|
||||||
})
|
|
||||||
e.GET("/config", func(c echo.Context) (err error) {
|
|
||||||
globalconfig, err := models.GetAllConfigv2(cfg)
|
|
||||||
return Result(c, err, globalconfig)
|
|
||||||
})
|
|
||||||
e.GET("/config/trustlist", func(c echo.Context) (err error) {
|
e.GET("/config/trustlist", func(c echo.Context) (err error) {
|
||||||
trustlists, err := models.GetTrustlists(cfg)
|
trustlists, err := models.GetTrustlists(*cfg)
|
||||||
return Result(c, err, trustlists)
|
return Result(c, err, trustlists)
|
||||||
})
|
})
|
||||||
e.POST("/config/trustlist", func(c echo.Context) (err error) {
|
e.POST("/config/trustlist", func(c echo.Context) (err error) {
|
||||||
var cidr models.CfgTrustlist
|
var cidr models.CfgTrustlist
|
||||||
err = c.Bind(&cidr)
|
err = c.Bind(&cidr)
|
||||||
if err == nil && cidr.Verify() {
|
if err == nil && cidr.Verify() {
|
||||||
err = cidr.InsertOrUpdate(cfg)
|
err = cidr.InsertOrUpdate(*cfg)
|
||||||
return Result(c, err, cidr)
|
return Result(c, err, cidr)
|
||||||
}
|
}
|
||||||
return Result(c, err, nil)
|
return Result(c, err, nil)
|
||||||
@ -136,28 +101,28 @@ func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
|
|||||||
e.DELETE("/config/trustlist/:ip", func(c echo.Context) (err error) {
|
e.DELETE("/config/trustlist/:ip", func(c echo.Context) (err error) {
|
||||||
var ip = c.Param("ip")
|
var ip = c.Param("ip")
|
||||||
var cidr models.CfgTrustlist
|
var cidr models.CfgTrustlist
|
||||||
_, err = cidr.Delete(cfg, ip)
|
_, err = cidr.Delete(*cfg, ip)
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
e.GET("/config/sets", func(c echo.Context) (err error) {
|
e.GET("/config/sets", func(c echo.Context) (err error) {
|
||||||
sets, err := models.GetSets(cfg)
|
sets, err := models.GetSets(*cfg)
|
||||||
return Result(c, err, sets)
|
return Result(c, err, sets)
|
||||||
})
|
})
|
||||||
e.GET("/config/ws", func(c echo.Context) (err error) {
|
e.POST("/config/folders", func(c echo.Context) (err error) {
|
||||||
folders, err := models.GetWS(cfg)
|
var sets []models.CfgSet
|
||||||
|
err = c.Bind(&sets)
|
||||||
|
if err != nil {
|
||||||
|
return Result(c, err, "Unable to parse JSON")
|
||||||
|
}
|
||||||
|
_, err = models.InsertOrUpdateSets(*cfg, sets)
|
||||||
|
return Result(c, err, sets)
|
||||||
|
})
|
||||||
|
e.GET("/config/zmq", func(c echo.Context) (err error) {
|
||||||
|
folders, err := models.GetZMQ(*cfg)
|
||||||
return Result(c, err, folders)
|
return Result(c, err, folders)
|
||||||
})
|
})
|
||||||
e.GET("/discovery", func(c echo.Context) (err error) {
|
e.GET("/discovery", func(c echo.Context) (err error) {
|
||||||
disc, err := models.DiscoverURLS(cfg, e.Routes())
|
disc, err := models.DiscoverURLS(*cfg, e.Routes())
|
||||||
return Result(c, err, disc)
|
return Result(c, err, disc)
|
||||||
})
|
})
|
||||||
e.File("/test.html", "/home/paul/test.html")
|
|
||||||
e.GET("/wsps", func(c echo.Context) (err error) {
|
|
||||||
ws.HandleWSPS(&c, cfg)
|
|
||||||
return
|
|
||||||
})
|
|
||||||
e.GET("/wsrr", func(c echo.Context) (err error) {
|
|
||||||
ws.HandleWSRR(&c, cfg)
|
|
||||||
return
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,6 @@ func RunServer(ctx *context.Context, cfg *config.Config) (err error) {
|
|||||||
|
|
||||||
func Result(c echo.Context, inputerr error, data interface{}) (err error) {
|
func Result(c echo.Context, inputerr error, data interface{}) (err error) {
|
||||||
if inputerr != nil {
|
if inputerr != nil {
|
||||||
if inputerr.Error() == "not found" {
|
|
||||||
return c.String(http.StatusNotFound, "Content not found")
|
|
||||||
}
|
|
||||||
if inputerr.Error() == "Not Found" {
|
if inputerr.Error() == "Not Found" {
|
||||||
return c.String(http.StatusNotFound, "Content not found")
|
return c.String(http.StatusNotFound, "Content not found")
|
||||||
}
|
}
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
package ws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
)
|
|
||||||
|
|
||||||
var listeners sync.Map
|
|
||||||
|
|
||||||
func Init(cfg *config.Config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func welcomeAgents(ws *websocket.Conn, welcome wsWelcome, t string) {
|
|
||||||
connectinfoVal, ok := listeners.Load(welcome.Hostname)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
switch t {
|
|
||||||
case "ps":
|
|
||||||
connectinfo := connectionInfo{
|
|
||||||
ConnectionPS: ws,
|
|
||||||
InitDate: time.Now(),
|
|
||||||
}
|
|
||||||
listeners.Store(welcome.Hostname, &connectinfo)
|
|
||||||
case "rr":
|
|
||||||
connectinfo := connectionInfo{
|
|
||||||
ConnectionRR: ws,
|
|
||||||
InitDate: time.Now(),
|
|
||||||
}
|
|
||||||
listeners.Store(welcome.Hostname, &connectinfo)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
connectinfo := connectinfoVal.(*connectionInfo)
|
|
||||||
switch t {
|
|
||||||
case "ps":
|
|
||||||
connectinfo.ConnectionPS = ws
|
|
||||||
case "rr":
|
|
||||||
connectinfo.ConnectionRR = ws
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func gcConnOnError(ws *websocket.Conn) (err error) {
|
|
||||||
listeners.Range(func(index, value interface{}) bool {
|
|
||||||
if value.(*connectionInfo).ConnectionPS == ws || value.(*connectionInfo).ConnectionRR == ws {
|
|
||||||
value.(*connectionInfo).ConnectionPS.Close()
|
|
||||||
value.(*connectionInfo).ConnectionRR.Close()
|
|
||||||
listeners.Delete(index)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type connectionInfo struct {
|
|
||||||
ConnectionPS *websocket.Conn
|
|
||||||
ConnectionRR *websocket.Conn
|
|
||||||
InitDate time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// WSWelcome
|
|
||||||
type wsWelcome struct {
|
|
||||||
Hostname string
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package ws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HandleWSPS handle pub sub flows
|
|
||||||
func HandleWSPS(c *echo.Context, cfg *config.Config) (err error) {
|
|
||||||
websocket.Handler(func(ws *websocket.Conn) {
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
var welcome = wsWelcome{}
|
|
||||||
|
|
||||||
var msg []byte
|
|
||||||
err := websocket.Message.Receive(ws, &msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(msg, &welcome)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
} else {
|
|
||||||
welcomeAgents(ws, welcome, "ps")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = websocket.Message.Receive(ws, "OK")
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("disconnect: %s (from pubsub channel)\n", welcome.Hostname)
|
|
||||||
ws.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}).ServeHTTP((*c).Response(), (*c).Request())
|
|
||||||
return nil
|
|
||||||
}
|
|
123
src/ws/reqrep.go
123
src/ws/reqrep.go
@ -1,123 +0,0 @@
|
|||||||
package ws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
|
||||||
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HandleWSRR handle req rep flows
|
|
||||||
func HandleWSRR(c *echo.Context, cfg *config.Config) error {
|
|
||||||
websocket.Handler(func(ws *websocket.Conn) {
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
var welcome = wsWelcome{}
|
|
||||||
|
|
||||||
var msg []byte
|
|
||||||
err := websocket.Message.Receive(ws, &msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(msg, &welcome)
|
|
||||||
if err == nil {
|
|
||||||
welcomeAgents(ws, welcome, "rr")
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastip string
|
|
||||||
for {
|
|
||||||
var apievent = models.APIEvent{}
|
|
||||||
var event = models.Event{}
|
|
||||||
|
|
||||||
var msg []byte
|
|
||||||
err := websocket.Message.Receive(ws, &msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("disconnect: %s (from reqrep channel)", welcome.Hostname)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(msg, &apievent)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if lastip != "" && apievent.IPData.IP == lastip {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch apievent.MsgType {
|
|
||||||
case "bootstrap":
|
|
||||||
log.Printf("bootstrap: %s\n", apievent.Hostname)
|
|
||||||
listeners.Range(func(index, value interface{}) bool {
|
|
||||||
if index != apievent.Hostname && value.(*connectionInfo).ConnectionPS != nil {
|
|
||||||
err = websocket.Message.Send(value.(*connectionInfo).ConnectionPS, msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
ws.Close()
|
|
||||||
gcConnOnError(ws)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
case "add":
|
|
||||||
session := cfg.Db.NewSession()
|
|
||||||
event.APIParse(session, apievent)
|
|
||||||
session.Close()
|
|
||||||
|
|
||||||
err := event.Insert(cfg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners.Range(func(index, value interface{}) bool {
|
|
||||||
if value.(*connectionInfo).ConnectionPS != nil {
|
|
||||||
err = websocket.Message.Send(value.(*connectionInfo).ConnectionPS, msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
ws.Close()
|
|
||||||
gcConnOnError(ws)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
log.Printf("ws: Inserted event")
|
|
||||||
case "init":
|
|
||||||
listeners.Range(func(index, value interface{}) bool {
|
|
||||||
if value.(*connectionInfo).ConnectionPS != nil {
|
|
||||||
err = websocket.Message.Send(value.(*connectionInfo).ConnectionPS, msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
ws.Close()
|
|
||||||
gcConnOnError(ws)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
case "ping":
|
|
||||||
listeners.Range(func(index, value interface{}) bool {
|
|
||||||
if index == apievent.Hostname && value.(*connectionInfo).ConnectionPS != nil {
|
|
||||||
err = websocket.Message.Send(value.(*connectionInfo).ConnectionPS, msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
ws.Close()
|
|
||||||
gcConnOnError(ws)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
err = websocket.Message.Send(ws, "OK")
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
gcConnOnError(ws)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).ServeHTTP((*c).Response(), (*c).Request())
|
|
||||||
return nil
|
|
||||||
}
|
|
78
src/zmqrouter/main.go
Normal file
78
src/zmqrouter/main.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package zmqrouter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.paulbsd.com/paulbsd/ipbl/src/config"
|
||||||
|
"git.paulbsd.com/paulbsd/ipbl/src/models"
|
||||||
|
"gopkg.in/zeromq/goczmq.v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Init(cfg *config.Config) (err error) {
|
||||||
|
log.Println("Initiating ZMQ sockets")
|
||||||
|
reqsock, err := InitRep()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pubsock, err := InitPub()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle(cfg, reqsock, pubsock, cfg.Options.ZMQChannel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handle(cfg *config.Config, reqsock *goczmq.Sock, pubsock *goczmq.Sock, channel string) (err error) {
|
||||||
|
log.Println("Start handling zmq sockets")
|
||||||
|
for {
|
||||||
|
var msg = "err"
|
||||||
|
var req, err = reqsock.RecvMessage()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("unable to receive message from req socket")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var topub [][]byte
|
||||||
|
for _, val := range req {
|
||||||
|
var ip = models.IP{}
|
||||||
|
err = json.Unmarshal(val, &ip)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("unable to parse ip address", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
has, err := cfg.Db.Get(&ip)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error fetching ip address", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !has {
|
||||||
|
num, err := cfg.Db.Insert(&ip)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error inserting ip address", num, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
num, err := cfg.Db.Where("id = ?", ip.ID).Update(&ip)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error updating ip address", num, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmpval := fmt.Sprintf("%s %s", channel, string(val))
|
||||||
|
val = []byte(tmpval)
|
||||||
|
topub = append(topub, val)
|
||||||
|
}
|
||||||
|
err = pubsock.SendMessage(topub)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error sending message to pub socket")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msg = "ok"
|
||||||
|
var resp [][]byte = [][]byte{[]byte(msg)}
|
||||||
|
err = reqsock.SendMessage(resp)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error replying message to req socket")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/zmqrouter/pubsub.go
Normal file
10
src/zmqrouter/pubsub.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package zmqrouter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/zeromq/goczmq.v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitPub() (sock *goczmq.Sock, err error) {
|
||||||
|
sock, err = goczmq.NewPub("tcp://*:9999")
|
||||||
|
return
|
||||||
|
}
|
10
src/zmqrouter/reqrep.go
Normal file
10
src/zmqrouter/reqrep.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package zmqrouter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/zeromq/goczmq.v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitRep() (sock *goczmq.Sock, err error) {
|
||||||
|
sock, err = goczmq.NewRep("tcp://*:9998")
|
||||||
|
return
|
||||||
|
}
|
11
vendor/github.com/goccy/go-json/.golangci.yml
generated
vendored
11
vendor/github.com/goccy/go-json/.golangci.yml
generated
vendored
@ -48,17 +48,6 @@ linters:
|
|||||||
- nlreturn
|
- nlreturn
|
||||||
- testpackage
|
- testpackage
|
||||||
- wsl
|
- wsl
|
||||||
- varnamelen
|
|
||||||
- nilnil
|
|
||||||
- ireturn
|
|
||||||
- govet
|
|
||||||
- forcetypeassert
|
|
||||||
- cyclop
|
|
||||||
- containedctx
|
|
||||||
- revive
|
|
||||||
- nosnakecase
|
|
||||||
- exhaustruct
|
|
||||||
- depguard
|
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
|
102
vendor/github.com/goccy/go-json/CHANGELOG.md
generated
vendored
102
vendor/github.com/goccy/go-json/CHANGELOG.md
generated
vendored
@ -1,105 +1,3 @@
|
|||||||
# v0.10.2 - 2023/03/20
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
* Support DebugDOT option for debugging encoder ( #440 )
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix combination of embedding structure and omitempty option ( #442 )
|
|
||||||
|
|
||||||
# v0.10.1 - 2023/03/13
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix checkptr error for array decoder ( #415 )
|
|
||||||
* Fix added buffer size check when decoding key ( #430 )
|
|
||||||
* Fix handling of anonymous fields other than struct ( #431 )
|
|
||||||
* Fix to not optimize when lower conversion can't handle byte-by-byte ( #432 )
|
|
||||||
* Fix a problem that MarshalIndent does not work when UnorderedMap is specified ( #435 )
|
|
||||||
* Fix mapDecoder.DecodeStream() for empty objects containing whitespace ( #425 )
|
|
||||||
* Fix an issue that could not set the correct NextField for fields in the embedded structure ( #438 )
|
|
||||||
|
|
||||||
# v0.10.0 - 2022/11/29
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
* Support JSON Path ( #250 )
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix marshaler for map's key ( #409 )
|
|
||||||
|
|
||||||
# v0.9.11 - 2022/08/18
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix unexpected behavior when buffer ends with backslash ( #383 )
|
|
||||||
* Fix stream decoding of escaped character ( #387 )
|
|
||||||
|
|
||||||
# v0.9.10 - 2022/07/15
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix boundary exception of type caching ( #382 )
|
|
||||||
|
|
||||||
# v0.9.9 - 2022/07/15
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix encoding of directed interface with typed nil ( #377 )
|
|
||||||
* Fix embedded primitive type encoding using alias ( #378 )
|
|
||||||
* Fix slice/array type encoding with types implementing MarshalJSON ( #379 )
|
|
||||||
* Fix unicode decoding when the expected buffer state is not met after reading ( #380 )
|
|
||||||
|
|
||||||
# v0.9.8 - 2022/06/30
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix decoding of surrogate-pair ( #365 )
|
|
||||||
* Fix handling of embedded primitive type ( #366 )
|
|
||||||
* Add validation of escape sequence for decoder ( #367 )
|
|
||||||
* Fix stream tokenizing respecting UseNumber ( #369 )
|
|
||||||
* Fix encoding when struct pointer type that implements Marshal JSON is embedded ( #375 )
|
|
||||||
|
|
||||||
### Improve performance
|
|
||||||
|
|
||||||
* Improve performance of linkRecursiveCode ( #368 )
|
|
||||||
|
|
||||||
# v0.9.7 - 2022/04/22
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
#### Encoder
|
|
||||||
|
|
||||||
* Add filtering process for encoding on slow path ( #355 )
|
|
||||||
* Fix encoding of interface{} with pointer type ( #363 )
|
|
||||||
|
|
||||||
#### Decoder
|
|
||||||
|
|
||||||
* Fix map key decoder that implements UnmarshalJSON ( #353 )
|
|
||||||
* Fix decoding of []uint8 type ( #361 )
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
* Add DebugWith option for encoder ( #356 )
|
|
||||||
|
|
||||||
# v0.9.6 - 2022/03/22
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Correct the handling of the minimum value of int type for decoder ( #344 )
|
|
||||||
* Fix bugs of stream decoder's bufferSize ( #349 )
|
|
||||||
* Add a guard to use typeptr more safely ( #351 )
|
|
||||||
|
|
||||||
### Improve decoder performance
|
|
||||||
|
|
||||||
* Improve escapeString's performance ( #345 )
|
|
||||||
|
|
||||||
### Others
|
|
||||||
|
|
||||||
* Update go version for CI ( #347 )
|
|
||||||
|
|
||||||
# v0.9.5 - 2022/03/04
|
# v0.9.5 - 2022/03/04
|
||||||
|
|
||||||
### Fix bugs
|
### Fix bugs
|
||||||
|
4
vendor/github.com/goccy/go-json/Makefile
generated
vendored
4
vendor/github.com/goccy/go-json/Makefile
generated
vendored
@ -22,7 +22,7 @@ cover-html: cover
|
|||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: golangci-lint
|
lint: golangci-lint
|
||||||
$(BIN_DIR)/golangci-lint run
|
golangci-lint run
|
||||||
|
|
||||||
golangci-lint: | $(BIN_DIR)
|
golangci-lint: | $(BIN_DIR)
|
||||||
@{ \
|
@{ \
|
||||||
@ -30,7 +30,7 @@ golangci-lint: | $(BIN_DIR)
|
|||||||
GOLANGCI_LINT_TMP_DIR=$$(mktemp -d); \
|
GOLANGCI_LINT_TMP_DIR=$$(mktemp -d); \
|
||||||
cd $$GOLANGCI_LINT_TMP_DIR; \
|
cd $$GOLANGCI_LINT_TMP_DIR; \
|
||||||
go mod init tmp; \
|
go mod init tmp; \
|
||||||
GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2; \
|
GOBIN=$(BIN_DIR) go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.36.0; \
|
||||||
rm -rf $$GOLANGCI_LINT_TMP_DIR; \
|
rm -rf $$GOLANGCI_LINT_TMP_DIR; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/goccy/go-json/README.md
generated
vendored
2
vendor/github.com/goccy/go-json/README.md
generated
vendored
@ -184,7 +184,7 @@ func Marshal(v interface{}) ([]byte, error) {
|
|||||||
`json.Marshal` and `json.Unmarshal` receive `interface{}` value and they perform type determination dynamically to process.
|
`json.Marshal` and `json.Unmarshal` receive `interface{}` value and they perform type determination dynamically to process.
|
||||||
In normal case, you need to use the `reflect` library to determine the type dynamically, but since `reflect.Type` is defined as `interface`, when you call the method of `reflect.Type`, The reflect's argument is escaped.
|
In normal case, you need to use the `reflect` library to determine the type dynamically, but since `reflect.Type` is defined as `interface`, when you call the method of `reflect.Type`, The reflect's argument is escaped.
|
||||||
|
|
||||||
Therefore, the arguments for `Marshal` and `Unmarshal` are always escaped to the heap.
|
Therefore, the arguments for `Marshal` and `Unmarshal` are always escape to the heap.
|
||||||
However, `go-json` can use the feature of `reflect.Type` while avoiding escaping.
|
However, `go-json` can use the feature of `reflect.Type` while avoiding escaping.
|
||||||
|
|
||||||
`reflect.Type` is defined as `interface`, but in reality `reflect.Type` is implemented only by the structure `rtype` defined in the `reflect` package.
|
`reflect.Type` is defined as `interface`, but in reality `reflect.Type` is implemented only by the structure `rtype` defined in the `reflect` package.
|
||||||
|
31
vendor/github.com/goccy/go-json/decode.go
generated
vendored
31
vendor/github.com/goccy/go-json/decode.go
generated
vendored
@ -83,37 +83,6 @@ func unmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs
|
|||||||
return validateEndBuf(src, cursor)
|
return validateEndBuf(src, cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
pathDecoder = decoder.NewPathDecoder()
|
|
||||||
)
|
|
||||||
|
|
||||||
func extractFromPath(path *Path, data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
|
|
||||||
if path.path.RootSelectorOnly {
|
|
||||||
return [][]byte{data}, nil
|
|
||||||
}
|
|
||||||
src := make([]byte, len(data)+1) // append nul byte to the end
|
|
||||||
copy(src, data)
|
|
||||||
|
|
||||||
ctx := decoder.TakeRuntimeContext()
|
|
||||||
ctx.Buf = src
|
|
||||||
ctx.Option.Flags = 0
|
|
||||||
ctx.Option.Flags |= decoder.PathOption
|
|
||||||
ctx.Option.Path = path.path
|
|
||||||
for _, optFunc := range optFuncs {
|
|
||||||
optFunc(ctx.Option)
|
|
||||||
}
|
|
||||||
paths, cursor, err := pathDecoder.DecodePath(ctx, 0, 0)
|
|
||||||
if err != nil {
|
|
||||||
decoder.ReleaseRuntimeContext(ctx)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
decoder.ReleaseRuntimeContext(ctx)
|
|
||||||
if err := validateEndBuf(src, cursor); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return paths, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
|
func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
|
||||||
src := make([]byte, len(data)+1) // append nul byte to the end
|
src := make([]byte, len(data)+1) // append nul byte to the end
|
||||||
copy(src, data)
|
copy(src, data)
|
||||||
|
2
vendor/github.com/goccy/go-json/docker-compose.yml
generated
vendored
2
vendor/github.com/goccy/go-json/docker-compose.yml
generated
vendored
@ -1,7 +1,7 @@
|
|||||||
version: '2'
|
version: '2'
|
||||||
services:
|
services:
|
||||||
go-json:
|
go-json:
|
||||||
image: golang:1.18
|
image: golang:1.17
|
||||||
volumes:
|
volumes:
|
||||||
- '.:/go/src/go-json'
|
- '.:/go/src/go-json'
|
||||||
deploy:
|
deploy:
|
||||||
|
6
vendor/github.com/goccy/go-json/encode.go
generated
vendored
6
vendor/github.com/goccy/go-json/encode.go
generated
vendored
@ -3,7 +3,6 @@ package json
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/encoder"
|
"github.com/goccy/go-json/internal/encoder"
|
||||||
@ -52,7 +51,7 @@ func (e *Encoder) EncodeContext(ctx context.Context, v interface{}, optFuncs ...
|
|||||||
rctx.Option.Flag |= encoder.ContextOption
|
rctx.Option.Flag |= encoder.ContextOption
|
||||||
rctx.Option.Context = ctx
|
rctx.Option.Context = ctx
|
||||||
|
|
||||||
err := e.encodeWithOption(rctx, v, optFuncs...) //nolint: contextcheck
|
err := e.encodeWithOption(rctx, v, optFuncs...)
|
||||||
|
|
||||||
encoder.ReleaseRuntimeContext(rctx)
|
encoder.ReleaseRuntimeContext(rctx)
|
||||||
return err
|
return err
|
||||||
@ -63,7 +62,6 @@ func (e *Encoder) encodeWithOption(ctx *encoder.RuntimeContext, v interface{}, o
|
|||||||
ctx.Option.Flag |= encoder.HTMLEscapeOption
|
ctx.Option.Flag |= encoder.HTMLEscapeOption
|
||||||
}
|
}
|
||||||
ctx.Option.Flag |= encoder.NormalizeUTF8Option
|
ctx.Option.Flag |= encoder.NormalizeUTF8Option
|
||||||
ctx.Option.DebugOut = os.Stdout
|
|
||||||
for _, optFunc := range optFuncs {
|
for _, optFunc := range optFuncs {
|
||||||
optFunc(ctx.Option)
|
optFunc(ctx.Option)
|
||||||
}
|
}
|
||||||
@ -120,7 +118,7 @@ func marshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOption
|
|||||||
optFunc(rctx.Option)
|
optFunc(rctx.Option)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := encode(rctx, v) //nolint: contextcheck
|
buf, err := encode(rctx, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
encoder.ReleaseRuntimeContext(rctx)
|
encoder.ReleaseRuntimeContext(rctx)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
2
vendor/github.com/goccy/go-json/error.go
generated
vendored
2
vendor/github.com/goccy/go-json/error.go
generated
vendored
@ -37,5 +37,3 @@ type UnmarshalTypeError = errors.UnmarshalTypeError
|
|||||||
type UnsupportedTypeError = errors.UnsupportedTypeError
|
type UnsupportedTypeError = errors.UnsupportedTypeError
|
||||||
|
|
||||||
type UnsupportedValueError = errors.UnsupportedValueError
|
type UnsupportedValueError = errors.UnsupportedValueError
|
||||||
|
|
||||||
type PathError = errors.PathError
|
|
||||||
|
4
vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go
generated
vendored
4
vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go
generated
vendored
@ -35,7 +35,3 @@ func (d *anonymousFieldDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,
|
|||||||
p = *(*unsafe.Pointer)(p)
|
p = *(*unsafe.Pointer)(p)
|
||||||
return d.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+d.offset))
|
return d.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+d.offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *anonymousFieldDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return d.dec.DecodePath(ctx, cursor, depth)
|
|
||||||
}
|
|
||||||
|
9
vendor/github.com/goccy/go-json/internal/decoder/array.go
generated
vendored
9
vendor/github.com/goccy/go-json/internal/decoder/array.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package decoder
|
package decoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/errors"
|
"github.com/goccy/go-json/internal/errors"
|
||||||
@ -19,9 +18,7 @@ type arrayDecoder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
|
func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
|
||||||
// workaround to avoid checkptr errors. cannot use `*(*unsafe.Pointer)(unsafe_New(elemType))` directly.
|
zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType))
|
||||||
zeroValuePtr := unsafe_New(elemType)
|
|
||||||
zeroValue := **(**unsafe.Pointer)(unsafe.Pointer(&zeroValuePtr))
|
|
||||||
return &arrayDecoder{
|
return &arrayDecoder{
|
||||||
valueDecoder: dec,
|
valueDecoder: dec,
|
||||||
elemType: elemType,
|
elemType: elemType,
|
||||||
@ -170,7 +167,3 @@ func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *arrayDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: array decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
438
vendor/github.com/goccy/go-json/internal/decoder/assign.go
generated
vendored
438
vendor/github.com/goccy/go-json/internal/decoder/assign.go
generated
vendored
@ -1,438 +0,0 @@
|
|||||||
package decoder
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
nilValue = reflect.ValueOf(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
func AssignValue(src, dst reflect.Value) error {
|
|
||||||
if dst.Type().Kind() != reflect.Ptr {
|
|
||||||
return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type())
|
|
||||||
}
|
|
||||||
casted, err := castValue(dst.Elem().Type(), src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dst.Elem().Set(casted)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) {
|
|
||||||
switch t.Kind() {
|
|
||||||
case reflect.Int:
|
|
||||||
vv, err := castInt(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(int(vv.Int())), nil
|
|
||||||
case reflect.Int8:
|
|
||||||
vv, err := castInt(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(int8(vv.Int())), nil
|
|
||||||
case reflect.Int16:
|
|
||||||
vv, err := castInt(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(int16(vv.Int())), nil
|
|
||||||
case reflect.Int32:
|
|
||||||
vv, err := castInt(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(int32(vv.Int())), nil
|
|
||||||
case reflect.Int64:
|
|
||||||
return castInt(v)
|
|
||||||
case reflect.Uint:
|
|
||||||
vv, err := castUint(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(uint(vv.Uint())), nil
|
|
||||||
case reflect.Uint8:
|
|
||||||
vv, err := castUint(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(uint8(vv.Uint())), nil
|
|
||||||
case reflect.Uint16:
|
|
||||||
vv, err := castUint(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(uint16(vv.Uint())), nil
|
|
||||||
case reflect.Uint32:
|
|
||||||
vv, err := castUint(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(uint32(vv.Uint())), nil
|
|
||||||
case reflect.Uint64:
|
|
||||||
return castUint(v)
|
|
||||||
case reflect.Uintptr:
|
|
||||||
vv, err := castUint(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(uintptr(vv.Uint())), nil
|
|
||||||
case reflect.String:
|
|
||||||
return castString(v)
|
|
||||||
case reflect.Bool:
|
|
||||||
return castBool(v)
|
|
||||||
case reflect.Float32:
|
|
||||||
vv, err := castFloat(v)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(float32(vv.Float())), nil
|
|
||||||
case reflect.Float64:
|
|
||||||
return castFloat(v)
|
|
||||||
case reflect.Array:
|
|
||||||
return castArray(t, v)
|
|
||||||
case reflect.Slice:
|
|
||||||
return castSlice(t, v)
|
|
||||||
case reflect.Map:
|
|
||||||
return castMap(t, v)
|
|
||||||
case reflect.Struct:
|
|
||||||
return castStruct(t, v)
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func castInt(v reflect.Value) (reflect.Value, error) {
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return v, nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
return reflect.ValueOf(int64(v.Uint())), nil
|
|
||||||
case reflect.String:
|
|
||||||
i64, err := strconv.ParseInt(v.String(), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(i64), nil
|
|
||||||
case reflect.Bool:
|
|
||||||
if v.Bool() {
|
|
||||||
return reflect.ValueOf(int64(1)), nil
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(int64(0)), nil
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return reflect.ValueOf(int64(v.Float())), nil
|
|
||||||
case reflect.Array:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castInt(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to int64 from empty array")
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castInt(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to int64 from empty slice")
|
|
||||||
case reflect.Interface:
|
|
||||||
return castInt(reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Map:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to int64 from map")
|
|
||||||
case reflect.Struct:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to int64 from struct")
|
|
||||||
case reflect.Ptr:
|
|
||||||
return castInt(v.Elem())
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func castUint(v reflect.Value) (reflect.Value, error) {
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return reflect.ValueOf(uint64(v.Int())), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
return v, nil
|
|
||||||
case reflect.String:
|
|
||||||
u64, err := strconv.ParseUint(v.String(), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(u64), nil
|
|
||||||
case reflect.Bool:
|
|
||||||
if v.Bool() {
|
|
||||||
return reflect.ValueOf(uint64(1)), nil
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(uint64(0)), nil
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return reflect.ValueOf(uint64(v.Float())), nil
|
|
||||||
case reflect.Array:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castUint(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to uint64 from empty array")
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castUint(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to uint64 from empty slice")
|
|
||||||
case reflect.Interface:
|
|
||||||
return castUint(reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Map:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to uint64 from map")
|
|
||||||
case reflect.Struct:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to uint64 from struct")
|
|
||||||
case reflect.Ptr:
|
|
||||||
return castUint(v.Elem())
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func castString(v reflect.Value) (reflect.Value, error) {
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return reflect.ValueOf(fmt.Sprint(v.Int())), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
return reflect.ValueOf(fmt.Sprint(v.Uint())), nil
|
|
||||||
case reflect.String:
|
|
||||||
return v, nil
|
|
||||||
case reflect.Bool:
|
|
||||||
if v.Bool() {
|
|
||||||
return reflect.ValueOf("true"), nil
|
|
||||||
}
|
|
||||||
return reflect.ValueOf("false"), nil
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return reflect.ValueOf(fmt.Sprint(v.Float())), nil
|
|
||||||
case reflect.Array:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castString(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from empty array")
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castString(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from empty slice")
|
|
||||||
case reflect.Interface:
|
|
||||||
return castString(reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Map:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from map")
|
|
||||||
case reflect.Struct:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from struct")
|
|
||||||
case reflect.Ptr:
|
|
||||||
return castString(v.Elem())
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func castBool(v reflect.Value) (reflect.Value, error) {
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
switch v.Int() {
|
|
||||||
case 0:
|
|
||||||
return reflect.ValueOf(false), nil
|
|
||||||
case 1:
|
|
||||||
return reflect.ValueOf(true), nil
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int())
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
switch v.Uint() {
|
|
||||||
case 0:
|
|
||||||
return reflect.ValueOf(false), nil
|
|
||||||
case 1:
|
|
||||||
return reflect.ValueOf(true), nil
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint())
|
|
||||||
case reflect.String:
|
|
||||||
b, err := strconv.ParseBool(v.String())
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(b), nil
|
|
||||||
case reflect.Bool:
|
|
||||||
return v, nil
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
switch v.Float() {
|
|
||||||
case 0:
|
|
||||||
return reflect.ValueOf(false), nil
|
|
||||||
case 1:
|
|
||||||
return reflect.ValueOf(true), nil
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float())
|
|
||||||
case reflect.Array:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castBool(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from empty array")
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castBool(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from empty slice")
|
|
||||||
case reflect.Interface:
|
|
||||||
return castBool(reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Map:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from map")
|
|
||||||
case reflect.Struct:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to string from struct")
|
|
||||||
case reflect.Ptr:
|
|
||||||
return castBool(v.Elem())
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func castFloat(v reflect.Value) (reflect.Value, error) {
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return reflect.ValueOf(float64(v.Int())), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
return reflect.ValueOf(float64(v.Uint())), nil
|
|
||||||
case reflect.String:
|
|
||||||
f64, err := strconv.ParseFloat(v.String(), 64)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(f64), nil
|
|
||||||
case reflect.Bool:
|
|
||||||
if v.Bool() {
|
|
||||||
return reflect.ValueOf(float64(1)), nil
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(float64(0)), nil
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return v, nil
|
|
||||||
case reflect.Array:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castFloat(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to float64 from empty array")
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castFloat(v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to float64 from empty slice")
|
|
||||||
case reflect.Interface:
|
|
||||||
return castFloat(reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Map:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to float64 from map")
|
|
||||||
case reflect.Struct:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to float64 from struct")
|
|
||||||
case reflect.Ptr:
|
|
||||||
return castFloat(v.Elem())
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) {
|
|
||||||
kind := v.Type().Kind()
|
|
||||||
if kind == reflect.Interface {
|
|
||||||
return castArray(t, reflect.ValueOf(v.Interface()))
|
|
||||||
}
|
|
||||||
if kind != reflect.Slice && kind != reflect.Array {
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to array from %s", kind)
|
|
||||||
}
|
|
||||||
if t.Elem() == v.Type().Elem() {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
if t.Len() != v.Len() {
|
|
||||||
return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len())
|
|
||||||
}
|
|
||||||
ret := reflect.New(t).Elem()
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
vv, err := castValue(t.Elem(), v.Index(i))
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
ret.Index(i).Set(vv)
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) {
|
|
||||||
kind := v.Type().Kind()
|
|
||||||
if kind == reflect.Interface {
|
|
||||||
return castSlice(t, reflect.ValueOf(v.Interface()))
|
|
||||||
}
|
|
||||||
if kind != reflect.Slice && kind != reflect.Array {
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to slice from %s", kind)
|
|
||||||
}
|
|
||||||
if t.Elem() == v.Type().Elem() {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
ret := reflect.MakeSlice(t, v.Len(), v.Len())
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
vv, err := castValue(t.Elem(), v.Index(i))
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
ret.Index(i).Set(vv)
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) {
|
|
||||||
ret := reflect.MakeMap(t)
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
iter := v.MapRange()
|
|
||||||
for iter.Next() {
|
|
||||||
key, err := castValue(t.Key(), iter.Key())
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
value, err := castValue(t.Elem(), iter.Value())
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
ret.SetMapIndex(key, value)
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
case reflect.Interface:
|
|
||||||
return castMap(t, reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castMap(t, v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to map from empty slice")
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) {
|
|
||||||
ret := reflect.New(t).Elem()
|
|
||||||
switch v.Type().Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
iter := v.MapRange()
|
|
||||||
for iter.Next() {
|
|
||||||
key := iter.Key()
|
|
||||||
k, err := castString(key)
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
fieldName := k.String()
|
|
||||||
field, ok := t.FieldByName(fieldName)
|
|
||||||
if ok {
|
|
||||||
value, err := castValue(field.Type, iter.Value())
|
|
||||||
if err != nil {
|
|
||||||
return nilValue, err
|
|
||||||
}
|
|
||||||
ret.FieldByName(fieldName).Set(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
case reflect.Struct:
|
|
||||||
for i := 0; i < v.Type().NumField(); i++ {
|
|
||||||
name := v.Type().Field(i).Name
|
|
||||||
ret.FieldByName(name).Set(v.FieldByName(name))
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
case reflect.Interface:
|
|
||||||
return castStruct(t, reflect.ValueOf(v.Interface()))
|
|
||||||
case reflect.Slice:
|
|
||||||
if v.Len() > 0 {
|
|
||||||
return castStruct(t, v.Index(0))
|
|
||||||
}
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to struct from empty slice")
|
|
||||||
default:
|
|
||||||
return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind())
|
|
||||||
}
|
|
||||||
}
|
|
5
vendor/github.com/goccy/go-json/internal/decoder/bool.go
generated
vendored
5
vendor/github.com/goccy/go-json/internal/decoder/bool.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package decoder
|
package decoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/errors"
|
"github.com/goccy/go-json/internal/errors"
|
||||||
@ -77,7 +76,3 @@ func (d *boolDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.
|
|||||||
}
|
}
|
||||||
return 0, errors.ErrUnexpectedEndOfJSON("bool", cursor)
|
return 0, errors.ErrUnexpectedEndOfJSON("bool", cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *boolDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: bool decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
10
vendor/github.com/goccy/go-json/internal/decoder/bytes.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/decoder/bytes.go
generated
vendored
@ -2,7 +2,6 @@ package decoder
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/errors"
|
"github.com/goccy/go-json/internal/errors"
|
||||||
@ -24,8 +23,9 @@ func byteUnmarshalerSliceDecoder(typ *runtime.Type, structName string, fieldName
|
|||||||
unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName)
|
unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName)
|
||||||
case runtime.PtrTo(typ).Implements(unmarshalTextType):
|
case runtime.PtrTo(typ).Implements(unmarshalTextType):
|
||||||
unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName)
|
unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName)
|
||||||
default:
|
}
|
||||||
unmarshalDecoder, _ = compileUint8(typ, structName, fieldName)
|
if unmarshalDecoder == nil {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName)
|
return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName)
|
||||||
}
|
}
|
||||||
@ -79,10 +79,6 @@ func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe
|
|||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bytesDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: []byte decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) {
|
func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) {
|
||||||
c := s.skipWhiteSpace()
|
c := s.skipWhiteSpace()
|
||||||
if c == '[' {
|
if c == '[' {
|
||||||
|
23
vendor/github.com/goccy/go-json/internal/decoder/compile.go
generated
vendored
23
vendor/github.com/goccy/go-json/internal/decoder/compile.go
generated
vendored
@ -24,7 +24,7 @@ func init() {
|
|||||||
if typeAddr == nil {
|
if typeAddr == nil {
|
||||||
typeAddr = &runtime.TypeAddr{}
|
typeAddr = &runtime.TypeAddr{}
|
||||||
}
|
}
|
||||||
cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift+1)
|
cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadDecoderMap() map[uintptr]Decoder {
|
func loadDecoderMap() map[uintptr]Decoder {
|
||||||
@ -154,9 +154,6 @@ func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeTo
|
|||||||
if runtime.PtrTo(typ).Implements(unmarshalTextType) {
|
if runtime.PtrTo(typ).Implements(unmarshalTextType) {
|
||||||
return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
|
return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
|
||||||
}
|
}
|
||||||
if typ.Kind() == reflect.String {
|
|
||||||
return newStringDecoder(structName, fieldName), nil
|
|
||||||
}
|
|
||||||
dec, err := compile(typ, structName, fieldName, structTypeToDecoder)
|
dec, err := compile(typ, structName, fieldName, structTypeToDecoder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -393,25 +390,7 @@ func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeTo
|
|||||||
}
|
}
|
||||||
allFields = append(allFields, fieldSet)
|
allFields = append(allFields, fieldSet)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fieldSet := &structFieldSet{
|
|
||||||
dec: pdec,
|
|
||||||
offset: field.Offset,
|
|
||||||
isTaggedKey: tag.IsTaggedKey,
|
|
||||||
key: field.Name,
|
|
||||||
keyLen: int64(len(field.Name)),
|
|
||||||
}
|
|
||||||
allFields = append(allFields, fieldSet)
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fieldSet := &structFieldSet{
|
|
||||||
dec: dec,
|
|
||||||
offset: field.Offset,
|
|
||||||
isTaggedKey: tag.IsTaggedKey,
|
|
||||||
key: field.Name,
|
|
||||||
keyLen: int64(len(field.Name)),
|
|
||||||
}
|
|
||||||
allFields = append(allFields, fieldSet)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) {
|
if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) {
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build !race
|
|
||||||
// +build !race
|
// +build !race
|
||||||
|
|
||||||
package decoder
|
package decoder
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/decoder/compile_race.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/decoder/compile_race.go
generated
vendored
@ -1,4 +1,3 @@
|
|||||||
//go:build race
|
|
||||||
// +build race
|
// +build race
|
||||||
|
|
||||||
package decoder
|
package decoder
|
||||||
|
12
vendor/github.com/goccy/go-json/internal/decoder/float.go
generated
vendored
12
vendor/github.com/goccy/go-json/internal/decoder/float.go
generated
vendored
@ -156,15 +156,3 @@ func (d *floatDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe
|
|||||||
d.op(p, f64)
|
d.op(p, f64)
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *floatDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
buf := ctx.Buf
|
|
||||||
bytes, c, err := d.decodeByte(buf, cursor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
if bytes == nil {
|
|
||||||
return [][]byte{nullbytes}, c, nil
|
|
||||||
}
|
|
||||||
return [][]byte{bytes}, c, nil
|
|
||||||
}
|
|
||||||
|
5
vendor/github.com/goccy/go-json/internal/decoder/func.go
generated
vendored
5
vendor/github.com/goccy/go-json/internal/decoder/func.go
generated
vendored
@ -2,7 +2,6 @@ package decoder
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/errors"
|
"github.com/goccy/go-json/internal/errors"
|
||||||
@ -140,7 +139,3 @@ func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.
|
|||||||
}
|
}
|
||||||
return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
|
return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *funcDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: func decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
16
vendor/github.com/goccy/go-json/internal/decoder/int.go
generated
vendored
16
vendor/github.com/goccy/go-json/internal/decoder/int.go
generated
vendored
@ -192,15 +192,15 @@ func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
|
|||||||
}
|
}
|
||||||
switch d.kind {
|
switch d.kind {
|
||||||
case reflect.Int8:
|
case reflect.Int8:
|
||||||
if i64 < -1*(1<<7) || (1<<7) <= i64 {
|
if i64 <= -1*(1<<7) || (1<<7) <= i64 {
|
||||||
return d.typeError(bytes, s.totalOffset())
|
return d.typeError(bytes, s.totalOffset())
|
||||||
}
|
}
|
||||||
case reflect.Int16:
|
case reflect.Int16:
|
||||||
if i64 < -1*(1<<15) || (1<<15) <= i64 {
|
if i64 <= -1*(1<<15) || (1<<15) <= i64 {
|
||||||
return d.typeError(bytes, s.totalOffset())
|
return d.typeError(bytes, s.totalOffset())
|
||||||
}
|
}
|
||||||
case reflect.Int32:
|
case reflect.Int32:
|
||||||
if i64 < -1*(1<<31) || (1<<31) <= i64 {
|
if i64 <= -1*(1<<31) || (1<<31) <= i64 {
|
||||||
return d.typeError(bytes, s.totalOffset())
|
return d.typeError(bytes, s.totalOffset())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,22 +225,18 @@ func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P
|
|||||||
}
|
}
|
||||||
switch d.kind {
|
switch d.kind {
|
||||||
case reflect.Int8:
|
case reflect.Int8:
|
||||||
if i64 < -1*(1<<7) || (1<<7) <= i64 {
|
if i64 <= -1*(1<<7) || (1<<7) <= i64 {
|
||||||
return 0, d.typeError(bytes, cursor)
|
return 0, d.typeError(bytes, cursor)
|
||||||
}
|
}
|
||||||
case reflect.Int16:
|
case reflect.Int16:
|
||||||
if i64 < -1*(1<<15) || (1<<15) <= i64 {
|
if i64 <= -1*(1<<15) || (1<<15) <= i64 {
|
||||||
return 0, d.typeError(bytes, cursor)
|
return 0, d.typeError(bytes, cursor)
|
||||||
}
|
}
|
||||||
case reflect.Int32:
|
case reflect.Int32:
|
||||||
if i64 < -1*(1<<31) || (1<<31) <= i64 {
|
if i64 <= -1*(1<<31) || (1<<31) <= i64 {
|
||||||
return 0, d.typeError(bytes, cursor)
|
return 0, d.typeError(bytes, cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.op(p, i64)
|
d.op(p, i64)
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *intDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: int decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
70
vendor/github.com/goccy/go-json/internal/decoder/interface.go
generated
vendored
70
vendor/github.com/goccy/go-json/internal/decoder/interface.go
generated
vendored
@ -94,7 +94,6 @@ func (d *interfaceDecoder) numDecoder(s *Stream) Decoder {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem())
|
emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem())
|
||||||
EmptyInterfaceType = emptyInterfaceType
|
|
||||||
interfaceMapType = runtime.Type2RType(
|
interfaceMapType = runtime.Type2RType(
|
||||||
reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
|
reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
|
||||||
)
|
)
|
||||||
@ -457,72 +456,3 @@ func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, dep
|
|||||||
}
|
}
|
||||||
return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
|
return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPathDecoder() Decoder {
|
|
||||||
ifaceDecoder := &interfaceDecoder{
|
|
||||||
typ: emptyInterfaceType,
|
|
||||||
structName: "",
|
|
||||||
fieldName: "",
|
|
||||||
floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) {
|
|
||||||
*(*interface{})(p) = v
|
|
||||||
}),
|
|
||||||
numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) {
|
|
||||||
*(*interface{})(p) = v
|
|
||||||
}),
|
|
||||||
stringDecoder: newStringDecoder("", ""),
|
|
||||||
}
|
|
||||||
ifaceDecoder.sliceDecoder = newSliceDecoder(
|
|
||||||
ifaceDecoder,
|
|
||||||
emptyInterfaceType,
|
|
||||||
emptyInterfaceType.Size(),
|
|
||||||
"", "",
|
|
||||||
)
|
|
||||||
ifaceDecoder.mapDecoder = newMapDecoder(
|
|
||||||
interfaceMapType,
|
|
||||||
stringType,
|
|
||||||
ifaceDecoder.stringDecoder,
|
|
||||||
interfaceMapType.Elem(),
|
|
||||||
ifaceDecoder,
|
|
||||||
"", "",
|
|
||||||
)
|
|
||||||
return ifaceDecoder
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
truebytes = []byte("true")
|
|
||||||
falsebytes = []byte("false")
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
buf := ctx.Buf
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
|
||||||
switch buf[cursor] {
|
|
||||||
case '{':
|
|
||||||
return d.mapDecoder.DecodePath(ctx, cursor, depth)
|
|
||||||
case '[':
|
|
||||||
return d.sliceDecoder.DecodePath(ctx, cursor, depth)
|
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
||||||
return d.floatDecoder.DecodePath(ctx, cursor, depth)
|
|
||||||
case '"':
|
|
||||||
return d.stringDecoder.DecodePath(ctx, cursor, depth)
|
|
||||||
case 't':
|
|
||||||
if err := validateTrue(buf, cursor); err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor += 4
|
|
||||||
return [][]byte{truebytes}, cursor, nil
|
|
||||||
case 'f':
|
|
||||||
if err := validateFalse(buf, cursor); err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor += 5
|
|
||||||
return [][]byte{falsebytes}, cursor, nil
|
|
||||||
case 'n':
|
|
||||||
if err := validateNull(buf, cursor); err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor += 4
|
|
||||||
return [][]byte{nullbytes}, cursor, nil
|
|
||||||
}
|
|
||||||
return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
|
|
||||||
}
|
|
||||||
|
10
vendor/github.com/goccy/go-json/internal/decoder/invalid.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/decoder/invalid.go
generated
vendored
@ -43,13 +43,3 @@ func (d *invalidDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsa
|
|||||||
Field: d.fieldName,
|
Field: d.fieldName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *invalidDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, &errors.UnmarshalTypeError{
|
|
||||||
Value: "object",
|
|
||||||
Type: runtime.RType2Type(d.typ),
|
|
||||||
Offset: cursor,
|
|
||||||
Struct: d.structName,
|
|
||||||
Field: d.fieldName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
95
vendor/github.com/goccy/go-json/internal/decoder/map.go
generated
vendored
95
vendor/github.com/goccy/go-json/internal/decoder/map.go
generated
vendored
@ -88,7 +88,7 @@ func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
|
|||||||
mapValue = makemap(d.mapType, 0)
|
mapValue = makemap(d.mapType, 0)
|
||||||
}
|
}
|
||||||
s.cursor++
|
s.cursor++
|
||||||
if s.skipWhiteSpace() == '}' {
|
if s.equalChar('}') {
|
||||||
*(*unsafe.Pointer)(p) = mapValue
|
*(*unsafe.Pointer)(p) = mapValue
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return nil
|
return nil
|
||||||
@ -185,96 +185,3 @@ func (d *mapDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P
|
|||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *mapDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
buf := ctx.Buf
|
|
||||||
depth++
|
|
||||||
if depth > maxDecodeNestingDepth {
|
|
||||||
return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
|
||||||
buflen := int64(len(buf))
|
|
||||||
if buflen < 2 {
|
|
||||||
return nil, 0, errors.ErrExpected("{} for map", cursor)
|
|
||||||
}
|
|
||||||
switch buf[cursor] {
|
|
||||||
case 'n':
|
|
||||||
if err := validateNull(buf, cursor); err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor += 4
|
|
||||||
return [][]byte{nullbytes}, cursor, nil
|
|
||||||
case '{':
|
|
||||||
default:
|
|
||||||
return nil, 0, errors.ErrExpected("{ character for map value", cursor)
|
|
||||||
}
|
|
||||||
cursor++
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
|
||||||
if buf[cursor] == '}' {
|
|
||||||
cursor++
|
|
||||||
return nil, cursor, nil
|
|
||||||
}
|
|
||||||
keyDecoder, ok := d.keyDecoder.(*stringDecoder)
|
|
||||||
if !ok {
|
|
||||||
return nil, 0, &errors.UnmarshalTypeError{
|
|
||||||
Value: "string",
|
|
||||||
Type: reflect.TypeOf(""),
|
|
||||||
Offset: cursor,
|
|
||||||
Struct: d.structName,
|
|
||||||
Field: d.fieldName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret := [][]byte{}
|
|
||||||
for {
|
|
||||||
key, keyCursor, err := keyDecoder.decodeByte(buf, cursor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor = skipWhiteSpace(buf, keyCursor)
|
|
||||||
if buf[cursor] != ':' {
|
|
||||||
return nil, 0, errors.ErrExpected("colon after object key", cursor)
|
|
||||||
}
|
|
||||||
cursor++
|
|
||||||
child, found, err := ctx.Option.Path.Field(string(key))
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
if child != nil {
|
|
||||||
oldPath := ctx.Option.Path.node
|
|
||||||
ctx.Option.Path.node = child
|
|
||||||
paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
ctx.Option.Path.node = oldPath
|
|
||||||
ret = append(ret, paths...)
|
|
||||||
cursor = c
|
|
||||||
} else {
|
|
||||||
start := cursor
|
|
||||||
end, err := skipValue(buf, cursor, depth)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
ret = append(ret, buf[start:end])
|
|
||||||
cursor = end
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c, err := skipValue(buf, cursor, depth)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor = c
|
|
||||||
}
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
|
||||||
if buf[cursor] == '}' {
|
|
||||||
cursor++
|
|
||||||
return ret, cursor, nil
|
|
||||||
}
|
|
||||||
if buf[cursor] != ',' {
|
|
||||||
return nil, 0, errors.ErrExpected("comma after object value", cursor)
|
|
||||||
}
|
|
||||||
cursor++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
11
vendor/github.com/goccy/go-json/internal/decoder/number.go
generated
vendored
11
vendor/github.com/goccy/go-json/internal/decoder/number.go
generated
vendored
@ -51,17 +51,6 @@ func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
|||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *numberDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
bytes, c, err := d.decodeByte(ctx.Buf, cursor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
if bytes == nil {
|
|
||||||
return [][]byte{nullbytes}, c, nil
|
|
||||||
}
|
|
||||||
return [][]byte{bytes}, c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
|
func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
|
||||||
start := s.cursor
|
start := s.cursor
|
||||||
for {
|
for {
|
||||||
|
2
vendor/github.com/goccy/go-json/internal/decoder/option.go
generated
vendored
2
vendor/github.com/goccy/go-json/internal/decoder/option.go
generated
vendored
@ -7,11 +7,9 @@ type OptionFlags uint8
|
|||||||
const (
|
const (
|
||||||
FirstWinOption OptionFlags = 1 << iota
|
FirstWinOption OptionFlags = 1 << iota
|
||||||
ContextOption
|
ContextOption
|
||||||
PathOption
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
Flags OptionFlags
|
Flags OptionFlags
|
||||||
Context context.Context
|
Context context.Context
|
||||||
Path *Path
|
|
||||||
}
|
}
|
||||||
|
670
vendor/github.com/goccy/go-json/internal/decoder/path.go
generated
vendored
670
vendor/github.com/goccy/go-json/internal/decoder/path.go
generated
vendored
@ -1,670 +0,0 @@
|
|||||||
package decoder
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/errors"
|
|
||||||
"github.com/goccy/go-json/internal/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PathString string
|
|
||||||
|
|
||||||
func (s PathString) Build() (*Path, error) {
|
|
||||||
builder := new(PathBuilder)
|
|
||||||
return builder.Build([]rune(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathBuilder struct {
|
|
||||||
root PathNode
|
|
||||||
node PathNode
|
|
||||||
singleQuotePathSelector bool
|
|
||||||
doubleQuotePathSelector bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) Build(buf []rune) (*Path, error) {
|
|
||||||
node, err := b.build(buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Path{
|
|
||||||
node: node,
|
|
||||||
RootSelectorOnly: node == nil,
|
|
||||||
SingleQuotePathSelector: b.singleQuotePathSelector,
|
|
||||||
DoubleQuotePathSelector: b.doubleQuotePathSelector,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) build(buf []rune) (PathNode, error) {
|
|
||||||
if len(buf) == 0 {
|
|
||||||
return nil, errors.ErrEmptyPath()
|
|
||||||
}
|
|
||||||
if buf[0] != '$' {
|
|
||||||
return nil, errors.ErrInvalidPath("JSON Path must start with a $ character")
|
|
||||||
}
|
|
||||||
if len(buf) == 1 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
buf = buf[1:]
|
|
||||||
offset, err := b.buildNext(buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(buf) > offset {
|
|
||||||
return nil, errors.ErrInvalidPath("remain invalid path %q", buf[offset:])
|
|
||||||
}
|
|
||||||
return b.root, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) buildNextCharIfExists(buf []rune, cursor int) (int, error) {
|
|
||||||
if len(buf) > cursor {
|
|
||||||
offset, err := b.buildNext(buf[cursor:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return cursor + 1 + offset, nil
|
|
||||||
}
|
|
||||||
return cursor, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) buildNext(buf []rune) (int, error) {
|
|
||||||
switch buf[0] {
|
|
||||||
case '.':
|
|
||||||
if len(buf) == 1 {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
|
|
||||||
}
|
|
||||||
offset, err := b.buildSelector(buf[1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return offset + 1, nil
|
|
||||||
case '[':
|
|
||||||
if len(buf) == 1 {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
|
|
||||||
}
|
|
||||||
offset, err := b.buildIndex(buf[1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return offset + 1, nil
|
|
||||||
default:
|
|
||||||
return 0, errors.ErrInvalidPath("expect dot or left bracket character. but found %c character", buf[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) buildSelector(buf []rune) (int, error) {
|
|
||||||
switch buf[0] {
|
|
||||||
case '.':
|
|
||||||
if len(buf) == 1 {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with double dot character")
|
|
||||||
}
|
|
||||||
offset, err := b.buildPathRecursive(buf[1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return 1 + offset, nil
|
|
||||||
case '[', ']', '$', '*':
|
|
||||||
return 0, errors.ErrInvalidPath("found invalid path character %c after dot", buf[0])
|
|
||||||
}
|
|
||||||
for cursor := 0; cursor < len(buf); cursor++ {
|
|
||||||
switch buf[cursor] {
|
|
||||||
case '$', '*', ']':
|
|
||||||
return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor])
|
|
||||||
case '.':
|
|
||||||
if cursor+1 >= len(buf) {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
|
|
||||||
}
|
|
||||||
selector := buf[:cursor]
|
|
||||||
b.addSelectorNode(string(selector))
|
|
||||||
offset, err := b.buildSelector(buf[cursor+1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return cursor + 1 + offset, nil
|
|
||||||
case '[':
|
|
||||||
if cursor+1 >= len(buf) {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
|
|
||||||
}
|
|
||||||
selector := buf[:cursor]
|
|
||||||
b.addSelectorNode(string(selector))
|
|
||||||
offset, err := b.buildIndex(buf[cursor+1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return cursor + 1 + offset, nil
|
|
||||||
case '"':
|
|
||||||
if cursor+1 >= len(buf) {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with double quote character")
|
|
||||||
}
|
|
||||||
offset, err := b.buildQuoteSelector(buf[cursor+1:], DoubleQuotePathSelector)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return cursor + 1 + offset, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.addSelectorNode(string(buf))
|
|
||||||
return len(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) buildQuoteSelector(buf []rune, sel QuotePathSelector) (int, error) {
|
|
||||||
switch buf[0] {
|
|
||||||
case '[', ']', '$', '.', '*', '\'', '"':
|
|
||||||
return 0, errors.ErrInvalidPath("found invalid path character %c after quote", buf[0])
|
|
||||||
}
|
|
||||||
for cursor := 0; cursor < len(buf); cursor++ {
|
|
||||||
switch buf[cursor] {
|
|
||||||
case '\'':
|
|
||||||
if sel != SingleQuotePathSelector {
|
|
||||||
return 0, errors.ErrInvalidPath("found double quote character in field selector with single quote context")
|
|
||||||
}
|
|
||||||
if len(buf) <= cursor+1 {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with single quote character in field selector context")
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != ']' {
|
|
||||||
return 0, errors.ErrInvalidPath("expect right bracket for field selector with single quote but found %c", buf[cursor+1])
|
|
||||||
}
|
|
||||||
selector := buf[:cursor]
|
|
||||||
b.addSelectorNode(string(selector))
|
|
||||||
b.singleQuotePathSelector = true
|
|
||||||
return b.buildNextCharIfExists(buf, cursor+2)
|
|
||||||
case '"':
|
|
||||||
if sel != DoubleQuotePathSelector {
|
|
||||||
return 0, errors.ErrInvalidPath("found single quote character in field selector with double quote context")
|
|
||||||
}
|
|
||||||
selector := buf[:cursor]
|
|
||||||
b.addSelectorNode(string(selector))
|
|
||||||
b.doubleQuotePathSelector = true
|
|
||||||
return b.buildNextCharIfExists(buf, cursor+1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errors.ErrInvalidPath("couldn't find quote character in selector quote path context")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) buildPathRecursive(buf []rune) (int, error) {
|
|
||||||
switch buf[0] {
|
|
||||||
case '.', '[', ']', '$', '*':
|
|
||||||
return 0, errors.ErrInvalidPath("found invalid path character %c after double dot", buf[0])
|
|
||||||
}
|
|
||||||
for cursor := 0; cursor < len(buf); cursor++ {
|
|
||||||
switch buf[cursor] {
|
|
||||||
case '$', '*', ']':
|
|
||||||
return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor])
|
|
||||||
case '.':
|
|
||||||
if cursor+1 >= len(buf) {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
|
|
||||||
}
|
|
||||||
selector := buf[:cursor]
|
|
||||||
b.addRecursiveNode(string(selector))
|
|
||||||
offset, err := b.buildSelector(buf[cursor+1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return cursor + 1 + offset, nil
|
|
||||||
case '[':
|
|
||||||
if cursor+1 >= len(buf) {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
|
|
||||||
}
|
|
||||||
selector := buf[:cursor]
|
|
||||||
b.addRecursiveNode(string(selector))
|
|
||||||
offset, err := b.buildIndex(buf[cursor+1:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return cursor + 1 + offset, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.addRecursiveNode(string(buf))
|
|
||||||
return len(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) buildIndex(buf []rune) (int, error) {
|
|
||||||
switch buf[0] {
|
|
||||||
case '.', '[', ']', '$':
|
|
||||||
return 0, errors.ErrInvalidPath("found invalid path character %c after left bracket", buf[0])
|
|
||||||
case '\'':
|
|
||||||
if len(buf) == 1 {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with single quote character")
|
|
||||||
}
|
|
||||||
offset, err := b.buildQuoteSelector(buf[1:], SingleQuotePathSelector)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return 1 + offset, nil
|
|
||||||
case '*':
|
|
||||||
if len(buf) == 1 {
|
|
||||||
return 0, errors.ErrInvalidPath("JSON Path ends with star character")
|
|
||||||
}
|
|
||||||
if buf[1] != ']' {
|
|
||||||
return 0, errors.ErrInvalidPath("expect right bracket character for index all path but found %c character", buf[1])
|
|
||||||
}
|
|
||||||
b.addIndexAllNode()
|
|
||||||
offset := len("*]")
|
|
||||||
if len(buf) > 2 {
|
|
||||||
buildOffset, err := b.buildNext(buf[2:])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return offset + buildOffset, nil
|
|
||||||
}
|
|
||||||
return offset, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for cursor := 0; cursor < len(buf); cursor++ {
|
|
||||||
switch buf[cursor] {
|
|
||||||
case ']':
|
|
||||||
index, err := strconv.ParseInt(string(buf[:cursor]), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.ErrInvalidPath("%q is unexpected index path", buf[:cursor])
|
|
||||||
}
|
|
||||||
b.addIndexNode(int(index))
|
|
||||||
return b.buildNextCharIfExists(buf, cursor+1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errors.ErrInvalidPath("couldn't find right bracket character in index path context")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) addIndexAllNode() {
|
|
||||||
node := newPathIndexAllNode()
|
|
||||||
if b.root == nil {
|
|
||||||
b.root = node
|
|
||||||
b.node = node
|
|
||||||
} else {
|
|
||||||
b.node = b.node.chain(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) addRecursiveNode(selector string) {
|
|
||||||
node := newPathRecursiveNode(selector)
|
|
||||||
if b.root == nil {
|
|
||||||
b.root = node
|
|
||||||
b.node = node
|
|
||||||
} else {
|
|
||||||
b.node = b.node.chain(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) addSelectorNode(name string) {
|
|
||||||
node := newPathSelectorNode(name)
|
|
||||||
if b.root == nil {
|
|
||||||
b.root = node
|
|
||||||
b.node = node
|
|
||||||
} else {
|
|
||||||
b.node = b.node.chain(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *PathBuilder) addIndexNode(idx int) {
|
|
||||||
node := newPathIndexNode(idx)
|
|
||||||
if b.root == nil {
|
|
||||||
b.root = node
|
|
||||||
b.node = node
|
|
||||||
} else {
|
|
||||||
b.node = b.node.chain(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type QuotePathSelector int
|
|
||||||
|
|
||||||
const (
|
|
||||||
SingleQuotePathSelector QuotePathSelector = 1
|
|
||||||
DoubleQuotePathSelector QuotePathSelector = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
type Path struct {
|
|
||||||
node PathNode
|
|
||||||
RootSelectorOnly bool
|
|
||||||
SingleQuotePathSelector bool
|
|
||||||
DoubleQuotePathSelector bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Path) Field(sel string) (PathNode, bool, error) {
|
|
||||||
if p.node == nil {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
return p.node.Field(sel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Path) Get(src, dst reflect.Value) error {
|
|
||||||
if p.node == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return p.node.Get(src, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Path) String() string {
|
|
||||||
if p.node == nil {
|
|
||||||
return "$"
|
|
||||||
}
|
|
||||||
return p.node.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathNode interface {
|
|
||||||
fmt.Stringer
|
|
||||||
Index(idx int) (PathNode, bool, error)
|
|
||||||
Field(fieldName string) (PathNode, bool, error)
|
|
||||||
Get(src, dst reflect.Value) error
|
|
||||||
chain(PathNode) PathNode
|
|
||||||
target() bool
|
|
||||||
single() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type BasePathNode struct {
|
|
||||||
child PathNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasePathNode) chain(node PathNode) PathNode {
|
|
||||||
n.child = node
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasePathNode) target() bool {
|
|
||||||
return n.child == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasePathNode) single() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathSelectorNode struct {
|
|
||||||
*BasePathNode
|
|
||||||
selector string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPathSelectorNode(selector string) *PathSelectorNode {
|
|
||||||
return &PathSelectorNode{
|
|
||||||
BasePathNode: &BasePathNode{},
|
|
||||||
selector: selector,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathSelectorNode) Index(idx int) (PathNode, bool, error) {
|
|
||||||
return nil, false, &errors.PathError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathSelectorNode) Field(fieldName string) (PathNode, bool, error) {
|
|
||||||
if n.selector == fieldName {
|
|
||||||
return n.child, true, nil
|
|
||||||
}
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathSelectorNode) Get(src, dst reflect.Value) error {
|
|
||||||
switch src.Type().Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
iter := src.MapRange()
|
|
||||||
for iter.Next() {
|
|
||||||
key, ok := iter.Key().Interface().(string)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("invalid map key type %T", src.Type().Key())
|
|
||||||
}
|
|
||||||
child, found, err := n.Field(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
if child != nil {
|
|
||||||
return child.Get(iter.Value(), dst)
|
|
||||||
}
|
|
||||||
return AssignValue(iter.Value(), dst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Struct:
|
|
||||||
typ := src.Type()
|
|
||||||
for i := 0; i < typ.Len(); i++ {
|
|
||||||
tag := runtime.StructTagFromField(typ.Field(i))
|
|
||||||
child, found, err := n.Field(tag.Key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
if child != nil {
|
|
||||||
return child.Get(src.Field(i), dst)
|
|
||||||
}
|
|
||||||
return AssignValue(src.Field(i), dst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Ptr:
|
|
||||||
return n.Get(src.Elem(), dst)
|
|
||||||
case reflect.Interface:
|
|
||||||
return n.Get(reflect.ValueOf(src.Interface()), dst)
|
|
||||||
case reflect.Float64, reflect.String, reflect.Bool:
|
|
||||||
return AssignValue(src, dst)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathSelectorNode) String() string {
|
|
||||||
s := fmt.Sprintf(".%s", n.selector)
|
|
||||||
if n.child != nil {
|
|
||||||
s += n.child.String()
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathIndexNode struct {
|
|
||||||
*BasePathNode
|
|
||||||
selector int
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPathIndexNode(selector int) *PathIndexNode {
|
|
||||||
return &PathIndexNode{
|
|
||||||
BasePathNode: &BasePathNode{},
|
|
||||||
selector: selector,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexNode) Index(idx int) (PathNode, bool, error) {
|
|
||||||
if n.selector == idx {
|
|
||||||
return n.child, true, nil
|
|
||||||
}
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexNode) Field(fieldName string) (PathNode, bool, error) {
|
|
||||||
return nil, false, &errors.PathError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexNode) Get(src, dst reflect.Value) error {
|
|
||||||
switch src.Type().Kind() {
|
|
||||||
case reflect.Array, reflect.Slice:
|
|
||||||
if src.Len() > n.selector {
|
|
||||||
if n.child != nil {
|
|
||||||
return n.child.Get(src.Index(n.selector), dst)
|
|
||||||
}
|
|
||||||
return AssignValue(src.Index(n.selector), dst)
|
|
||||||
}
|
|
||||||
case reflect.Ptr:
|
|
||||||
return n.Get(src.Elem(), dst)
|
|
||||||
case reflect.Interface:
|
|
||||||
return n.Get(reflect.ValueOf(src.Interface()), dst)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to get [%d] value from %s", n.selector, src.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexNode) String() string {
|
|
||||||
s := fmt.Sprintf("[%d]", n.selector)
|
|
||||||
if n.child != nil {
|
|
||||||
s += n.child.String()
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathIndexAllNode struct {
|
|
||||||
*BasePathNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPathIndexAllNode() *PathIndexAllNode {
|
|
||||||
return &PathIndexAllNode{
|
|
||||||
BasePathNode: &BasePathNode{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexAllNode) Index(idx int) (PathNode, bool, error) {
|
|
||||||
return n.child, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexAllNode) Field(fieldName string) (PathNode, bool, error) {
|
|
||||||
return nil, false, &errors.PathError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexAllNode) Get(src, dst reflect.Value) error {
|
|
||||||
switch src.Type().Kind() {
|
|
||||||
case reflect.Array, reflect.Slice:
|
|
||||||
var arr []interface{}
|
|
||||||
for i := 0; i < src.Len(); i++ {
|
|
||||||
var v interface{}
|
|
||||||
rv := reflect.ValueOf(&v)
|
|
||||||
if n.child != nil {
|
|
||||||
if err := n.child.Get(src.Index(i), rv); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := AssignValue(src.Index(i), rv); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arr = append(arr, v)
|
|
||||||
}
|
|
||||||
if err := AssignValue(reflect.ValueOf(arr), dst); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
case reflect.Ptr:
|
|
||||||
return n.Get(src.Elem(), dst)
|
|
||||||
case reflect.Interface:
|
|
||||||
return n.Get(reflect.ValueOf(src.Interface()), dst)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to get all value from %s", src.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathIndexAllNode) String() string {
|
|
||||||
s := "[*]"
|
|
||||||
if n.child != nil {
|
|
||||||
s += n.child.String()
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathRecursiveNode struct {
|
|
||||||
*BasePathNode
|
|
||||||
selector string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPathRecursiveNode(selector string) *PathRecursiveNode {
|
|
||||||
node := newPathSelectorNode(selector)
|
|
||||||
return &PathRecursiveNode{
|
|
||||||
BasePathNode: &BasePathNode{
|
|
||||||
child: node,
|
|
||||||
},
|
|
||||||
selector: selector,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathRecursiveNode) Field(fieldName string) (PathNode, bool, error) {
|
|
||||||
if n.selector == fieldName {
|
|
||||||
return n.child, true, nil
|
|
||||||
}
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathRecursiveNode) Index(_ int) (PathNode, bool, error) {
|
|
||||||
return n, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func valueToSliceValue(v interface{}) []interface{} {
|
|
||||||
rv := reflect.ValueOf(v)
|
|
||||||
ret := []interface{}{}
|
|
||||||
if rv.Type().Kind() == reflect.Slice || rv.Type().Kind() == reflect.Array {
|
|
||||||
for i := 0; i < rv.Len(); i++ {
|
|
||||||
ret = append(ret, rv.Index(i).Interface())
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
return []interface{}{v}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathRecursiveNode) Get(src, dst reflect.Value) error {
|
|
||||||
if n.child == nil {
|
|
||||||
return fmt.Errorf("failed to get by recursive path ..%s", n.selector)
|
|
||||||
}
|
|
||||||
var arr []interface{}
|
|
||||||
switch src.Type().Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
iter := src.MapRange()
|
|
||||||
for iter.Next() {
|
|
||||||
key, ok := iter.Key().Interface().(string)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("invalid map key type %T", src.Type().Key())
|
|
||||||
}
|
|
||||||
child, found, err := n.Field(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
var v interface{}
|
|
||||||
rv := reflect.ValueOf(&v)
|
|
||||||
_ = child.Get(iter.Value(), rv)
|
|
||||||
arr = append(arr, valueToSliceValue(v)...)
|
|
||||||
} else {
|
|
||||||
var v interface{}
|
|
||||||
rv := reflect.ValueOf(&v)
|
|
||||||
_ = n.Get(iter.Value(), rv)
|
|
||||||
if v != nil {
|
|
||||||
arr = append(arr, valueToSliceValue(v)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ = AssignValue(reflect.ValueOf(arr), dst)
|
|
||||||
return nil
|
|
||||||
case reflect.Struct:
|
|
||||||
typ := src.Type()
|
|
||||||
for i := 0; i < typ.Len(); i++ {
|
|
||||||
tag := runtime.StructTagFromField(typ.Field(i))
|
|
||||||
child, found, err := n.Field(tag.Key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
var v interface{}
|
|
||||||
rv := reflect.ValueOf(&v)
|
|
||||||
_ = child.Get(src.Field(i), rv)
|
|
||||||
arr = append(arr, valueToSliceValue(v)...)
|
|
||||||
} else {
|
|
||||||
var v interface{}
|
|
||||||
rv := reflect.ValueOf(&v)
|
|
||||||
_ = n.Get(src.Field(i), rv)
|
|
||||||
if v != nil {
|
|
||||||
arr = append(arr, valueToSliceValue(v)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ = AssignValue(reflect.ValueOf(arr), dst)
|
|
||||||
return nil
|
|
||||||
case reflect.Array, reflect.Slice:
|
|
||||||
for i := 0; i < src.Len(); i++ {
|
|
||||||
var v interface{}
|
|
||||||
rv := reflect.ValueOf(&v)
|
|
||||||
_ = n.Get(src.Index(i), rv)
|
|
||||||
if v != nil {
|
|
||||||
arr = append(arr, valueToSliceValue(v)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ = AssignValue(reflect.ValueOf(arr), dst)
|
|
||||||
return nil
|
|
||||||
case reflect.Ptr:
|
|
||||||
return n.Get(src.Elem(), dst)
|
|
||||||
case reflect.Interface:
|
|
||||||
return n.Get(reflect.ValueOf(src.Interface()), dst)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *PathRecursiveNode) String() string {
|
|
||||||
s := fmt.Sprintf("..%s", n.selector)
|
|
||||||
if n.child != nil {
|
|
||||||
s += n.child.String()
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
10
vendor/github.com/goccy/go-json/internal/decoder/ptr.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/decoder/ptr.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package decoder
|
package decoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/runtime"
|
"github.com/goccy/go-json/internal/runtime"
|
||||||
@ -35,10 +34,6 @@ func (d *ptrDecoder) contentDecoder() Decoder {
|
|||||||
//go:linkname unsafe_New reflect.unsafe_New
|
//go:linkname unsafe_New reflect.unsafe_New
|
||||||
func unsafe_New(*runtime.Type) unsafe.Pointer
|
func unsafe_New(*runtime.Type) unsafe.Pointer
|
||||||
|
|
||||||
func UnsafeNew(t *runtime.Type) unsafe.Pointer {
|
|
||||||
return unsafe_New(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
||||||
if s.skipWhiteSpace() == nul {
|
if s.skipWhiteSpace() == nul {
|
||||||
s.read()
|
s.read()
|
||||||
@ -85,13 +80,8 @@ func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P
|
|||||||
}
|
}
|
||||||
c, err := d.dec.Decode(ctx, cursor, depth, newptr)
|
c, err := d.dec.Decode(ctx, cursor, depth, newptr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
*(*unsafe.Pointer)(p) = nil
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
cursor = c
|
cursor = c
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ptrDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: ptr decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
79
vendor/github.com/goccy/go-json/internal/decoder/slice.go
generated
vendored
79
vendor/github.com/goccy/go-json/internal/decoder/slice.go
generated
vendored
@ -299,82 +299,3 @@ func (d *sliceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sliceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
buf := ctx.Buf
|
|
||||||
depth++
|
|
||||||
if depth > maxDecodeNestingDepth {
|
|
||||||
return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := [][]byte{}
|
|
||||||
for {
|
|
||||||
switch buf[cursor] {
|
|
||||||
case ' ', '\n', '\t', '\r':
|
|
||||||
cursor++
|
|
||||||
continue
|
|
||||||
case 'n':
|
|
||||||
if err := validateNull(buf, cursor); err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor += 4
|
|
||||||
return [][]byte{nullbytes}, cursor, nil
|
|
||||||
case '[':
|
|
||||||
cursor++
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
|
||||||
if buf[cursor] == ']' {
|
|
||||||
cursor++
|
|
||||||
return ret, cursor, nil
|
|
||||||
}
|
|
||||||
idx := 0
|
|
||||||
for {
|
|
||||||
child, found, err := ctx.Option.Path.node.Index(idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
if child != nil {
|
|
||||||
oldPath := ctx.Option.Path.node
|
|
||||||
ctx.Option.Path.node = child
|
|
||||||
paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
ctx.Option.Path.node = oldPath
|
|
||||||
ret = append(ret, paths...)
|
|
||||||
cursor = c
|
|
||||||
} else {
|
|
||||||
start := cursor
|
|
||||||
end, err := skipValue(buf, cursor, depth)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
ret = append(ret, buf[start:end])
|
|
||||||
cursor = end
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c, err := skipValue(buf, cursor, depth)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
cursor = c
|
|
||||||
}
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
|
||||||
switch buf[cursor] {
|
|
||||||
case ']':
|
|
||||||
cursor++
|
|
||||||
return ret, cursor, nil
|
|
||||||
case ',':
|
|
||||||
idx++
|
|
||||||
default:
|
|
||||||
return nil, 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor)
|
|
||||||
}
|
|
||||||
cursor++
|
|
||||||
}
|
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
||||||
return nil, 0, d.errNumber(cursor)
|
|
||||||
default:
|
|
||||||
return nil, 0, errors.ErrUnexpectedEndOfJSON("slice", cursor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
15
vendor/github.com/goccy/go-json/internal/decoder/stream.go
generated
vendored
15
vendor/github.com/goccy/go-json/internal/decoder/stream.go
generated
vendored
@ -103,7 +103,7 @@ func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) {
|
|||||||
|
|
||||||
func (s *Stream) Reset() {
|
func (s *Stream) Reset() {
|
||||||
s.reset()
|
s.reset()
|
||||||
s.bufSize = int64(len(s.buf))
|
s.bufSize = initBufSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) More() bool {
|
func (s *Stream) More() bool {
|
||||||
@ -138,11 +138,8 @@ func (s *Stream) Token() (interface{}, error) {
|
|||||||
s.cursor++
|
s.cursor++
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
bytes := floatBytes(s)
|
bytes := floatBytes(s)
|
||||||
str := *(*string)(unsafe.Pointer(&bytes))
|
s := *(*string)(unsafe.Pointer(&bytes))
|
||||||
if s.UseNumber {
|
f64, err := strconv.ParseFloat(s, 64)
|
||||||
return json.Number(str), nil
|
|
||||||
}
|
|
||||||
f64, err := strconv.ParseFloat(str, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -280,7 +277,7 @@ func (s *Stream) skipObject(depth int64) error {
|
|||||||
if char(p, cursor) == nul {
|
if char(p, cursor) == nul {
|
||||||
s.cursor = cursor
|
s.cursor = cursor
|
||||||
if s.read() {
|
if s.read() {
|
||||||
_, cursor, p = s.stat()
|
_, cursor, p = s.statForRetry()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
|
return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
|
||||||
@ -343,7 +340,7 @@ func (s *Stream) skipArray(depth int64) error {
|
|||||||
if char(p, cursor) == nul {
|
if char(p, cursor) == nul {
|
||||||
s.cursor = cursor
|
s.cursor = cursor
|
||||||
if s.read() {
|
if s.read() {
|
||||||
_, cursor, p = s.stat()
|
_, cursor, p = s.statForRetry()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
|
return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
|
||||||
@ -401,7 +398,7 @@ func (s *Stream) skipValue(depth int64) error {
|
|||||||
if char(p, cursor) == nul {
|
if char(p, cursor) == nul {
|
||||||
s.cursor = cursor
|
s.cursor = cursor
|
||||||
if s.read() {
|
if s.read() {
|
||||||
_, cursor, p = s.stat()
|
_, cursor, p = s.statForRetry()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset())
|
return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset())
|
||||||
|
117
vendor/github.com/goccy/go-json/internal/decoder/string.go
generated
vendored
117
vendor/github.com/goccy/go-json/internal/decoder/string.go
generated
vendored
@ -2,7 +2,6 @@ package decoder
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
@ -60,17 +59,6 @@ func (d *stringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
|||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *stringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
bytes, c, err := d.decodeByte(ctx.Buf, cursor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
if bytes == nil {
|
|
||||||
return [][]byte{nullbytes}, c, nil
|
|
||||||
}
|
|
||||||
return [][]byte{bytes}, c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
hexToInt = [256]int{
|
hexToInt = [256]int{
|
||||||
'0': 0,
|
'0': 0,
|
||||||
@ -106,30 +94,24 @@ func unicodeToRune(code []byte) rune {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func readAtLeast(s *Stream, n int64, p *unsafe.Pointer) bool {
|
|
||||||
for s.cursor+n >= s.length {
|
|
||||||
if !s.read() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*p = s.bufptr()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeUnicodeRune(s *Stream, p unsafe.Pointer) (rune, int64, unsafe.Pointer, error) {
|
func decodeUnicodeRune(s *Stream, p unsafe.Pointer) (rune, int64, unsafe.Pointer, error) {
|
||||||
const defaultOffset = 5
|
const defaultOffset = 5
|
||||||
const surrogateOffset = 11
|
const surrogateOffset = 11
|
||||||
|
|
||||||
if !readAtLeast(s, defaultOffset, &p) {
|
if s.cursor+defaultOffset >= s.length {
|
||||||
return rune(0), 0, nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
|
if !s.read() {
|
||||||
|
return rune(0), 0, nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
|
||||||
|
}
|
||||||
|
p = s.bufptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
r := unicodeToRune(s.buf[s.cursor+1 : s.cursor+defaultOffset])
|
r := unicodeToRune(s.buf[s.cursor+1 : s.cursor+defaultOffset])
|
||||||
if utf16.IsSurrogate(r) {
|
if utf16.IsSurrogate(r) {
|
||||||
if !readAtLeast(s, surrogateOffset, &p) {
|
if s.cursor+surrogateOffset >= s.length {
|
||||||
return unicode.ReplacementChar, defaultOffset, p, nil
|
s.read()
|
||||||
|
p = s.bufptr()
|
||||||
}
|
}
|
||||||
if s.buf[s.cursor+defaultOffset] != '\\' || s.buf[s.cursor+defaultOffset+1] != 'u' {
|
if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor+defaultOffset] != '\\' || s.buf[s.cursor+defaultOffset+1] != 'u' {
|
||||||
return unicode.ReplacementChar, defaultOffset, p, nil
|
return unicode.ReplacementChar, defaultOffset, p, nil
|
||||||
}
|
}
|
||||||
r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset])
|
r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset])
|
||||||
@ -182,7 +164,6 @@ RETRY:
|
|||||||
if !s.read() {
|
if !s.read() {
|
||||||
return nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
|
return nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
|
||||||
}
|
}
|
||||||
p = s.bufptr()
|
|
||||||
goto RETRY
|
goto RETRY
|
||||||
default:
|
default:
|
||||||
return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
|
return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
|
||||||
@ -342,12 +323,6 @@ func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, err
|
|||||||
if cursor+5 >= buflen {
|
if cursor+5 >= buflen {
|
||||||
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
|
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
|
||||||
}
|
}
|
||||||
for i := int64(1); i <= 4; i++ {
|
|
||||||
c := char(b, cursor+i)
|
|
||||||
if !(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')) {
|
|
||||||
return nil, 0, errors.ErrSyntax(fmt.Sprintf("json: invalid character %c in \\u hexadecimal character escape", c), cursor+i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor += 5
|
cursor += 5
|
||||||
default:
|
default:
|
||||||
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
|
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
|
||||||
@ -356,7 +331,7 @@ func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, err
|
|||||||
case '"':
|
case '"':
|
||||||
literal := buf[start:cursor]
|
literal := buf[start:cursor]
|
||||||
if escaped > 0 {
|
if escaped > 0 {
|
||||||
literal = literal[:unescapeString(literal)]
|
literal = literal[:unescapeString(literal, escaped)]
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
return literal, cursor, nil
|
return literal, cursor, nil
|
||||||
@ -388,65 +363,21 @@ var unescapeMap = [256]byte{
|
|||||||
't': '\t',
|
't': '\t',
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsafeAdd(ptr unsafe.Pointer, offset int) unsafe.Pointer {
|
func unescapeString(buf []byte, escaped int) int {
|
||||||
return unsafe.Pointer(uintptr(ptr) + uintptr(offset))
|
cursor := 0
|
||||||
}
|
for i := 0; i < escaped; i++ {
|
||||||
|
cursor += bytes.IndexByte(buf[cursor:], '\\')
|
||||||
func unescapeString(buf []byte) int {
|
c := buf[cursor+1]
|
||||||
p := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
if c == 'u' {
|
||||||
end := unsafeAdd(p, len(buf))
|
code := unicodeToRune(buf[cursor+2 : cursor+6])
|
||||||
src := unsafeAdd(p, bytes.IndexByte(buf, '\\'))
|
unicode := []byte(string(code))
|
||||||
dst := src
|
buf = append(append(buf[:cursor], unicode...), buf[cursor+6:]...)
|
||||||
for src != end {
|
cursor += len(unicode)
|
||||||
c := char(src, 0)
|
|
||||||
if c == '\\' {
|
|
||||||
escapeChar := char(src, 1)
|
|
||||||
if escapeChar != 'u' {
|
|
||||||
*(*byte)(dst) = unescapeMap[escapeChar]
|
|
||||||
src = unsafeAdd(src, 2)
|
|
||||||
dst = unsafeAdd(dst, 1)
|
|
||||||
} else {
|
|
||||||
v1 := hexToInt[char(src, 2)]
|
|
||||||
v2 := hexToInt[char(src, 3)]
|
|
||||||
v3 := hexToInt[char(src, 4)]
|
|
||||||
v4 := hexToInt[char(src, 5)]
|
|
||||||
code := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4)
|
|
||||||
if code >= 0xd800 && code < 0xdc00 && uintptr(unsafeAdd(src, 11)) < uintptr(end) {
|
|
||||||
if char(src, 6) == '\\' && char(src, 7) == 'u' {
|
|
||||||
v1 := hexToInt[char(src, 8)]
|
|
||||||
v2 := hexToInt[char(src, 9)]
|
|
||||||
v3 := hexToInt[char(src, 10)]
|
|
||||||
v4 := hexToInt[char(src, 11)]
|
|
||||||
lo := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4)
|
|
||||||
if lo >= 0xdc00 && lo < 0xe000 {
|
|
||||||
code = (code-0xd800)<<10 | (lo - 0xdc00) + 0x10000
|
|
||||||
src = unsafeAdd(src, 6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var b [utf8.UTFMax]byte
|
|
||||||
n := utf8.EncodeRune(b[:], code)
|
|
||||||
switch n {
|
|
||||||
case 4:
|
|
||||||
*(*byte)(unsafeAdd(dst, 3)) = b[3]
|
|
||||||
fallthrough
|
|
||||||
case 3:
|
|
||||||
*(*byte)(unsafeAdd(dst, 2)) = b[2]
|
|
||||||
fallthrough
|
|
||||||
case 2:
|
|
||||||
*(*byte)(unsafeAdd(dst, 1)) = b[1]
|
|
||||||
fallthrough
|
|
||||||
case 1:
|
|
||||||
*(*byte)(unsafeAdd(dst, 0)) = b[0]
|
|
||||||
}
|
|
||||||
src = unsafeAdd(src, 6)
|
|
||||||
dst = unsafeAdd(dst, n)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
*(*byte)(dst) = c
|
buf[cursor+1] = unescapeMap[c]
|
||||||
src = unsafeAdd(src, 1)
|
buf = append(buf[:cursor], buf[cursor+1:]...)
|
||||||
dst = unsafeAdd(dst, 1)
|
cursor++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return int(uintptr(dst) - uintptr(p))
|
return len(buf)
|
||||||
}
|
}
|
||||||
|
58
vendor/github.com/goccy/go-json/internal/decoder/struct.go
generated
vendored
58
vendor/github.com/goccy/go-json/internal/decoder/struct.go
generated
vendored
@ -51,14 +51,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toASCIILower(s string) string {
|
|
||||||
b := []byte(s)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = largeToSmallTable[b[i]]
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder {
|
func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder {
|
||||||
return &structDecoder{
|
return &structDecoder{
|
||||||
fieldMap: fieldMap,
|
fieldMap: fieldMap,
|
||||||
@ -99,10 +91,6 @@ func (d *structDecoder) tryOptimize() {
|
|||||||
for k, v := range d.fieldMap {
|
for k, v := range d.fieldMap {
|
||||||
key := strings.ToLower(k)
|
key := strings.ToLower(k)
|
||||||
if key != k {
|
if key != k {
|
||||||
if key != toASCIILower(k) {
|
|
||||||
d.isTriedOptimize = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// already exists same key (e.g. Hello and HELLO has same lower case key
|
// already exists same key (e.g. Hello and HELLO has same lower case key
|
||||||
if _, exists := conflicted[key]; exists {
|
if _, exists := conflicted[key]; exists {
|
||||||
d.isTriedOptimize = true
|
d.isTriedOptimize = true
|
||||||
@ -170,53 +158,49 @@ func (d *structDecoder) tryOptimize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decode from '\uXXXX'
|
// decode from '\uXXXX'
|
||||||
func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64, error) {
|
func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64) {
|
||||||
const defaultOffset = 4
|
const defaultOffset = 4
|
||||||
const surrogateOffset = 6
|
const surrogateOffset = 6
|
||||||
|
|
||||||
if cursor+defaultOffset >= int64(len(buf)) {
|
|
||||||
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
r := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
||||||
if utf16.IsSurrogate(r) {
|
if utf16.IsSurrogate(r) {
|
||||||
cursor += defaultOffset
|
cursor += defaultOffset
|
||||||
if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
|
if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
|
||||||
return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1, nil
|
return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1
|
||||||
}
|
}
|
||||||
cursor += 2
|
cursor += 2
|
||||||
r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
||||||
if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
|
if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
|
||||||
return []byte(string(r)), cursor + defaultOffset - 1, nil
|
return []byte(string(r)), cursor + defaultOffset - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []byte(string(r)), cursor + defaultOffset - 1, nil
|
return []byte(string(r)), cursor + defaultOffset - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error) {
|
func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64) {
|
||||||
c := buf[cursor]
|
c := buf[cursor]
|
||||||
cursor++
|
cursor++
|
||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
return []byte{'"'}, cursor, nil
|
return []byte{'"'}, cursor
|
||||||
case '\\':
|
case '\\':
|
||||||
return []byte{'\\'}, cursor, nil
|
return []byte{'\\'}, cursor
|
||||||
case '/':
|
case '/':
|
||||||
return []byte{'/'}, cursor, nil
|
return []byte{'/'}, cursor
|
||||||
case 'b':
|
case 'b':
|
||||||
return []byte{'\b'}, cursor, nil
|
return []byte{'\b'}, cursor
|
||||||
case 'f':
|
case 'f':
|
||||||
return []byte{'\f'}, cursor, nil
|
return []byte{'\f'}, cursor
|
||||||
case 'n':
|
case 'n':
|
||||||
return []byte{'\n'}, cursor, nil
|
return []byte{'\n'}, cursor
|
||||||
case 'r':
|
case 'r':
|
||||||
return []byte{'\r'}, cursor, nil
|
return []byte{'\r'}, cursor
|
||||||
case 't':
|
case 't':
|
||||||
return []byte{'\t'}, cursor, nil
|
return []byte{'\t'}, cursor
|
||||||
case 'u':
|
case 'u':
|
||||||
return decodeKeyCharByUnicodeRune(buf, cursor)
|
return decodeKeyCharByUnicodeRune(buf, cursor)
|
||||||
}
|
}
|
||||||
return nil, cursor, nil
|
return nil, cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
||||||
@ -258,10 +242,7 @@ func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64,
|
|||||||
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
||||||
case '\\':
|
case '\\':
|
||||||
cursor++
|
cursor++
|
||||||
chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
|
chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
|
||||||
for _, c := range chars {
|
for _, c := range chars {
|
||||||
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
||||||
if curBit == 0 {
|
if curBit == 0 {
|
||||||
@ -324,10 +305,7 @@ func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64,
|
|||||||
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
||||||
case '\\':
|
case '\\':
|
||||||
cursor++
|
cursor++
|
||||||
chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
|
chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
|
||||||
for _, c := range chars {
|
for _, c := range chars {
|
||||||
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
||||||
if curBit == 0 {
|
if curBit == 0 {
|
||||||
@ -839,7 +817,3 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
|
|||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *structDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: struct decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/decoder/type.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/decoder/type.go
generated
vendored
@ -10,7 +10,6 @@ import (
|
|||||||
|
|
||||||
type Decoder interface {
|
type Decoder interface {
|
||||||
Decode(*RuntimeContext, int64, int64, unsafe.Pointer) (int64, error)
|
Decode(*RuntimeContext, int64, int64, unsafe.Pointer) (int64, error)
|
||||||
DecodePath(*RuntimeContext, int64, int64) ([][]byte, int64, error)
|
|
||||||
DecodeStream(*Stream, int64, unsafe.Pointer) error
|
DecodeStream(*Stream, int64, unsafe.Pointer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
vendor/github.com/goccy/go-json/internal/decoder/uint.go
generated
vendored
4
vendor/github.com/goccy/go-json/internal/decoder/uint.go
generated
vendored
@ -188,7 +188,3 @@ func (d *uintDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.
|
|||||||
d.op(p, u64)
|
d.op(p, u64)
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *uintDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: uint decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
5
vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go
generated
vendored
5
vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go
generated
vendored
@ -3,7 +3,6 @@ package decoder
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/errors"
|
"github.com/goccy/go-json/internal/errors"
|
||||||
@ -98,7 +97,3 @@ func (d *unmarshalJSONDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,
|
|||||||
}
|
}
|
||||||
return end, nil
|
return end, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *unmarshalJSONDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: unmarshal json decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
7
vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go
generated
vendored
7
vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go
generated
vendored
@ -3,7 +3,6 @@ package decoder
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding"
|
"encoding"
|
||||||
"fmt"
|
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
@ -143,11 +142,7 @@ func (d *unmarshalTextDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,
|
|||||||
return end, nil
|
return end, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *unmarshalTextDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
func unquoteBytes(s []byte) (t []byte, ok bool) {
|
||||||
return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
|
||||||
func unquoteBytes(s []byte) (t []byte, ok bool) { //nolint: nonamedreturns
|
|
||||||
length := len(s)
|
length := len(s)
|
||||||
if length < 2 || s[0] != '"' || s[length-1] != '"' {
|
if length < 2 || s[0] != '"' || s[length-1] != '"' {
|
||||||
return
|
return
|
||||||
|
5
vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go
generated
vendored
5
vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package decoder
|
package decoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -67,7 +66,3 @@ func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,
|
|||||||
ctx.Buf = oldBuf
|
ctx.Buf = oldBuf
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *wrappedStringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
|
|
||||||
return nil, 0, fmt.Errorf("json: wrapped string decoder does not support decode path")
|
|
||||||
}
|
|
||||||
|
34
vendor/github.com/goccy/go-json/internal/encoder/code.go
generated
vendored
34
vendor/github.com/goccy/go-json/internal/encoder/code.go
generated
vendored
@ -2,7 +2,6 @@ package encoder
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/runtime"
|
"github.com/goccy/go-json/internal/runtime"
|
||||||
@ -384,7 +383,7 @@ func (c *StructCode) Kind() CodeKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode {
|
func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode {
|
||||||
if isEmbeddedStruct(field) {
|
if field.isAnonymous {
|
||||||
return c.lastAnonymousFieldCode(firstField)
|
return c.lastAnonymousFieldCode(firstField)
|
||||||
}
|
}
|
||||||
lastField := firstField
|
lastField := firstField
|
||||||
@ -397,10 +396,7 @@ func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *
|
|||||||
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
||||||
// firstField is special StructHead operation for anonymous structure.
|
// firstField is special StructHead operation for anonymous structure.
|
||||||
// So, StructHead's next operation is truly struct head operation.
|
// So, StructHead's next operation is truly struct head operation.
|
||||||
for firstField.Op == OpStructHead || firstField.Op == OpStructField {
|
lastField := firstField.Next
|
||||||
firstField = firstField.Next
|
|
||||||
}
|
|
||||||
lastField := firstField
|
|
||||||
for lastField.NextField != nil {
|
for lastField.NextField != nil {
|
||||||
lastField = lastField.NextField
|
lastField = lastField.NextField
|
||||||
}
|
}
|
||||||
@ -440,6 +436,11 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
|||||||
}
|
}
|
||||||
if isEndField {
|
if isEndField {
|
||||||
endField := fieldCodes.Last()
|
endField := fieldCodes.Last()
|
||||||
|
if field.isAnonymous {
|
||||||
|
firstField.End = endField
|
||||||
|
lastField := c.lastAnonymousFieldCode(firstField)
|
||||||
|
lastField.NextField = endField
|
||||||
|
}
|
||||||
if len(codes) > 0 {
|
if len(codes) > 0 {
|
||||||
codes.First().End = endField
|
codes.First().End = endField
|
||||||
} else {
|
} else {
|
||||||
@ -696,15 +697,7 @@ func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) O
|
|||||||
Indent: ctx.indent,
|
Indent: ctx.indent,
|
||||||
}
|
}
|
||||||
codes.Last().Next = end
|
codes.Last().Next = end
|
||||||
code := codes.First()
|
codes.First().NextField = end
|
||||||
for code.Op == OpStructField || code.Op == OpStructHead {
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
for code.NextField != nil {
|
|
||||||
code = code.NextField
|
|
||||||
}
|
|
||||||
code.NextField = end
|
|
||||||
|
|
||||||
codes = codes.Add(end)
|
codes = codes.Add(end)
|
||||||
ctx.incOpcodeIndex()
|
ctx.incOpcodeIndex()
|
||||||
return codes
|
return codes
|
||||||
@ -1010,14 +1003,3 @@ func convertPtrOp(code *Opcode) OpType {
|
|||||||
}
|
}
|
||||||
return code.Op
|
return code.Op
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEmbeddedStruct(field *StructFieldCode) bool {
|
|
||||||
if !field.isAnonymous {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
t := field.typ
|
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
return t.Kind() == reflect.Struct
|
|
||||||
}
|
|
||||||
|
2
vendor/github.com/goccy/go-json/internal/encoder/compact.go
generated
vendored
2
vendor/github.com/goccy/go-json/internal/encoder/compact.go
generated
vendored
@ -213,8 +213,8 @@ func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, e
|
|||||||
dst = append(dst, src[start:cursor]...)
|
dst = append(dst, src[start:cursor]...)
|
||||||
dst = append(dst, `\u202`...)
|
dst = append(dst, `\u202`...)
|
||||||
dst = append(dst, hex[src[cursor+2]&0xF])
|
dst = append(dst, hex[src[cursor+2]&0xF])
|
||||||
start = cursor + 3
|
|
||||||
cursor += 2
|
cursor += 2
|
||||||
|
start = cursor + 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch c {
|
switch c {
|
||||||
|
48
vendor/github.com/goccy/go-json/internal/encoder/compiler.go
generated
vendored
48
vendor/github.com/goccy/go-json/internal/encoder/compiler.go
generated
vendored
@ -31,7 +31,7 @@ func init() {
|
|||||||
if typeAddr == nil {
|
if typeAddr == nil {
|
||||||
typeAddr = &runtime.TypeAddr{}
|
typeAddr = &runtime.TypeAddr{}
|
||||||
}
|
}
|
||||||
cachedOpcodeSets = make([]*OpcodeSet, typeAddr.AddrRange>>typeAddr.AddrShift+1)
|
cachedOpcodeSets = make([]*OpcodeSet, typeAddr.AddrRange>>typeAddr.AddrShift)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadOpcodeMap() map[uintptr]*OpcodeSet {
|
func loadOpcodeMap() map[uintptr]*OpcodeSet {
|
||||||
@ -480,17 +480,14 @@ func (c *Compiler) mapCode(typ *runtime.Type) (*MapCode, error) {
|
|||||||
|
|
||||||
func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) {
|
func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) {
|
||||||
switch {
|
switch {
|
||||||
case c.implementsMarshalJSONType(typ) || c.implementsMarshalJSONType(runtime.PtrTo(typ)):
|
case c.isPtrMarshalJSONType(typ):
|
||||||
return c.marshalJSONCode(typ)
|
return c.marshalJSONCode(typ)
|
||||||
case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType):
|
case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType):
|
||||||
return c.marshalTextCode(typ)
|
return c.marshalTextCode(typ)
|
||||||
case typ.Kind() == reflect.Map:
|
case typ.Kind() == reflect.Map:
|
||||||
return c.ptrCode(runtime.PtrTo(typ))
|
return c.ptrCode(runtime.PtrTo(typ))
|
||||||
default:
|
default:
|
||||||
// isPtr was originally used to indicate whether the type of top level is pointer.
|
code, err := c.typeToCodeWithPtr(typ, false)
|
||||||
// However, since the slice/array element is a specification that can get the pointer address, explicitly set isPtr to true.
|
|
||||||
// See here for related issues: https://github.com/goccy/go-json/issues/370
|
|
||||||
code, err := c.typeToCodeWithPtr(typ, true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -506,6 +503,8 @@ func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) {
|
|||||||
|
|
||||||
func (c *Compiler) mapKeyCode(typ *runtime.Type) (Code, error) {
|
func (c *Compiler) mapKeyCode(typ *runtime.Type) (Code, error) {
|
||||||
switch {
|
switch {
|
||||||
|
case c.implementsMarshalJSON(typ):
|
||||||
|
return c.marshalJSONCode(typ)
|
||||||
case c.implementsMarshalText(typ):
|
case c.implementsMarshalText(typ):
|
||||||
return c.marshalTextCode(typ)
|
return c.marshalTextCode(typ)
|
||||||
}
|
}
|
||||||
@ -617,13 +616,6 @@ func (c *Compiler) structCode(typ *runtime.Type, isPtr bool) (*StructCode, error
|
|||||||
return code, nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toElemType(t *runtime.Type) *runtime.Type {
|
|
||||||
for t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) {
|
func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) {
|
||||||
field := tag.Field
|
field := tag.Field
|
||||||
fieldType := runtime.Type2RType(field.Type)
|
fieldType := runtime.Type2RType(field.Type)
|
||||||
@ -633,7 +625,7 @@ func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTa
|
|||||||
key: tag.Key,
|
key: tag.Key,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
offset: field.Offset,
|
offset: field.Offset,
|
||||||
isAnonymous: field.Anonymous && !tag.IsTaggedKey && toElemType(fieldType).Kind() == reflect.Struct,
|
isAnonymous: field.Anonymous && !tag.IsTaggedKey,
|
||||||
isTaggedKey: tag.IsTaggedKey,
|
isTaggedKey: tag.IsTaggedKey,
|
||||||
isNilableType: c.isNilableType(fieldType),
|
isNilableType: c.isNilableType(fieldType),
|
||||||
isNilCheck: true,
|
isNilCheck: true,
|
||||||
@ -861,9 +853,6 @@ func (c *Compiler) implementsMarshalText(typ *runtime.Type) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) isNilableType(typ *runtime.Type) bool {
|
func (c *Compiler) isNilableType(typ *runtime.Type) bool {
|
||||||
if !runtime.IfaceIndir(typ) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return true
|
return true
|
||||||
@ -896,40 +885,29 @@ func (c *Compiler) codeToOpcode(ctx *compileContext, typ *runtime.Type, code Cod
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) linkRecursiveCode(ctx *compileContext) {
|
func (c *Compiler) linkRecursiveCode(ctx *compileContext) {
|
||||||
recursiveCodes := map[uintptr]*CompiledCode{}
|
|
||||||
for _, recursive := range *ctx.recursiveCodes {
|
for _, recursive := range *ctx.recursiveCodes {
|
||||||
typeptr := uintptr(unsafe.Pointer(recursive.Type))
|
typeptr := uintptr(unsafe.Pointer(recursive.Type))
|
||||||
codes := ctx.structTypeToCodes[typeptr]
|
codes := ctx.structTypeToCodes[typeptr]
|
||||||
if recursiveCode, ok := recursiveCodes[typeptr]; ok {
|
compiled := recursive.Jmp
|
||||||
*recursive.Jmp = *recursiveCode
|
compiled.Code = copyOpcode(codes.First())
|
||||||
continue
|
code := compiled.Code
|
||||||
}
|
code.End.Next = newEndOp(&compileContext{}, recursive.Type)
|
||||||
|
|
||||||
code := copyOpcode(codes.First())
|
|
||||||
code.Op = code.Op.PtrHeadToHead()
|
code.Op = code.Op.PtrHeadToHead()
|
||||||
lastCode := newEndOp(&compileContext{}, recursive.Type)
|
|
||||||
lastCode.Op = OpRecursiveEnd
|
|
||||||
|
|
||||||
// OpRecursiveEnd must set before call TotalLength
|
beforeLastCode := code.End
|
||||||
code.End.Next = lastCode
|
lastCode := beforeLastCode.Next
|
||||||
|
|
||||||
totalLength := code.TotalLength()
|
totalLength := code.TotalLength()
|
||||||
|
|
||||||
// Idx, ElemIdx, Length must set after call TotalLength
|
|
||||||
lastCode.Idx = uint32((totalLength + 1) * uintptrSize)
|
lastCode.Idx = uint32((totalLength + 1) * uintptrSize)
|
||||||
lastCode.ElemIdx = lastCode.Idx + uintptrSize
|
lastCode.ElemIdx = lastCode.Idx + uintptrSize
|
||||||
lastCode.Length = lastCode.Idx + 2*uintptrSize
|
lastCode.Length = lastCode.Idx + 2*uintptrSize
|
||||||
|
code.End.Next.Op = OpRecursiveEnd
|
||||||
|
|
||||||
// extend length to alloc slot for elemIdx + length
|
// extend length to alloc slot for elemIdx + length
|
||||||
curTotalLength := uintptr(recursive.TotalLength()) + 3
|
curTotalLength := uintptr(recursive.TotalLength()) + 3
|
||||||
nextTotalLength := uintptr(totalLength) + 3
|
nextTotalLength := uintptr(totalLength) + 3
|
||||||
|
|
||||||
compiled := recursive.Jmp
|
|
||||||
compiled.Code = code
|
|
||||||
compiled.CurLen = curTotalLength
|
compiled.CurLen = curTotalLength
|
||||||
compiled.NextLen = nextTotalLength
|
compiled.NextLen = nextTotalLength
|
||||||
compiled.Linked = true
|
compiled.Linked = true
|
||||||
|
|
||||||
recursiveCodes[typeptr] = compiled
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go
generated
vendored
8
vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go
generated
vendored
@ -4,12 +4,8 @@
|
|||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) {
|
func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) {
|
||||||
if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr {
|
if typeptr > typeAddr.MaxTypeAddr {
|
||||||
codeSet, err := compileToGetCodeSetSlowPath(typeptr)
|
return compileToGetCodeSetSlowPath(typeptr)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return getFilteredCodeSetIfNeeded(ctx, codeSet)
|
|
||||||
}
|
}
|
||||||
index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
|
index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
|
||||||
if codeSet := cachedOpcodeSets[index]; codeSet != nil {
|
if codeSet := cachedOpcodeSets[index]; codeSet != nil {
|
||||||
|
8
vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go
generated
vendored
8
vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go
generated
vendored
@ -10,12 +10,8 @@ import (
|
|||||||
var setsMu sync.RWMutex
|
var setsMu sync.RWMutex
|
||||||
|
|
||||||
func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) {
|
func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) {
|
||||||
if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr {
|
if typeptr > typeAddr.MaxTypeAddr {
|
||||||
codeSet, err := compileToGetCodeSetSlowPath(typeptr)
|
return compileToGetCodeSetSlowPath(typeptr)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return getFilteredCodeSetIfNeeded(ctx, codeSet)
|
|
||||||
}
|
}
|
||||||
index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
|
index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
|
||||||
setsMu.RLock()
|
setsMu.RLock()
|
||||||
|
24
vendor/github.com/goccy/go-json/internal/encoder/int.go
generated
vendored
24
vendor/github.com/goccy/go-json/internal/encoder/int.go
generated
vendored
@ -1,27 +1,3 @@
|
|||||||
// This files's processing codes are inspired by https://github.com/segmentio/encoding.
|
|
||||||
// The license notation is as follows.
|
|
||||||
//
|
|
||||||
// # MIT License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2019 Segment.io, Inc.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
85
vendor/github.com/goccy/go-json/internal/encoder/opcode.go
generated
vendored
85
vendor/github.com/goccy/go-json/internal/encoder/opcode.go
generated
vendored
@ -1,9 +1,7 @@
|
|||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -365,7 +363,7 @@ func copyOpcode(code *Opcode) *Opcode {
|
|||||||
|
|
||||||
func setTotalLengthToInterfaceOp(code *Opcode) {
|
func setTotalLengthToInterfaceOp(code *Opcode) {
|
||||||
for c := code; !c.IsEnd(); {
|
for c := code; !c.IsEnd(); {
|
||||||
if c.Op == OpInterface || c.Op == OpInterfacePtr {
|
if c.Op == OpInterface {
|
||||||
c.Length = uint32(code.TotalLength())
|
c.Length = uint32(code.TotalLength())
|
||||||
}
|
}
|
||||||
c = c.IterNext()
|
c = c.IterNext()
|
||||||
@ -557,87 +555,6 @@ func (c *Opcode) Dump() string {
|
|||||||
return strings.Join(codes, "\n")
|
return strings.Join(codes, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Opcode) DumpDOT() string {
|
|
||||||
type edge struct {
|
|
||||||
from, to *Opcode
|
|
||||||
label string
|
|
||||||
weight int
|
|
||||||
}
|
|
||||||
var edges []edge
|
|
||||||
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(b, "digraph \"%p\" {\n", c.Type)
|
|
||||||
fmt.Fprintln(b, "mclimit=1.5;\nrankdir=TD;\nordering=out;\nnode[shape=box];")
|
|
||||||
for code := c; !code.IsEnd(); {
|
|
||||||
label := code.Op.String()
|
|
||||||
fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, label)
|
|
||||||
if p := code.Next; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p,
|
|
||||||
label: "Next",
|
|
||||||
weight: 10,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if p := code.NextField; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p,
|
|
||||||
label: "NextField",
|
|
||||||
weight: 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if p := code.End; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p,
|
|
||||||
label: "End",
|
|
||||||
weight: 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if p := code.Jmp; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p.Code,
|
|
||||||
label: "Jmp",
|
|
||||||
weight: 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
switch code.Op.CodeType() {
|
|
||||||
case CodeSliceHead:
|
|
||||||
code = code.Next
|
|
||||||
case CodeMapHead:
|
|
||||||
code = code.Next
|
|
||||||
case CodeArrayElem, CodeSliceElem:
|
|
||||||
code = code.End
|
|
||||||
case CodeMapKey:
|
|
||||||
code = code.End
|
|
||||||
case CodeMapValue:
|
|
||||||
code = code.Next
|
|
||||||
case CodeMapEnd:
|
|
||||||
code = code.Next
|
|
||||||
case CodeStructField:
|
|
||||||
code = code.Next
|
|
||||||
case CodeStructEnd:
|
|
||||||
code = code.Next
|
|
||||||
default:
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
if code.IsEnd() {
|
|
||||||
fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, code.Op.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Slice(edges, func(i, j int) bool {
|
|
||||||
return edges[i].to.DisplayIdx < edges[j].to.DisplayIdx
|
|
||||||
})
|
|
||||||
for _, e := range edges {
|
|
||||||
fmt.Fprintf(b, "\"%p\" -> \"%p\" [label=%q][weight=%d];\n", e.from, e.to, e.label, e.weight)
|
|
||||||
}
|
|
||||||
fmt.Fprint(b, "}")
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
|
func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
|
||||||
idx := opcodeOffset(ctx.ptrIndex)
|
idx := opcodeOffset(ctx.ptrIndex)
|
||||||
ctx.incPtrIndex()
|
ctx.incPtrIndex()
|
||||||
|
7
vendor/github.com/goccy/go-json/internal/encoder/option.go
generated
vendored
7
vendor/github.com/goccy/go-json/internal/encoder/option.go
generated
vendored
@ -1,9 +1,6 @@
|
|||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import "context"
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OptionFlag uint8
|
type OptionFlag uint8
|
||||||
|
|
||||||
@ -22,8 +19,6 @@ type Option struct {
|
|||||||
Flag OptionFlag
|
Flag OptionFlag
|
||||||
ColorScheme *ColorScheme
|
ColorScheme *ColorScheme
|
||||||
Context context.Context
|
Context context.Context
|
||||||
DebugOut io.Writer
|
|
||||||
DebugDOTOut io.WriteCloser
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EncodeFormat struct {
|
type EncodeFormat struct {
|
||||||
|
24
vendor/github.com/goccy/go-json/internal/encoder/string.go
generated
vendored
24
vendor/github.com/goccy/go-json/internal/encoder/string.go
generated
vendored
@ -1,27 +1,3 @@
|
|||||||
// This files's string processing codes are inspired by https://github.com/segmentio/encoding.
|
|
||||||
// The license notation is as follows.
|
|
||||||
//
|
|
||||||
// # MIT License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2019 Segment.io, Inc.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
27
vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go
generated
vendored
27
vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go
generated
vendored
@ -2,7 +2,6 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/encoder"
|
"github.com/goccy/go-json/internal/encoder"
|
||||||
)
|
)
|
||||||
@ -15,24 +14,18 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet)
|
|||||||
} else {
|
} else {
|
||||||
code = codeSet.NoescapeKeyCode
|
code = codeSet.NoescapeKeyCode
|
||||||
}
|
}
|
||||||
if wc := ctx.Option.DebugDOTOut; wc != nil {
|
|
||||||
_, _ = io.WriteString(wc, code.DumpDOT())
|
|
||||||
wc.Close()
|
|
||||||
ctx.Option.DebugDOTOut = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
w := ctx.Option.DebugOut
|
fmt.Println("=============[DEBUG]===============")
|
||||||
fmt.Fprintln(w, "=============[DEBUG]===============")
|
fmt.Println("* [TYPE]")
|
||||||
fmt.Fprintln(w, "* [TYPE]")
|
fmt.Println(codeSet.Type)
|
||||||
fmt.Fprintln(w, codeSet.Type)
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [ALL OPCODE]")
|
||||||
fmt.Fprintln(w, "* [ALL OPCODE]")
|
fmt.Println(code.Dump())
|
||||||
fmt.Fprintln(w, code.Dump())
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [CONTEXT]")
|
||||||
fmt.Fprintln(w, "* [CONTEXT]")
|
fmt.Printf("%+v\n", ctx)
|
||||||
fmt.Fprintf(w, "%+v\n", ctx)
|
fmt.Println("===================================")
|
||||||
fmt.Fprintln(w, "===================================")
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
10
vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go
generated
vendored
@ -3,7 +3,6 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -195,12 +194,9 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||||||
typ = iface.typ
|
typ = iface.typ
|
||||||
}
|
}
|
||||||
if ifacePtr == nil {
|
if ifacePtr == nil {
|
||||||
isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
|
b = appendNullComma(ctx, b)
|
||||||
if !isDirectedNil {
|
code = code.Next
|
||||||
b = appendNullComma(ctx, b)
|
break
|
||||||
code = code.Next
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
||||||
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
||||||
|
21
vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go
generated
vendored
21
vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go
generated
vendored
@ -16,17 +16,16 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet)
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
w := ctx.Option.DebugOut
|
fmt.Println("=============[DEBUG]===============")
|
||||||
fmt.Fprintln(w, "=============[DEBUG]===============")
|
fmt.Println("* [TYPE]")
|
||||||
fmt.Fprintln(w, "* [TYPE]")
|
fmt.Println(codeSet.Type)
|
||||||
fmt.Fprintln(w, codeSet.Type)
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [ALL OPCODE]")
|
||||||
fmt.Fprintln(w, "* [ALL OPCODE]")
|
fmt.Println(code.Dump())
|
||||||
fmt.Fprintln(w, code.Dump())
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [CONTEXT]")
|
||||||
fmt.Fprintln(w, "* [CONTEXT]")
|
fmt.Printf("%+v\n", ctx)
|
||||||
fmt.Fprintf(w, "%+v\n", ctx)
|
fmt.Println("===================================")
|
||||||
fmt.Fprintln(w, "===================================")
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
10
vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go
generated
vendored
@ -3,7 +3,6 @@ package vm_color
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -195,12 +194,9 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||||||
typ = iface.typ
|
typ = iface.typ
|
||||||
}
|
}
|
||||||
if ifacePtr == nil {
|
if ifacePtr == nil {
|
||||||
isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
|
b = appendNullComma(ctx, b)
|
||||||
if !isDirectedNil {
|
code = code.Next
|
||||||
b = appendNullComma(ctx, b)
|
break
|
||||||
code = code.Next
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
||||||
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
||||||
|
21
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go
generated
vendored
21
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go
generated
vendored
@ -16,17 +16,16 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet)
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
w := ctx.Option.DebugOut
|
fmt.Println("=============[DEBUG]===============")
|
||||||
fmt.Fprintln(w, "=============[DEBUG]===============")
|
fmt.Println("* [TYPE]")
|
||||||
fmt.Fprintln(w, "* [TYPE]")
|
fmt.Println(codeSet.Type)
|
||||||
fmt.Fprintln(w, codeSet.Type)
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [ALL OPCODE]")
|
||||||
fmt.Fprintln(w, "* [ALL OPCODE]")
|
fmt.Println(code.Dump())
|
||||||
fmt.Fprintln(w, code.Dump())
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [CONTEXT]")
|
||||||
fmt.Fprintln(w, "* [CONTEXT]")
|
fmt.Printf("%+v\n", ctx)
|
||||||
fmt.Fprintf(w, "%+v\n", ctx)
|
fmt.Println("===================================")
|
||||||
fmt.Fprintln(w, "===================================")
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
7
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go
generated
vendored
7
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go
generated
vendored
@ -189,7 +189,7 @@ func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
||||||
return append(b[:len(b)-2], ':', ' ')
|
return append(b, ':', ' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
||||||
@ -229,9 +229,8 @@ func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
|
|
||||||
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
||||||
last := len(b) - 1
|
last := len(b) - 1
|
||||||
// replace comma to newline
|
b[last] = '\n'
|
||||||
b[last-1] = '\n'
|
b = appendIndent(ctx, b, code.Indent-1)
|
||||||
b = appendIndent(ctx, b[:last], code.Indent)
|
|
||||||
return append(b, '}', ',', '\n')
|
return append(b, '}', ',', '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go
generated
vendored
@ -3,7 +3,6 @@ package vm_color_indent
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -195,12 +194,9 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||||||
typ = iface.typ
|
typ = iface.typ
|
||||||
}
|
}
|
||||||
if ifacePtr == nil {
|
if ifacePtr == nil {
|
||||||
isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
|
b = appendNullComma(ctx, b)
|
||||||
if !isDirectedNil {
|
code = code.Next
|
||||||
b = appendNullComma(ctx, b)
|
break
|
||||||
code = code.Next
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
||||||
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
||||||
|
21
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go
generated
vendored
21
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go
generated
vendored
@ -16,17 +16,16 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet)
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
w := ctx.Option.DebugOut
|
fmt.Println("=============[DEBUG]===============")
|
||||||
fmt.Fprintln(w, "=============[DEBUG]===============")
|
fmt.Println("* [TYPE]")
|
||||||
fmt.Fprintln(w, "* [TYPE]")
|
fmt.Println(codeSet.Type)
|
||||||
fmt.Fprintln(w, codeSet.Type)
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [ALL OPCODE]")
|
||||||
fmt.Fprintln(w, "* [ALL OPCODE]")
|
fmt.Println(code.Dump())
|
||||||
fmt.Fprintln(w, code.Dump())
|
fmt.Printf("\n")
|
||||||
fmt.Fprintf(w, "\n")
|
fmt.Println("* [CONTEXT]")
|
||||||
fmt.Fprintln(w, "* [CONTEXT]")
|
fmt.Printf("%+v\n", ctx)
|
||||||
fmt.Fprintf(w, "%+v\n", ctx)
|
fmt.Println("===================================")
|
||||||
fmt.Fprintln(w, "===================================")
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
7
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go
generated
vendored
7
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go
generated
vendored
@ -133,7 +133,7 @@ func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
||||||
return append(b[:len(b)-2], ':', ' ')
|
return append(b, ':', ' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
||||||
@ -173,9 +173,8 @@ func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
|
|
||||||
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
||||||
last := len(b) - 1
|
last := len(b) - 1
|
||||||
// replace comma to newline
|
b[last] = '\n'
|
||||||
b[last-1] = '\n'
|
b = appendIndent(ctx, b, code.Indent-1)
|
||||||
b = appendIndent(ctx, b[:last], code.Indent)
|
|
||||||
return append(b, '}', ',', '\n')
|
return append(b, '}', ',', '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go
generated
vendored
10
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go
generated
vendored
@ -3,7 +3,6 @@ package vm_indent
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -195,12 +194,9 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||||||
typ = iface.typ
|
typ = iface.typ
|
||||||
}
|
}
|
||||||
if ifacePtr == nil {
|
if ifacePtr == nil {
|
||||||
isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
|
b = appendNullComma(ctx, b)
|
||||||
if !isDirectedNil {
|
code = code.Next
|
||||||
b = appendNullComma(ctx, b)
|
break
|
||||||
code = code.Next
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
ctx.KeepRefs = append(ctx.KeepRefs, up)
|
||||||
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
|
||||||
|
19
vendor/github.com/goccy/go-json/internal/errors/error.go
generated
vendored
19
vendor/github.com/goccy/go-json/internal/errors/error.go
generated
vendored
@ -162,22 +162,3 @@ func ErrInvalidBeginningOfValue(c byte, cursor int64) *SyntaxError {
|
|||||||
Offset: cursor,
|
Offset: cursor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PathError struct {
|
|
||||||
msg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *PathError) Error() string {
|
|
||||||
return fmt.Sprintf("json: invalid path format: %s", e.msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrInvalidPath(msg string, args ...interface{}) *PathError {
|
|
||||||
if len(args) != 0 {
|
|
||||||
return &PathError{msg: fmt.Sprintf(msg, args...)}
|
|
||||||
}
|
|
||||||
return &PathError{msg: msg}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrEmptyPath() *PathError {
|
|
||||||
return &PathError{msg: "path is empty"}
|
|
||||||
}
|
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/runtime/rtype.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/runtime/rtype.go
generated
vendored
@ -252,6 +252,7 @@ func IfaceIndir(*Type) bool
|
|||||||
//go:noescape
|
//go:noescape
|
||||||
func RType2Type(t *Type) reflect.Type
|
func RType2Type(t *Type) reflect.Type
|
||||||
|
|
||||||
|
//go:nolint structcheck
|
||||||
type emptyInterface struct {
|
type emptyInterface struct {
|
||||||
_ *Type
|
_ *Type
|
||||||
ptr unsafe.Pointer
|
ptr unsafe.Pointer
|
||||||
|
6
vendor/github.com/goccy/go-json/internal/runtime/struct_field.go
generated
vendored
6
vendor/github.com/goccy/go-json/internal/runtime/struct_field.go
generated
vendored
@ -13,11 +13,7 @@ func getTag(field reflect.StructField) string {
|
|||||||
func IsIgnoredStructField(field reflect.StructField) bool {
|
func IsIgnoredStructField(field reflect.StructField) bool {
|
||||||
if field.PkgPath != "" {
|
if field.PkgPath != "" {
|
||||||
if field.Anonymous {
|
if field.Anonymous {
|
||||||
t := field.Type
|
if !(field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct) && field.Type.Kind() != reflect.Struct {
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
if t.Kind() != reflect.Struct {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
35
vendor/github.com/goccy/go-json/json.go
generated
vendored
35
vendor/github.com/goccy/go-json/json.go
generated
vendored
@ -89,31 +89,31 @@ type UnmarshalerContext interface {
|
|||||||
//
|
//
|
||||||
// Examples of struct field tags and their meanings:
|
// Examples of struct field tags and their meanings:
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "myName".
|
// // Field appears in JSON as key "myName".
|
||||||
// Field int `json:"myName"`
|
// Field int `json:"myName"`
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "myName" and
|
// // Field appears in JSON as key "myName" and
|
||||||
// // the field is omitted from the object if its value is empty,
|
// // the field is omitted from the object if its value is empty,
|
||||||
// // as defined above.
|
// // as defined above.
|
||||||
// Field int `json:"myName,omitempty"`
|
// Field int `json:"myName,omitempty"`
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "Field" (the default), but
|
// // Field appears in JSON as key "Field" (the default), but
|
||||||
// // the field is skipped if empty.
|
// // the field is skipped if empty.
|
||||||
// // Note the leading comma.
|
// // Note the leading comma.
|
||||||
// Field int `json:",omitempty"`
|
// Field int `json:",omitempty"`
|
||||||
//
|
//
|
||||||
// // Field is ignored by this package.
|
// // Field is ignored by this package.
|
||||||
// Field int `json:"-"`
|
// Field int `json:"-"`
|
||||||
//
|
//
|
||||||
// // Field appears in JSON as key "-".
|
// // Field appears in JSON as key "-".
|
||||||
// Field int `json:"-,"`
|
// Field int `json:"-,"`
|
||||||
//
|
//
|
||||||
// The "string" option signals that a field is stored as JSON inside a
|
// The "string" option signals that a field is stored as JSON inside a
|
||||||
// JSON-encoded string. It applies only to fields of string, floating point,
|
// JSON-encoded string. It applies only to fields of string, floating point,
|
||||||
// integer, or boolean types. This extra level of encoding is sometimes used
|
// integer, or boolean types. This extra level of encoding is sometimes used
|
||||||
// when communicating with JavaScript programs:
|
// when communicating with JavaScript programs:
|
||||||
//
|
//
|
||||||
// Int64String int64 `json:",string"`
|
// Int64String int64 `json:",string"`
|
||||||
//
|
//
|
||||||
// The key name will be used if it's a non-empty string consisting of
|
// The key name will be used if it's a non-empty string consisting of
|
||||||
// only Unicode letters, digits, and ASCII punctuation except quotation
|
// only Unicode letters, digits, and ASCII punctuation except quotation
|
||||||
@ -166,6 +166,7 @@ type UnmarshalerContext interface {
|
|||||||
// JSON cannot represent cyclic data structures and Marshal does not
|
// JSON cannot represent cyclic data structures and Marshal does not
|
||||||
// handle them. Passing cyclic structures to Marshal will result in
|
// handle them. Passing cyclic structures to Marshal will result in
|
||||||
// an infinite recursion.
|
// an infinite recursion.
|
||||||
|
//
|
||||||
func Marshal(v interface{}) ([]byte, error) {
|
func Marshal(v interface{}) ([]byte, error) {
|
||||||
return MarshalWithOption(v)
|
return MarshalWithOption(v)
|
||||||
}
|
}
|
||||||
@ -263,13 +264,14 @@ func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...E
|
|||||||
//
|
//
|
||||||
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
||||||
// by setting that Go value to nil. Because null is often used in JSON to mean
|
// by setting that Go value to nil. Because null is often used in JSON to mean
|
||||||
// “not present,” unmarshaling a JSON null into any other Go type has no effect
|
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
|
||||||
// on the value and produces no error.
|
// on the value and produces no error.
|
||||||
//
|
//
|
||||||
// When unmarshaling quoted strings, invalid UTF-8 or
|
// When unmarshaling quoted strings, invalid UTF-8 or
|
||||||
// invalid UTF-16 surrogate pairs are not treated as an error.
|
// invalid UTF-16 surrogate pairs are not treated as an error.
|
||||||
// Instead, they are replaced by the Unicode replacement
|
// Instead, they are replaced by the Unicode replacement
|
||||||
// character U+FFFD.
|
// character U+FFFD.
|
||||||
|
//
|
||||||
func Unmarshal(data []byte, v interface{}) error {
|
func Unmarshal(data []byte, v interface{}) error {
|
||||||
return unmarshal(data, v)
|
return unmarshal(data, v)
|
||||||
}
|
}
|
||||||
@ -297,6 +299,7 @@ func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc)
|
|||||||
// Number, for JSON numbers
|
// Number, for JSON numbers
|
||||||
// string, for JSON string literals
|
// string, for JSON string literals
|
||||||
// nil, for JSON null
|
// nil, for JSON null
|
||||||
|
//
|
||||||
type Token = json.Token
|
type Token = json.Token
|
||||||
|
|
||||||
// A Number represents a JSON number literal.
|
// A Number represents a JSON number literal.
|
||||||
|
16
vendor/github.com/goccy/go-json/option.go
generated
vendored
16
vendor/github.com/goccy/go-json/option.go
generated
vendored
@ -1,8 +1,6 @@
|
|||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/decoder"
|
"github.com/goccy/go-json/internal/decoder"
|
||||||
"github.com/goccy/go-json/internal/encoder"
|
"github.com/goccy/go-json/internal/encoder"
|
||||||
)
|
)
|
||||||
@ -41,20 +39,6 @@ func Debug() EncodeOptionFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugWith sets the destination to write debug messages.
|
|
||||||
func DebugWith(w io.Writer) EncodeOptionFunc {
|
|
||||||
return func(opt *EncodeOption) {
|
|
||||||
opt.DebugOut = w
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DebugDOT sets the destination to write opcodes graph.
|
|
||||||
func DebugDOT(w io.WriteCloser) EncodeOptionFunc {
|
|
||||||
return func(opt *EncodeOption) {
|
|
||||||
opt.DebugDOTOut = w
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Colorize add an identifier for coloring to the string of the encoded result.
|
// Colorize add an identifier for coloring to the string of the encoded result.
|
||||||
func Colorize(scheme *ColorScheme) EncodeOptionFunc {
|
func Colorize(scheme *ColorScheme) EncodeOptionFunc {
|
||||||
return func(opt *EncodeOption) {
|
return func(opt *EncodeOption) {
|
||||||
|
84
vendor/github.com/goccy/go-json/path.go
generated
vendored
84
vendor/github.com/goccy/go-json/path.go
generated
vendored
@ -1,84 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/decoder"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreatePath creates JSON Path.
|
|
||||||
//
|
|
||||||
// JSON Path rule
|
|
||||||
// $ : root object or element. The JSON Path format must start with this operator, which refers to the outermost level of the JSON-formatted string.
|
|
||||||
// . : child operator. You can identify child values using dot-notation.
|
|
||||||
// .. : recursive descent.
|
|
||||||
// [] : subscript operator. If the JSON object is an array, you can use brackets to specify the array index.
|
|
||||||
// [*] : all objects/elements for array.
|
|
||||||
//
|
|
||||||
// Reserved words must be properly escaped when included in Path.
|
|
||||||
//
|
|
||||||
// Escape Rule
|
|
||||||
// single quote style escape: e.g.) `$['a.b'].c`
|
|
||||||
// double quote style escape: e.g.) `$."a.b".c`
|
|
||||||
func CreatePath(p string) (*Path, error) {
|
|
||||||
path, err := decoder.PathString(p).Build()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Path{path: path}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path represents JSON Path.
|
|
||||||
type Path struct {
|
|
||||||
path *decoder.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
// RootSelectorOnly whether only the root selector ($) is used.
|
|
||||||
func (p *Path) RootSelectorOnly() bool {
|
|
||||||
return p.path.RootSelectorOnly
|
|
||||||
}
|
|
||||||
|
|
||||||
// UsedSingleQuotePathSelector whether single quote-based escaping was done when building the JSON Path.
|
|
||||||
func (p *Path) UsedSingleQuotePathSelector() bool {
|
|
||||||
return p.path.SingleQuotePathSelector
|
|
||||||
}
|
|
||||||
|
|
||||||
// UsedSingleQuotePathSelector whether double quote-based escaping was done when building the JSON Path.
|
|
||||||
func (p *Path) UsedDoubleQuotePathSelector() bool {
|
|
||||||
return p.path.DoubleQuotePathSelector
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract extracts a specific JSON string.
|
|
||||||
func (p *Path) Extract(data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
|
|
||||||
return extractFromPath(p, data, optFuncs...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PathString returns original JSON Path string.
|
|
||||||
func (p *Path) PathString() string {
|
|
||||||
return p.path.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal extract and decode the value of the part corresponding to JSON Path from the input data.
|
|
||||||
func (p *Path) Unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
|
|
||||||
contents, err := extractFromPath(p, data, optFuncs...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
results := make([]interface{}, 0, len(contents))
|
|
||||||
for _, content := range contents {
|
|
||||||
var result interface{}
|
|
||||||
if err := Unmarshal(content, &result); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
results = append(results, result)
|
|
||||||
}
|
|
||||||
if err := decoder.AssignValue(reflect.ValueOf(results), reflect.ValueOf(v)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get extract and substitute the value of the part corresponding to JSON Path from the input value.
|
|
||||||
func (p *Path) Get(src, dst interface{}) error {
|
|
||||||
return p.path.Get(reflect.ValueOf(src), reflect.ValueOf(dst))
|
|
||||||
}
|
|
21
vendor/github.com/labstack/echo/v4/.travis.yml
generated
vendored
Normal file
21
vendor/github.com/labstack/echo/v4/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
arch:
|
||||||
|
- amd64
|
||||||
|
- ppc64le
|
||||||
|
|
||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.14.x
|
||||||
|
- 1.15.x
|
||||||
|
- tip
|
||||||
|
env:
|
||||||
|
- GO111MODULE=on
|
||||||
|
install:
|
||||||
|
- go get -v golang.org/x/lint/golint
|
||||||
|
script:
|
||||||
|
- golint -set_exit_status ./...
|
||||||
|
- go test -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
250
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
250
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,255 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v4.12.0 - 2024-04-15
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Update golang.org/x/net dep because of [GO-2024-2687](https://pkg.go.dev/vuln/GO-2024-2687) by @aldas in https://github.com/labstack/echo/pull/2625
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* binder: make binding to Map work better with string destinations by @aldas in https://github.com/labstack/echo/pull/2554
|
|
||||||
* README.md: add Encore as sponsor by @marcuskohlberg in https://github.com/labstack/echo/pull/2579
|
|
||||||
* Reorder paragraphs in README.md by @aldas in https://github.com/labstack/echo/pull/2581
|
|
||||||
* CI: upgrade actions/checkout to v4 by @aldas in https://github.com/labstack/echo/pull/2584
|
|
||||||
* Remove default charset from 'application/json' Content-Type header by @doortts in https://github.com/labstack/echo/pull/2568
|
|
||||||
* CI: Use Go 1.22 by @aldas in https://github.com/labstack/echo/pull/2588
|
|
||||||
* binder: allow binding to a nil map by @georgmu in https://github.com/labstack/echo/pull/2574
|
|
||||||
* Add Skipper Unit Test In BasicBasicAuthConfig and Add More Detail Explanation regarding BasicAuthValidator by @RyoKusnadi in https://github.com/labstack/echo/pull/2461
|
|
||||||
* fix some typos by @teslaedison in https://github.com/labstack/echo/pull/2603
|
|
||||||
* fix: some typos by @pomadev in https://github.com/labstack/echo/pull/2596
|
|
||||||
* Allow ResponseWriters to unwrap writers when flushing/hijacking by @aldas in https://github.com/labstack/echo/pull/2595
|
|
||||||
* Add SPDX licence comments to files. by @aldas in https://github.com/labstack/echo/pull/2604
|
|
||||||
* Upgrade deps by @aldas in https://github.com/labstack/echo/pull/2605
|
|
||||||
* Change type definition blocks to single declarations. This helps copy… by @aldas in https://github.com/labstack/echo/pull/2606
|
|
||||||
* Fix Real IP logic by @cl-bvl in https://github.com/labstack/echo/pull/2550
|
|
||||||
* Default binder can use `UnmarshalParams(params []string) error` inter… by @aldas in https://github.com/labstack/echo/pull/2607
|
|
||||||
* Default binder can bind pointer to slice as struct field. For example `*[]string` by @aldas in https://github.com/labstack/echo/pull/2608
|
|
||||||
* Remove maxparam dependence from Context by @aldas in https://github.com/labstack/echo/pull/2611
|
|
||||||
* When route is registered with empty path it is normalized to `/`. by @aldas in https://github.com/labstack/echo/pull/2616
|
|
||||||
* proxy middleware should use httputil.ReverseProxy for SSE requests by @aldas in https://github.com/labstack/echo/pull/2624
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.4 - 2023-12-20
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Upgrade golang.org/x/crypto to v0.17.0 to fix vulnerability [issue](https://pkg.go.dev/vuln/GO-2023-2402) [#2562](https://github.com/labstack/echo/pull/2562)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Update deps and mark Go version to 1.18 as this is what golang.org/x/* use [#2563](https://github.com/labstack/echo/pull/2563)
|
|
||||||
* Request logger: add example for Slog https://pkg.go.dev/log/slog [#2543](https://github.com/labstack/echo/pull/2543)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.3 - 2023-11-07
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* 'c.Attachment' and 'c.Inline' should escape filename in 'Content-Disposition' header to avoid 'Reflect File Download' vulnerability. [#2541](https://github.com/labstack/echo/pull/2541)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Tests: refactor context tests to be separate functions [#2540](https://github.com/labstack/echo/pull/2540)
|
|
||||||
* Proxy middleware: reuse echo request context [#2537](https://github.com/labstack/echo/pull/2537)
|
|
||||||
* Mark unmarshallable yaml struct tags as ignored [#2536](https://github.com/labstack/echo/pull/2536)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.2 - 2023-10-11
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Bump golang.org/x/net to prevent CVE-2023-39325 / CVE-2023-44487 HTTP/2 Rapid Reset Attack [#2527](https://github.com/labstack/echo/pull/2527)
|
|
||||||
* fix(sec): randomString bias introduced by #2490 [#2492](https://github.com/labstack/echo/pull/2492)
|
|
||||||
* CSRF/RequestID mw: switch math/random usage to crypto/random [#2490](https://github.com/labstack/echo/pull/2490)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Delete unused context in body_limit.go [#2483](https://github.com/labstack/echo/pull/2483)
|
|
||||||
* Use Go 1.21 in CI [#2505](https://github.com/labstack/echo/pull/2505)
|
|
||||||
* Fix some typos [#2511](https://github.com/labstack/echo/pull/2511)
|
|
||||||
* Allow CORS middleware to send Access-Control-Max-Age: 0 [#2518](https://github.com/labstack/echo/pull/2518)
|
|
||||||
* Bump dependancies [#2522](https://github.com/labstack/echo/pull/2522)
|
|
||||||
|
|
||||||
## v4.11.1 - 2023-07-16
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fix `Gzip` middleware not sending response code for no content responses (404, 301/302 redirects etc) [#2481](https://github.com/labstack/echo/pull/2481)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.0 - 2023-07-14
|
|
||||||
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fixes the proxy middleware concurrency issue of calling the Next() proxy target on Round Robin Balancer [#2409](https://github.com/labstack/echo/pull/2409)
|
|
||||||
* Fix `group.RouteNotFound` not working when group has attached middlewares [#2411](https://github.com/labstack/echo/pull/2411)
|
|
||||||
* Fix global error handler return error message when message is an error [#2456](https://github.com/labstack/echo/pull/2456)
|
|
||||||
* Do not use global timeNow variables [#2477](https://github.com/labstack/echo/pull/2477)
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Added a optional config variable to disable centralized error handler in recovery middleware [#2410](https://github.com/labstack/echo/pull/2410)
|
|
||||||
* refactor: use `strings.ReplaceAll` directly [#2424](https://github.com/labstack/echo/pull/2424)
|
|
||||||
* Add support for Go1.20 `http.rwUnwrapper` to Response struct [#2425](https://github.com/labstack/echo/pull/2425)
|
|
||||||
* Check whether is nil before invoking centralized error handling [#2429](https://github.com/labstack/echo/pull/2429)
|
|
||||||
* Proper colon support in `echo.Reverse` method [#2416](https://github.com/labstack/echo/pull/2416)
|
|
||||||
* Fix misuses of a vs an in documentation comments [#2436](https://github.com/labstack/echo/pull/2436)
|
|
||||||
* Add link to slog.Handler library for Echo logging into README.md [#2444](https://github.com/labstack/echo/pull/2444)
|
|
||||||
* In proxy middleware Support retries of failed proxy requests [#2414](https://github.com/labstack/echo/pull/2414)
|
|
||||||
* gofmt fixes to comments [#2452](https://github.com/labstack/echo/pull/2452)
|
|
||||||
* gzip response only if it exceeds a minimal length [#2267](https://github.com/labstack/echo/pull/2267)
|
|
||||||
* Upgrade packages [#2475](https://github.com/labstack/echo/pull/2475)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.10.2 - 2023-02-22
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* `filepath.Clean` behaviour has changed in Go 1.20 - adapt to it [#2406](https://github.com/labstack/echo/pull/2406)
|
|
||||||
* Add `middleware.CORSConfig.UnsafeWildcardOriginWithAllowCredentials` to make UNSAFE usages of wildcard origin + allow cretentials less likely [#2405](https://github.com/labstack/echo/pull/2405)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Add more HTTP error values [#2277](https://github.com/labstack/echo/pull/2277)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.10.1 - 2023-02-19
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Upgrade deps due to the latest golang.org/x/net vulnerability [#2402](https://github.com/labstack/echo/pull/2402)
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Add new JWT repository to the README [#2377](https://github.com/labstack/echo/pull/2377)
|
|
||||||
* Return an empty string for ctx.path if there is no registered path [#2385](https://github.com/labstack/echo/pull/2385)
|
|
||||||
* Add context timeout middleware [#2380](https://github.com/labstack/echo/pull/2380)
|
|
||||||
* Update link to jaegertracing [#2394](https://github.com/labstack/echo/pull/2394)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.10.0 - 2022-12-27
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* We are deprecating JWT middleware in this repository. Please use https://github.com/labstack/echo-jwt instead.
|
|
||||||
|
|
||||||
JWT middleware is moved to separate repository to allow us to bump/upgrade version of JWT implementation (`github.com/golang-jwt/jwt`) we are using
|
|
||||||
which we can not do in Echo core because this would break backwards compatibility guarantees we try to maintain.
|
|
||||||
|
|
||||||
* This minor version bumps minimum Go version to 1.17 (from 1.16) due `golang.org/x/` packages we depend on. There are
|
|
||||||
several vulnerabilities fixed in these libraries.
|
|
||||||
|
|
||||||
Echo still tries to support last 4 Go versions but there are occasions we can not guarantee this promise.
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Bump x/text to 0.3.8 [#2305](https://github.com/labstack/echo/pull/2305)
|
|
||||||
* Bump dependencies and add notes about Go releases we support [#2336](https://github.com/labstack/echo/pull/2336)
|
|
||||||
* Add helper interface for ProxyBalancer interface [#2316](https://github.com/labstack/echo/pull/2316)
|
|
||||||
* Expose `middleware.CreateExtractors` function so we can use it from echo-contrib repository [#2338](https://github.com/labstack/echo/pull/2338)
|
|
||||||
* Refactor func(Context) error to HandlerFunc [#2315](https://github.com/labstack/echo/pull/2315)
|
|
||||||
* Improve function comments [#2329](https://github.com/labstack/echo/pull/2329)
|
|
||||||
* Add new method HTTPError.WithInternal [#2340](https://github.com/labstack/echo/pull/2340)
|
|
||||||
* Replace io/ioutil package usages [#2342](https://github.com/labstack/echo/pull/2342)
|
|
||||||
* Add staticcheck to CI flow [#2343](https://github.com/labstack/echo/pull/2343)
|
|
||||||
* Replace relative path determination from proprietary to std [#2345](https://github.com/labstack/echo/pull/2345)
|
|
||||||
* Remove square brackets from ipv6 addresses in XFF (X-Forwarded-For header) [#2182](https://github.com/labstack/echo/pull/2182)
|
|
||||||
* Add testcases for some BodyLimit middleware configuration options [#2350](https://github.com/labstack/echo/pull/2350)
|
|
||||||
* Additional configuration options for RequestLogger and Logger middleware [#2341](https://github.com/labstack/echo/pull/2341)
|
|
||||||
* Add route to request log [#2162](https://github.com/labstack/echo/pull/2162)
|
|
||||||
* GitHub Workflows security hardening [#2358](https://github.com/labstack/echo/pull/2358)
|
|
||||||
* Add govulncheck to CI and bump dependencies [#2362](https://github.com/labstack/echo/pull/2362)
|
|
||||||
* Fix rate limiter docs [#2366](https://github.com/labstack/echo/pull/2366)
|
|
||||||
* Refactor how `e.Routes()` work and introduce `e.OnAddRouteHandler` callback [#2337](https://github.com/labstack/echo/pull/2337)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.9.1 - 2022-10-12
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fix logger panicing (when template is set to empty) by bumping dependency version [#2295](https://github.com/labstack/echo/issues/2295)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Improve CORS documentation [#2272](https://github.com/labstack/echo/pull/2272)
|
|
||||||
* Update readme about supported Go versions [#2291](https://github.com/labstack/echo/pull/2291)
|
|
||||||
* Tests: improve error handling on closing body [#2254](https://github.com/labstack/echo/pull/2254)
|
|
||||||
* Tests: refactor some of the assertions in tests [#2275](https://github.com/labstack/echo/pull/2275)
|
|
||||||
* Tests: refactor assertions [#2301](https://github.com/labstack/echo/pull/2301)
|
|
||||||
|
|
||||||
## v4.9.0 - 2022-09-04
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Fix open redirect vulnerability in handlers serving static directories (e.Static, e.StaticFs, echo.StaticDirectoryHandler) [#2260](https://github.com/labstack/echo/pull/2260)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Allow configuring ErrorHandler in CSRF middleware [#2257](https://github.com/labstack/echo/pull/2257)
|
|
||||||
* Replace HTTP method constants in tests with stdlib constants [#2247](https://github.com/labstack/echo/pull/2247)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.8.0 - 2022-08-10
|
|
||||||
|
|
||||||
**Most notable things**
|
|
||||||
|
|
||||||
You can now add any arbitrary HTTP method type as a route [#2237](https://github.com/labstack/echo/pull/2237)
|
|
||||||
```go
|
|
||||||
e.Add("COPY", "/*", func(c echo.Context) error
|
|
||||||
return c.String(http.StatusOK, "OK COPY")
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
You can add custom 404 handler for specific paths [#2217](https://github.com/labstack/echo/pull/2217)
|
|
||||||
```go
|
|
||||||
e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
|
|
||||||
|
|
||||||
g := e.Group("/images")
|
|
||||||
g.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
|
|
||||||
```
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Add new value binding methods (UnixTimeMilli,TextUnmarshaler,JSONUnmarshaler) to Valuebinder [#2127](https://github.com/labstack/echo/pull/2127)
|
|
||||||
* Refactor: body_limit middleware unit test [#2145](https://github.com/labstack/echo/pull/2145)
|
|
||||||
* Refactor: Timeout mw: rework how test waits for timeout. [#2187](https://github.com/labstack/echo/pull/2187)
|
|
||||||
* BasicAuth middleware returns 500 InternalServerError on invalid base64 strings but should return 400 [#2191](https://github.com/labstack/echo/pull/2191)
|
|
||||||
* Refactor: duplicated findStaticChild process at findChildWithLabel [#2176](https://github.com/labstack/echo/pull/2176)
|
|
||||||
* Allow different param names in different methods with same path scheme [#2209](https://github.com/labstack/echo/pull/2209)
|
|
||||||
* Add support for registering handlers for different 404 routes [#2217](https://github.com/labstack/echo/pull/2217)
|
|
||||||
* Middlewares should use errors.As() instead of type assertion on HTTPError [#2227](https://github.com/labstack/echo/pull/2227)
|
|
||||||
* Allow arbitrary HTTP method types to be added as routes [#2237](https://github.com/labstack/echo/pull/2237)
|
|
||||||
|
|
||||||
## v4.7.2 - 2022-03-16
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fix nil pointer exception when calling Start again after address binding error [#2131](https://github.com/labstack/echo/pull/2131)
|
|
||||||
* Fix CSRF middleware not being able to extract token from multipart/form-data form [#2136](https://github.com/labstack/echo/pull/2136)
|
|
||||||
* Fix Timeout middleware write race [#2126](https://github.com/labstack/echo/pull/2126)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Recover middleware should not log panic for aborted handler [#2134](https://github.com/labstack/echo/pull/2134)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.7.1 - 2022-03-13
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fix `e.Static`, `.File()`, `c.Attachment()` being picky with paths starting with `./`, `../` and `/` after 4.7.0 introduced echo.Filesystem support (Go1.16+) [#2123](https://github.com/labstack/echo/pull/2123)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Remove some unused code [#2116](https://github.com/labstack/echo/pull/2116)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.7.0 - 2022-03-01
|
## v4.7.0 - 2022-03-01
|
||||||
|
|
||||||
**Enhancements**
|
**Enhancements**
|
||||||
|
8
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
8
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
@ -9,11 +9,9 @@ tag:
|
|||||||
check: lint vet race ## Check project
|
check: lint vet race ## Check project
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@go install golang.org/x/lint/golint@latest
|
@go get -u golang.org/x/lint/golint
|
||||||
@go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
||||||
|
|
||||||
lint: ## Lint the files
|
lint: ## Lint the files
|
||||||
@staticcheck ${PKG_LIST}
|
|
||||||
@golint -set_exit_status ${PKG_LIST}
|
@golint -set_exit_status ${PKG_LIST}
|
||||||
|
|
||||||
vet: ## Vet the files
|
vet: ## Vet the files
|
||||||
@ -31,6 +29,6 @@ benchmark: ## Run benchmarks
|
|||||||
help: ## Display this help screen
|
help: ## Display this help screen
|
||||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
goversion ?= "1.19"
|
goversion ?= "1.15"
|
||||||
test_version: ## Run tests inside Docker with given version (defaults to 1.19 oldest supported). Example: make test_version goversion=1.19
|
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.15
|
||||||
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
||||||
|
69
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
69
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
@ -3,24 +3,27 @@
|
|||||||
[![Sourcegraph](https://sourcegraph.com/github.com/labstack/echo/-/badge.svg?style=flat-square)](https://sourcegraph.com/github.com/labstack/echo?badge)
|
[![Sourcegraph](https://sourcegraph.com/github.com/labstack/echo/-/badge.svg?style=flat-square)](https://sourcegraph.com/github.com/labstack/echo?badge)
|
||||||
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/labstack/echo/v4)
|
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/labstack/echo/v4)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/labstack/echo?style=flat-square)](https://goreportcard.com/report/github.com/labstack/echo)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/labstack/echo?style=flat-square)](https://goreportcard.com/report/github.com/labstack/echo)
|
||||||
[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/labstack/echo/echo.yml?style=flat-square)](https://github.com/labstack/echo/actions)
|
[![Build Status](http://img.shields.io/travis/labstack/echo.svg?style=flat-square)](https://travis-ci.org/labstack/echo)
|
||||||
[![Codecov](https://img.shields.io/codecov/c/github/labstack/echo.svg?style=flat-square)](https://codecov.io/gh/labstack/echo)
|
[![Codecov](https://img.shields.io/codecov/c/github/labstack/echo.svg?style=flat-square)](https://codecov.io/gh/labstack/echo)
|
||||||
[![Forum](https://img.shields.io/badge/community-forum-00afd1.svg?style=flat-square)](https://github.com/labstack/echo/discussions)
|
[![Forum](https://img.shields.io/badge/community-forum-00afd1.svg?style=flat-square)](https://github.com/labstack/echo/discussions)
|
||||||
[![Twitter](https://img.shields.io/badge/twitter-@labstack-55acee.svg?style=flat-square)](https://twitter.com/labstack)
|
[![Twitter](https://img.shields.io/badge/twitter-@labstack-55acee.svg?style=flat-square)](https://twitter.com/labstack)
|
||||||
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/labstack/echo/master/LICENSE)
|
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/labstack/echo/master/LICENSE)
|
||||||
|
|
||||||
## Echo
|
## Supported Go versions
|
||||||
|
|
||||||
High performance, extensible, minimalist Go web framework.
|
As of version 4.0.0, Echo is available as a [Go module](https://github.com/golang/go/wiki/Modules).
|
||||||
|
Therefore a Go version capable of understanding /vN suffixed imports is required:
|
||||||
|
|
||||||
* [Official website](https://echo.labstack.com)
|
- 1.9.7+
|
||||||
* [Quick start](https://echo.labstack.com/docs/quick-start)
|
- 1.10.3+
|
||||||
* [Middlewares](https://echo.labstack.com/docs/category/middleware)
|
- 1.14+
|
||||||
|
|
||||||
Help and questions: [Github Discussions](https://github.com/labstack/echo/discussions)
|
Any of these versions will allow you to import Echo as `github.com/labstack/echo/v4` which is the recommended
|
||||||
|
way of using Echo going forward.
|
||||||
|
|
||||||
|
For older versions, please use the latest v3 tag.
|
||||||
|
|
||||||
### Feature Overview
|
## Feature Overview
|
||||||
|
|
||||||
- Optimized HTTP router which smartly prioritize routes
|
- Optimized HTTP router which smartly prioritize routes
|
||||||
- Build robust and scalable RESTful APIs
|
- Build robust and scalable RESTful APIs
|
||||||
@ -36,18 +39,6 @@ Help and questions: [Github Discussions](https://github.com/labstack/echo/discus
|
|||||||
- Automatic TLS via Let’s Encrypt
|
- Automatic TLS via Let’s Encrypt
|
||||||
- HTTP/2 support
|
- HTTP/2 support
|
||||||
|
|
||||||
## Sponsors
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<a href="https://encore.dev" style="display: inline-flex; align-items: center; gap: 10px">
|
|
||||||
<img src="https://user-images.githubusercontent.com/78424526/214602214-52e0483a-b5fc-4d4c-b03e-0b7b23e012df.svg" height="28px" alt="encore icon"></img>
|
|
||||||
<b>Encore – the platform for building Go-based cloud backends</b>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
Click [here](https://github.com/sponsors/labstack) for more information on sponsorship.
|
|
||||||
|
|
||||||
## Benchmarks
|
## Benchmarks
|
||||||
|
|
||||||
Date: 2020/11/11<br>
|
Date: 2020/11/11<br>
|
||||||
@ -67,7 +58,6 @@ The benchmarks above were run on an Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
|
|||||||
// go get github.com/labstack/echo/{version}
|
// go get github.com/labstack/echo/{version}
|
||||||
go get github.com/labstack/echo/v4
|
go get github.com/labstack/echo/v4
|
||||||
```
|
```
|
||||||
Latest version of Echo supports last four Go major [releases](https://go.dev/doc/devel/release) and might work with older versions.
|
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
@ -101,33 +91,24 @@ func hello(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Official middleware repositories
|
# Third-party middlewares
|
||||||
|
|
||||||
Following list of middleware is maintained by Echo team.
|
| Repository | Description |
|
||||||
|
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Repository | Description |
|
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
||||||
|------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
||||||
| [github.com/labstack/echo-jwt](https://github.com/labstack/echo-jwt) | [JWT](https://github.com/golang-jwt/jwt) middleware |
|
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
||||||
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](https://github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
||||||
|
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
||||||
# Third-party middleware repositories
|
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
||||||
|
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo.
|
||||||
Be careful when adding 3rd party middleware. Echo teams does not have time or manpower to guarantee safety and quality
|
|
||||||
of middlewares in this list.
|
|
||||||
|
|
||||||
| Repository | Description |
|
|
||||||
|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
|
||||||
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
|
||||||
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
|
||||||
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
|
||||||
| [github.com/samber/slog-echo](https://github.com/samber/slog-echo) | Go [slog](https://pkg.go.dev/golang.org/x/exp/slog) logging library wrapper for Echo logger interface. |
|
|
||||||
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
|
||||||
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo. |
|
|
||||||
| [github.com/go-woo/protoc-gen-echo](https://github.com/go-woo/protoc-gen-echo) | ProtoBuf generate Echo server side code |
|
|
||||||
|
|
||||||
Please send a PR to add your own library here.
|
Please send a PR to add your own library here.
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
- [Forum](https://github.com/labstack/echo/discussions)
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
**Use issues for everything**
|
**Use issues for everything**
|
||||||
|
150
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
150
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -14,28 +11,23 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Binder is the interface that wraps the Bind method.
|
type (
|
||||||
type Binder interface {
|
// Binder is the interface that wraps the Bind method.
|
||||||
Bind(i interface{}, c Context) error
|
Binder interface {
|
||||||
}
|
Bind(i interface{}, c Context) error
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultBinder is the default implementation of the Binder interface.
|
// DefaultBinder is the default implementation of the Binder interface.
|
||||||
type DefaultBinder struct{}
|
DefaultBinder struct{}
|
||||||
|
|
||||||
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
|
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
|
||||||
// Types that don't implement this, but do implement encoding.TextUnmarshaler
|
// Types that don't implement this, but do implement encoding.TextUnmarshaler
|
||||||
// will use that interface instead.
|
// will use that interface instead.
|
||||||
type BindUnmarshaler interface {
|
BindUnmarshaler interface {
|
||||||
// UnmarshalParam decodes and assigns a value from an form or query param.
|
// UnmarshalParam decodes and assigns a value from an form or query param.
|
||||||
UnmarshalParam(param string) error
|
UnmarshalParam(param string) error
|
||||||
}
|
}
|
||||||
|
)
|
||||||
// bindMultipleUnmarshaler is used by binder to unmarshal multiple values from request at once to
|
|
||||||
// type implementing this interface. For example request could have multiple query fields `?a=1&a=2&b=test` in that case
|
|
||||||
// for `a` following slice `["1", "2"] will be passed to unmarshaller.
|
|
||||||
type bindMultipleUnmarshaler interface {
|
|
||||||
UnmarshalParams(params []string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// BindPathParams binds path params to bindable object
|
// BindPathParams binds path params to bindable object
|
||||||
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
||||||
@ -122,7 +114,7 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
|||||||
// Only bind query parameters for GET/DELETE/HEAD to avoid unexpected behavior with destination struct binding from body.
|
// Only bind query parameters for GET/DELETE/HEAD to avoid unexpected behavior with destination struct binding from body.
|
||||||
// For example a request URL `&id=1&lang=en` with body `{"id":100,"lang":"de"}` would lead to precedence issues.
|
// For example a request URL `&id=1&lang=en` with body `{"id":100,"lang":"de"}` would lead to precedence issues.
|
||||||
// The HTTP method check restores pre-v4.1.11 behavior to avoid these problems (see issue #1670)
|
// The HTTP method check restores pre-v4.1.11 behavior to avoid these problems (see issue #1670)
|
||||||
method := c.Request().Method
|
method := c.Request().Method
|
||||||
if method == http.MethodGet || method == http.MethodDelete || method == http.MethodHead {
|
if method == http.MethodGet || method == http.MethodDelete || method == http.MethodHead {
|
||||||
if err = b.BindQueryParams(c, i); err != nil {
|
if err = b.BindQueryParams(c, i); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -139,29 +131,10 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
typ := reflect.TypeOf(destination).Elem()
|
typ := reflect.TypeOf(destination).Elem()
|
||||||
val := reflect.ValueOf(destination).Elem()
|
val := reflect.ValueOf(destination).Elem()
|
||||||
|
|
||||||
// Support binding to limited Map destinations:
|
// Map
|
||||||
// - map[string][]string,
|
if typ.Kind() == reflect.Map {
|
||||||
// - map[string]string <-- (binds first value from data slice)
|
|
||||||
// - map[string]interface{}
|
|
||||||
// You are better off binding to struct but there are user who want this map feature. Source of data for these cases are:
|
|
||||||
// params,query,header,form as these sources produce string values, most of the time slice of strings, actually.
|
|
||||||
if typ.Kind() == reflect.Map && typ.Key().Kind() == reflect.String {
|
|
||||||
k := typ.Elem().Kind()
|
|
||||||
isElemInterface := k == reflect.Interface
|
|
||||||
isElemString := k == reflect.String
|
|
||||||
isElemSliceOfStrings := k == reflect.Slice && typ.Elem().Elem().Kind() == reflect.String
|
|
||||||
if !(isElemSliceOfStrings || isElemString || isElemInterface) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if val.IsNil() {
|
|
||||||
val.Set(reflect.MakeMap(typ))
|
|
||||||
}
|
|
||||||
for k, v := range data {
|
for k, v := range data {
|
||||||
if isElemString {
|
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
||||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
|
||||||
} else {
|
|
||||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -188,14 +161,14 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
}
|
}
|
||||||
structFieldKind := structField.Kind()
|
structFieldKind := structField.Kind()
|
||||||
inputFieldName := typeField.Tag.Get(tag)
|
inputFieldName := typeField.Tag.Get(tag)
|
||||||
if typeField.Anonymous && structFieldKind == reflect.Struct && inputFieldName != "" {
|
if typeField.Anonymous && structField.Kind() == reflect.Struct && inputFieldName != "" {
|
||||||
// if anonymous struct with query/param/form tags, report an error
|
// if anonymous struct with query/param/form tags, report an error
|
||||||
return errors.New("query/param/form tags are not allowed with anonymous struct field")
|
return errors.New("query/param/form tags are not allowed with anonymous struct field")
|
||||||
}
|
}
|
||||||
|
|
||||||
if inputFieldName == "" {
|
if inputFieldName == "" {
|
||||||
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
||||||
// structs that implement BindUnmarshaler are bound only when they have explicit tag
|
// structs that implement BindUnmarshaler are binded only when they have explicit tag
|
||||||
if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
|
if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
|
||||||
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
|
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -224,46 +197,27 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: algorithm here is not particularly sophisticated. It probably does not work with absurd types like `**[]*int`
|
// Call this first, in case we're dealing with an alias to an array type
|
||||||
// but it is smart enough to handle niche cases like `*int`,`*[]string`,`[]*int` .
|
if ok, err := unmarshalField(typeField.Type.Kind(), inputValue[0], structField); ok {
|
||||||
|
|
||||||
// try unmarshalling first, in case we're dealing with an alias to an array type
|
|
||||||
if ok, err := unmarshalInputsToField(typeField.Type.Kind(), inputValue, structField); ok {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok, err := unmarshalInputToField(typeField.Type.Kind(), inputValue[0], structField); ok {
|
numElems := len(inputValue)
|
||||||
if err != nil {
|
if structFieldKind == reflect.Slice && numElems > 0 {
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// we could be dealing with pointer to slice `*[]string` so dereference it. There are wierd OpenAPI generators
|
|
||||||
// that could create struct fields like that.
|
|
||||||
if structFieldKind == reflect.Pointer {
|
|
||||||
structFieldKind = structField.Elem().Kind()
|
|
||||||
structField = structField.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
if structFieldKind == reflect.Slice {
|
|
||||||
sliceOf := structField.Type().Elem().Kind()
|
sliceOf := structField.Type().Elem().Kind()
|
||||||
numElems := len(inputValue)
|
|
||||||
slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
|
slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
|
||||||
for j := 0; j < numElems; j++ {
|
for j := 0; j < numElems; j++ {
|
||||||
if err := setWithProperType(sliceOf, inputValue[j], slice.Index(j)); err != nil {
|
if err := setWithProperType(sliceOf, inputValue[j], slice.Index(j)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
structField.Set(slice)
|
val.Field(i).Set(slice)
|
||||||
continue
|
} else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
if err := setWithProperType(structFieldKind, inputValue[0], structField); err != nil {
|
|
||||||
return err
|
return err
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -271,7 +225,7 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
|
|
||||||
func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error {
|
func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error {
|
||||||
// But also call it here, in case we're dealing with an array of BindUnmarshalers
|
// But also call it here, in case we're dealing with an array of BindUnmarshalers
|
||||||
if ok, err := unmarshalInputToField(valueKind, val, structField); ok {
|
if ok, err := unmarshalField(valueKind, val, structField); ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,41 +266,35 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalInputsToField(valueKind reflect.Kind, values []string, field reflect.Value) (bool, error) {
|
func unmarshalField(valueKind reflect.Kind, val string, field reflect.Value) (bool, error) {
|
||||||
if valueKind == reflect.Ptr {
|
switch valueKind {
|
||||||
if field.IsNil() {
|
case reflect.Ptr:
|
||||||
field.Set(reflect.New(field.Type().Elem()))
|
return unmarshalFieldPtr(val, field)
|
||||||
}
|
default:
|
||||||
field = field.Elem()
|
return unmarshalFieldNonPtr(val, field)
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldIValue := field.Addr().Interface()
|
|
||||||
unmarshaler, ok := fieldIValue.(bindMultipleUnmarshaler)
|
|
||||||
if !ok {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, unmarshaler.UnmarshalParams(values)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalInputToField(valueKind reflect.Kind, val string, field reflect.Value) (bool, error) {
|
func unmarshalFieldNonPtr(value string, field reflect.Value) (bool, error) {
|
||||||
if valueKind == reflect.Ptr {
|
|
||||||
if field.IsNil() {
|
|
||||||
field.Set(reflect.New(field.Type().Elem()))
|
|
||||||
}
|
|
||||||
field = field.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldIValue := field.Addr().Interface()
|
fieldIValue := field.Addr().Interface()
|
||||||
switch unmarshaler := fieldIValue.(type) {
|
if unmarshaler, ok := fieldIValue.(BindUnmarshaler); ok {
|
||||||
case BindUnmarshaler:
|
return true, unmarshaler.UnmarshalParam(value)
|
||||||
return true, unmarshaler.UnmarshalParam(val)
|
}
|
||||||
case encoding.TextUnmarshaler:
|
if unmarshaler, ok := fieldIValue.(encoding.TextUnmarshaler); ok {
|
||||||
return true, unmarshaler.UnmarshalText([]byte(val))
|
return true, unmarshaler.UnmarshalText([]byte(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unmarshalFieldPtr(value string, field reflect.Value) (bool, error) {
|
||||||
|
if field.IsNil() {
|
||||||
|
// Initialize the pointer to a nil value
|
||||||
|
field.Set(reflect.New(field.Type().Elem()))
|
||||||
|
}
|
||||||
|
return unmarshalFieldNonPtr(value, field.Elem())
|
||||||
|
}
|
||||||
|
|
||||||
func setIntField(value string, bitSize int, field reflect.Value) error {
|
func setIntField(value string, bitSize int, field reflect.Value) error {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
value = "0"
|
value = "0"
|
||||||
|
212
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
212
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
@ -1,11 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -57,11 +52,8 @@ import (
|
|||||||
* time
|
* time
|
||||||
* duration
|
* duration
|
||||||
* BindUnmarshaler() interface
|
* BindUnmarshaler() interface
|
||||||
* TextUnmarshaler() interface
|
|
||||||
* JSONUnmarshaler() interface
|
|
||||||
* UnixTime() - converts unix time (integer) to time.Time
|
* UnixTime() - converts unix time (integer) to time.Time
|
||||||
* UnixTimeMilli() - converts unix time with millisecond precision (integer) to time.Time
|
* UnixTimeNano() - converts unix time with nano second precision (integer) to time.Time
|
||||||
* UnixTimeNano() - converts unix time with nanosecond precision (integer) to time.Time
|
|
||||||
* CustomFunc() - callback function for your custom conversion logic. Signature `func(values []string) []error`
|
* CustomFunc() - callback function for your custom conversion logic. Signature `func(values []string) []error`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -212,7 +204,7 @@ func (b *ValueBinder) CustomFunc(sourceParam string, customFunc func(values []st
|
|||||||
return b.customFunc(sourceParam, customFunc, false)
|
return b.customFunc(sourceParam, customFunc, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustCustomFunc requires parameter values to exist to bind with Func. Returns error when value does not exist.
|
// MustCustomFunc requires parameter values to exist to be bind with Func. Returns error when value does not exist.
|
||||||
func (b *ValueBinder) MustCustomFunc(sourceParam string, customFunc func(values []string) []error) *ValueBinder {
|
func (b *ValueBinder) MustCustomFunc(sourceParam string, customFunc func(values []string) []error) *ValueBinder {
|
||||||
return b.customFunc(sourceParam, customFunc, true)
|
return b.customFunc(sourceParam, customFunc, true)
|
||||||
}
|
}
|
||||||
@ -249,7 +241,7 @@ func (b *ValueBinder) String(sourceParam string, dest *string) *ValueBinder {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustString requires parameter value to exist to bind to string variable. Returns error when value does not exist
|
// MustString requires parameter value to exist to be bind to string variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustString(sourceParam string, dest *string) *ValueBinder {
|
func (b *ValueBinder) MustString(sourceParam string, dest *string) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
return b
|
return b
|
||||||
@ -278,7 +270,7 @@ func (b *ValueBinder) Strings(sourceParam string, dest *[]string) *ValueBinder {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustStrings requires parameter values to exist to bind to slice of string variables. Returns error when value does not exist
|
// MustStrings requires parameter values to exist to be bind to slice of string variables. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustStrings(sourceParam string, dest *[]string) *ValueBinder {
|
func (b *ValueBinder) MustStrings(sourceParam string, dest *[]string) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
return b
|
return b
|
||||||
@ -310,7 +302,7 @@ func (b *ValueBinder) BindUnmarshaler(sourceParam string, dest BindUnmarshaler)
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBindUnmarshaler requires parameter value to exist to bind to destination implementing BindUnmarshaler interface.
|
// MustBindUnmarshaler requires parameter value to exist to be bind to destination implementing BindUnmarshaler interface.
|
||||||
// Returns error when value does not exist
|
// Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder {
|
func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
@ -329,85 +321,13 @@ func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshal
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONUnmarshaler binds parameter to destination implementing json.Unmarshaler interface
|
|
||||||
func (b *ValueBinder) JSONUnmarshaler(sourceParam string, dest json.Unmarshaler) *ValueBinder {
|
|
||||||
if b.failFast && b.errors != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp := b.ValueFunc(sourceParam)
|
|
||||||
if tmp == "" {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dest.UnmarshalJSON([]byte(tmp)); err != nil {
|
|
||||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to json.Unmarshaler interface", err))
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustJSONUnmarshaler requires parameter value to exist to bind to destination implementing json.Unmarshaler interface.
|
|
||||||
// Returns error when value does not exist
|
|
||||||
func (b *ValueBinder) MustJSONUnmarshaler(sourceParam string, dest json.Unmarshaler) *ValueBinder {
|
|
||||||
if b.failFast && b.errors != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp := b.ValueFunc(sourceParam)
|
|
||||||
if tmp == "" {
|
|
||||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "required field value is empty", nil))
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dest.UnmarshalJSON([]byte(tmp)); err != nil {
|
|
||||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to json.Unmarshaler interface", err))
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// TextUnmarshaler binds parameter to destination implementing encoding.TextUnmarshaler interface
|
|
||||||
func (b *ValueBinder) TextUnmarshaler(sourceParam string, dest encoding.TextUnmarshaler) *ValueBinder {
|
|
||||||
if b.failFast && b.errors != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp := b.ValueFunc(sourceParam)
|
|
||||||
if tmp == "" {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dest.UnmarshalText([]byte(tmp)); err != nil {
|
|
||||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to encoding.TextUnmarshaler interface", err))
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustTextUnmarshaler requires parameter value to exist to bind to destination implementing encoding.TextUnmarshaler interface.
|
|
||||||
// Returns error when value does not exist
|
|
||||||
func (b *ValueBinder) MustTextUnmarshaler(sourceParam string, dest encoding.TextUnmarshaler) *ValueBinder {
|
|
||||||
if b.failFast && b.errors != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp := b.ValueFunc(sourceParam)
|
|
||||||
if tmp == "" {
|
|
||||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "required field value is empty", nil))
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dest.UnmarshalText([]byte(tmp)); err != nil {
|
|
||||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to encoding.TextUnmarshaler interface", err))
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// BindWithDelimiter binds parameter to destination by suitable conversion function.
|
// BindWithDelimiter binds parameter to destination by suitable conversion function.
|
||||||
// Delimiter is used before conversion to split parameter value to separate values
|
// Delimiter is used before conversion to split parameter value to separate values
|
||||||
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
||||||
return b.bindWithDelimiter(sourceParam, dest, delimiter, false)
|
return b.bindWithDelimiter(sourceParam, dest, delimiter, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBindWithDelimiter requires parameter value to exist to bind destination by suitable conversion function.
|
// MustBindWithDelimiter requires parameter value to exist to be bind destination by suitable conversion function.
|
||||||
// Delimiter is used before conversion to split parameter value to separate values
|
// Delimiter is used before conversion to split parameter value to separate values
|
||||||
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
||||||
return b.bindWithDelimiter(sourceParam, dest, delimiter, true)
|
return b.bindWithDelimiter(sourceParam, dest, delimiter, true)
|
||||||
@ -456,7 +376,7 @@ func (b *ValueBinder) Int64(sourceParam string, dest *int64) *ValueBinder {
|
|||||||
return b.intValue(sourceParam, dest, 64, false)
|
return b.intValue(sourceParam, dest, 64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt64 requires parameter value to exist to bind to int64 variable. Returns error when value does not exist
|
// MustInt64 requires parameter value to exist to be bind to int64 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt64(sourceParam string, dest *int64) *ValueBinder {
|
func (b *ValueBinder) MustInt64(sourceParam string, dest *int64) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 64, true)
|
return b.intValue(sourceParam, dest, 64, true)
|
||||||
}
|
}
|
||||||
@ -466,7 +386,7 @@ func (b *ValueBinder) Int32(sourceParam string, dest *int32) *ValueBinder {
|
|||||||
return b.intValue(sourceParam, dest, 32, false)
|
return b.intValue(sourceParam, dest, 32, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt32 requires parameter value to exist to bind to int32 variable. Returns error when value does not exist
|
// MustInt32 requires parameter value to exist to be bind to int32 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt32(sourceParam string, dest *int32) *ValueBinder {
|
func (b *ValueBinder) MustInt32(sourceParam string, dest *int32) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 32, true)
|
return b.intValue(sourceParam, dest, 32, true)
|
||||||
}
|
}
|
||||||
@ -476,7 +396,7 @@ func (b *ValueBinder) Int16(sourceParam string, dest *int16) *ValueBinder {
|
|||||||
return b.intValue(sourceParam, dest, 16, false)
|
return b.intValue(sourceParam, dest, 16, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt16 requires parameter value to exist to bind to int16 variable. Returns error when value does not exist
|
// MustInt16 requires parameter value to exist to be bind to int16 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt16(sourceParam string, dest *int16) *ValueBinder {
|
func (b *ValueBinder) MustInt16(sourceParam string, dest *int16) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 16, true)
|
return b.intValue(sourceParam, dest, 16, true)
|
||||||
}
|
}
|
||||||
@ -486,7 +406,7 @@ func (b *ValueBinder) Int8(sourceParam string, dest *int8) *ValueBinder {
|
|||||||
return b.intValue(sourceParam, dest, 8, false)
|
return b.intValue(sourceParam, dest, 8, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt8 requires parameter value to exist to bind to int8 variable. Returns error when value does not exist
|
// MustInt8 requires parameter value to exist to be bind to int8 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt8(sourceParam string, dest *int8) *ValueBinder {
|
func (b *ValueBinder) MustInt8(sourceParam string, dest *int8) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 8, true)
|
return b.intValue(sourceParam, dest, 8, true)
|
||||||
}
|
}
|
||||||
@ -496,7 +416,7 @@ func (b *ValueBinder) Int(sourceParam string, dest *int) *ValueBinder {
|
|||||||
return b.intValue(sourceParam, dest, 0, false)
|
return b.intValue(sourceParam, dest, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt requires parameter value to exist to bind to int variable. Returns error when value does not exist
|
// MustInt requires parameter value to exist to be bind to int variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt(sourceParam string, dest *int) *ValueBinder {
|
func (b *ValueBinder) MustInt(sourceParam string, dest *int) *ValueBinder {
|
||||||
return b.intValue(sourceParam, dest, 0, true)
|
return b.intValue(sourceParam, dest, 0, true)
|
||||||
}
|
}
|
||||||
@ -624,7 +544,7 @@ func (b *ValueBinder) Int64s(sourceParam string, dest *[]int64) *ValueBinder {
|
|||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt64s requires parameter value to exist to bind to int64 slice variable. Returns error when value does not exist
|
// MustInt64s requires parameter value to exist to be bind to int64 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt64s(sourceParam string, dest *[]int64) *ValueBinder {
|
func (b *ValueBinder) MustInt64s(sourceParam string, dest *[]int64) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -634,7 +554,7 @@ func (b *ValueBinder) Int32s(sourceParam string, dest *[]int32) *ValueBinder {
|
|||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt32s requires parameter value to exist to bind to int32 slice variable. Returns error when value does not exist
|
// MustInt32s requires parameter value to exist to be bind to int32 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt32s(sourceParam string, dest *[]int32) *ValueBinder {
|
func (b *ValueBinder) MustInt32s(sourceParam string, dest *[]int32) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -644,7 +564,7 @@ func (b *ValueBinder) Int16s(sourceParam string, dest *[]int16) *ValueBinder {
|
|||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt16s requires parameter value to exist to bind to int16 slice variable. Returns error when value does not exist
|
// MustInt16s requires parameter value to exist to be bind to int16 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt16s(sourceParam string, dest *[]int16) *ValueBinder {
|
func (b *ValueBinder) MustInt16s(sourceParam string, dest *[]int16) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -654,7 +574,7 @@ func (b *ValueBinder) Int8s(sourceParam string, dest *[]int8) *ValueBinder {
|
|||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInt8s requires parameter value to exist to bind to int8 slice variable. Returns error when value does not exist
|
// MustInt8s requires parameter value to exist to be bind to int8 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInt8s(sourceParam string, dest *[]int8) *ValueBinder {
|
func (b *ValueBinder) MustInt8s(sourceParam string, dest *[]int8) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -664,7 +584,7 @@ func (b *ValueBinder) Ints(sourceParam string, dest *[]int) *ValueBinder {
|
|||||||
return b.intsValue(sourceParam, dest, false)
|
return b.intsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustInts requires parameter value to exist to bind to int slice variable. Returns error when value does not exist
|
// MustInts requires parameter value to exist to be bind to int slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustInts(sourceParam string, dest *[]int) *ValueBinder {
|
func (b *ValueBinder) MustInts(sourceParam string, dest *[]int) *ValueBinder {
|
||||||
return b.intsValue(sourceParam, dest, true)
|
return b.intsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -674,7 +594,7 @@ func (b *ValueBinder) Uint64(sourceParam string, dest *uint64) *ValueBinder {
|
|||||||
return b.uintValue(sourceParam, dest, 64, false)
|
return b.uintValue(sourceParam, dest, 64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint64 requires parameter value to exist to bind to uint64 variable. Returns error when value does not exist
|
// MustUint64 requires parameter value to exist to be bind to uint64 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint64(sourceParam string, dest *uint64) *ValueBinder {
|
func (b *ValueBinder) MustUint64(sourceParam string, dest *uint64) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 64, true)
|
return b.uintValue(sourceParam, dest, 64, true)
|
||||||
}
|
}
|
||||||
@ -684,7 +604,7 @@ func (b *ValueBinder) Uint32(sourceParam string, dest *uint32) *ValueBinder {
|
|||||||
return b.uintValue(sourceParam, dest, 32, false)
|
return b.uintValue(sourceParam, dest, 32, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint32 requires parameter value to exist to bind to uint32 variable. Returns error when value does not exist
|
// MustUint32 requires parameter value to exist to be bind to uint32 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint32(sourceParam string, dest *uint32) *ValueBinder {
|
func (b *ValueBinder) MustUint32(sourceParam string, dest *uint32) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 32, true)
|
return b.uintValue(sourceParam, dest, 32, true)
|
||||||
}
|
}
|
||||||
@ -694,7 +614,7 @@ func (b *ValueBinder) Uint16(sourceParam string, dest *uint16) *ValueBinder {
|
|||||||
return b.uintValue(sourceParam, dest, 16, false)
|
return b.uintValue(sourceParam, dest, 16, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint16 requires parameter value to exist to bind to uint16 variable. Returns error when value does not exist
|
// MustUint16 requires parameter value to exist to be bind to uint16 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint16(sourceParam string, dest *uint16) *ValueBinder {
|
func (b *ValueBinder) MustUint16(sourceParam string, dest *uint16) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 16, true)
|
return b.uintValue(sourceParam, dest, 16, true)
|
||||||
}
|
}
|
||||||
@ -704,7 +624,7 @@ func (b *ValueBinder) Uint8(sourceParam string, dest *uint8) *ValueBinder {
|
|||||||
return b.uintValue(sourceParam, dest, 8, false)
|
return b.uintValue(sourceParam, dest, 8, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint8 requires parameter value to exist to bind to uint8 variable. Returns error when value does not exist
|
// MustUint8 requires parameter value to exist to be bind to uint8 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint8(sourceParam string, dest *uint8) *ValueBinder {
|
func (b *ValueBinder) MustUint8(sourceParam string, dest *uint8) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 8, true)
|
return b.uintValue(sourceParam, dest, 8, true)
|
||||||
}
|
}
|
||||||
@ -714,7 +634,7 @@ func (b *ValueBinder) Byte(sourceParam string, dest *byte) *ValueBinder {
|
|||||||
return b.uintValue(sourceParam, dest, 8, false)
|
return b.uintValue(sourceParam, dest, 8, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustByte requires parameter value to exist to bind to byte variable. Returns error when value does not exist
|
// MustByte requires parameter value to exist to be bind to byte variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustByte(sourceParam string, dest *byte) *ValueBinder {
|
func (b *ValueBinder) MustByte(sourceParam string, dest *byte) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 8, true)
|
return b.uintValue(sourceParam, dest, 8, true)
|
||||||
}
|
}
|
||||||
@ -724,7 +644,7 @@ func (b *ValueBinder) Uint(sourceParam string, dest *uint) *ValueBinder {
|
|||||||
return b.uintValue(sourceParam, dest, 0, false)
|
return b.uintValue(sourceParam, dest, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint requires parameter value to exist to bind to uint variable. Returns error when value does not exist
|
// MustUint requires parameter value to exist to be bind to uint variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint(sourceParam string, dest *uint) *ValueBinder {
|
func (b *ValueBinder) MustUint(sourceParam string, dest *uint) *ValueBinder {
|
||||||
return b.uintValue(sourceParam, dest, 0, true)
|
return b.uintValue(sourceParam, dest, 0, true)
|
||||||
}
|
}
|
||||||
@ -852,7 +772,7 @@ func (b *ValueBinder) Uint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
|||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint64s requires parameter value to exist to bind to uint64 slice variable. Returns error when value does not exist
|
// MustUint64s requires parameter value to exist to be bind to uint64 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
func (b *ValueBinder) MustUint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -862,7 +782,7 @@ func (b *ValueBinder) Uint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
|||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint32s requires parameter value to exist to bind to uint32 slice variable. Returns error when value does not exist
|
// MustUint32s requires parameter value to exist to be bind to uint32 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
func (b *ValueBinder) MustUint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -872,7 +792,7 @@ func (b *ValueBinder) Uint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
|||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint16s requires parameter value to exist to bind to uint16 slice variable. Returns error when value does not exist
|
// MustUint16s requires parameter value to exist to be bind to uint16 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
func (b *ValueBinder) MustUint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -882,7 +802,7 @@ func (b *ValueBinder) Uint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
|||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUint8s requires parameter value to exist to bind to uint8 slice variable. Returns error when value does not exist
|
// MustUint8s requires parameter value to exist to be bind to uint8 slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
func (b *ValueBinder) MustUint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -892,7 +812,7 @@ func (b *ValueBinder) Uints(sourceParam string, dest *[]uint) *ValueBinder {
|
|||||||
return b.uintsValue(sourceParam, dest, false)
|
return b.uintsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUints requires parameter value to exist to bind to uint slice variable. Returns error when value does not exist
|
// MustUints requires parameter value to exist to be bind to uint slice variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustUints(sourceParam string, dest *[]uint) *ValueBinder {
|
func (b *ValueBinder) MustUints(sourceParam string, dest *[]uint) *ValueBinder {
|
||||||
return b.uintsValue(sourceParam, dest, true)
|
return b.uintsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -902,7 +822,7 @@ func (b *ValueBinder) Bool(sourceParam string, dest *bool) *ValueBinder {
|
|||||||
return b.boolValue(sourceParam, dest, false)
|
return b.boolValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBool requires parameter value to exist to bind to bool variable. Returns error when value does not exist
|
// MustBool requires parameter value to exist to be bind to bool variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustBool(sourceParam string, dest *bool) *ValueBinder {
|
func (b *ValueBinder) MustBool(sourceParam string, dest *bool) *ValueBinder {
|
||||||
return b.boolValue(sourceParam, dest, true)
|
return b.boolValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -967,7 +887,7 @@ func (b *ValueBinder) Bools(sourceParam string, dest *[]bool) *ValueBinder {
|
|||||||
return b.boolsValue(sourceParam, dest, false)
|
return b.boolsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustBools requires parameter values to exist to bind to slice of bool variables. Returns error when values does not exist
|
// MustBools requires parameter values to exist to be bind to slice of bool variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustBools(sourceParam string, dest *[]bool) *ValueBinder {
|
func (b *ValueBinder) MustBools(sourceParam string, dest *[]bool) *ValueBinder {
|
||||||
return b.boolsValue(sourceParam, dest, true)
|
return b.boolsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -977,7 +897,7 @@ func (b *ValueBinder) Float64(sourceParam string, dest *float64) *ValueBinder {
|
|||||||
return b.floatValue(sourceParam, dest, 64, false)
|
return b.floatValue(sourceParam, dest, 64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat64 requires parameter value to exist to bind to float64 variable. Returns error when value does not exist
|
// MustFloat64 requires parameter value to exist to be bind to float64 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustFloat64(sourceParam string, dest *float64) *ValueBinder {
|
func (b *ValueBinder) MustFloat64(sourceParam string, dest *float64) *ValueBinder {
|
||||||
return b.floatValue(sourceParam, dest, 64, true)
|
return b.floatValue(sourceParam, dest, 64, true)
|
||||||
}
|
}
|
||||||
@ -987,7 +907,7 @@ func (b *ValueBinder) Float32(sourceParam string, dest *float32) *ValueBinder {
|
|||||||
return b.floatValue(sourceParam, dest, 32, false)
|
return b.floatValue(sourceParam, dest, 32, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat32 requires parameter value to exist to bind to float32 variable. Returns error when value does not exist
|
// MustFloat32 requires parameter value to exist to be bind to float32 variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustFloat32(sourceParam string, dest *float32) *ValueBinder {
|
func (b *ValueBinder) MustFloat32(sourceParam string, dest *float32) *ValueBinder {
|
||||||
return b.floatValue(sourceParam, dest, 32, true)
|
return b.floatValue(sourceParam, dest, 32, true)
|
||||||
}
|
}
|
||||||
@ -1072,7 +992,7 @@ func (b *ValueBinder) Float64s(sourceParam string, dest *[]float64) *ValueBinder
|
|||||||
return b.floatsValue(sourceParam, dest, false)
|
return b.floatsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat64s requires parameter values to exist to bind to slice of float64 variables. Returns error when values does not exist
|
// MustFloat64s requires parameter values to exist to be bind to slice of float64 variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustFloat64s(sourceParam string, dest *[]float64) *ValueBinder {
|
func (b *ValueBinder) MustFloat64s(sourceParam string, dest *[]float64) *ValueBinder {
|
||||||
return b.floatsValue(sourceParam, dest, true)
|
return b.floatsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -1082,7 +1002,7 @@ func (b *ValueBinder) Float32s(sourceParam string, dest *[]float32) *ValueBinder
|
|||||||
return b.floatsValue(sourceParam, dest, false)
|
return b.floatsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustFloat32s requires parameter values to exist to bind to slice of float32 variables. Returns error when values does not exist
|
// MustFloat32s requires parameter values to exist to be bind to slice of float32 variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustFloat32s(sourceParam string, dest *[]float32) *ValueBinder {
|
func (b *ValueBinder) MustFloat32s(sourceParam string, dest *[]float32) *ValueBinder {
|
||||||
return b.floatsValue(sourceParam, dest, true)
|
return b.floatsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -1092,7 +1012,7 @@ func (b *ValueBinder) Time(sourceParam string, dest *time.Time, layout string) *
|
|||||||
return b.time(sourceParam, dest, layout, false)
|
return b.time(sourceParam, dest, layout, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustTime requires parameter value to exist to bind to time.Time variable. Returns error when value does not exist
|
// MustTime requires parameter value to exist to be bind to time.Time variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustTime(sourceParam string, dest *time.Time, layout string) *ValueBinder {
|
func (b *ValueBinder) MustTime(sourceParam string, dest *time.Time, layout string) *ValueBinder {
|
||||||
return b.time(sourceParam, dest, layout, true)
|
return b.time(sourceParam, dest, layout, true)
|
||||||
}
|
}
|
||||||
@ -1123,7 +1043,7 @@ func (b *ValueBinder) Times(sourceParam string, dest *[]time.Time, layout string
|
|||||||
return b.times(sourceParam, dest, layout, false)
|
return b.times(sourceParam, dest, layout, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustTimes requires parameter values to exist to bind to slice of time.Time variables. Returns error when values does not exist
|
// MustTimes requires parameter values to exist to be bind to slice of time.Time variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustTimes(sourceParam string, dest *[]time.Time, layout string) *ValueBinder {
|
func (b *ValueBinder) MustTimes(sourceParam string, dest *[]time.Time, layout string) *ValueBinder {
|
||||||
return b.times(sourceParam, dest, layout, true)
|
return b.times(sourceParam, dest, layout, true)
|
||||||
}
|
}
|
||||||
@ -1164,7 +1084,7 @@ func (b *ValueBinder) Duration(sourceParam string, dest *time.Duration) *ValueBi
|
|||||||
return b.duration(sourceParam, dest, false)
|
return b.duration(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustDuration requires parameter value to exist to bind to time.Duration variable. Returns error when value does not exist
|
// MustDuration requires parameter value to exist to be bind to time.Duration variable. Returns error when value does not exist
|
||||||
func (b *ValueBinder) MustDuration(sourceParam string, dest *time.Duration) *ValueBinder {
|
func (b *ValueBinder) MustDuration(sourceParam string, dest *time.Duration) *ValueBinder {
|
||||||
return b.duration(sourceParam, dest, true)
|
return b.duration(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -1195,7 +1115,7 @@ func (b *ValueBinder) Durations(sourceParam string, dest *[]time.Duration) *Valu
|
|||||||
return b.durationsValue(sourceParam, dest, false)
|
return b.durationsValue(sourceParam, dest, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustDurations requires parameter values to exist to bind to slice of time.Duration variables. Returns error when values does not exist
|
// MustDurations requires parameter values to exist to be bind to slice of time.Duration variables. Returns error when values does not exist
|
||||||
func (b *ValueBinder) MustDurations(sourceParam string, dest *[]time.Duration) *ValueBinder {
|
func (b *ValueBinder) MustDurations(sourceParam string, dest *[]time.Duration) *ValueBinder {
|
||||||
return b.durationsValue(sourceParam, dest, true)
|
return b.durationsValue(sourceParam, dest, true)
|
||||||
}
|
}
|
||||||
@ -1239,57 +1159,36 @@ func (b *ValueBinder) durations(sourceParam string, values []string, dest *[]tim
|
|||||||
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, time.Second)
|
return b.unixTime(sourceParam, dest, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUnixTime requires parameter value to exist to bind to time.Duration variable (in local time corresponding
|
// MustUnixTime requires parameter value to exist to be bind to time.Duration variable (in local Time corresponding
|
||||||
// to the given Unix time). Returns error when value does not exist.
|
// to the given Unix time). Returns error when value does not exist.
|
||||||
//
|
//
|
||||||
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, time.Second)
|
return b.unixTime(sourceParam, dest, true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnixTimeMilli binds parameter to time.Time variable (in local time corresponding to the given Unix time in millisecond precision).
|
// UnixTimeNano binds parameter to time.Time variable (in local Time corresponding to the given Unix time in nano second precision).
|
||||||
//
|
|
||||||
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
|
||||||
//
|
|
||||||
// Note:
|
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
|
||||||
func (b *ValueBinder) UnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
|
||||||
return b.unixTime(sourceParam, dest, false, time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustUnixTimeMilli requires parameter value to exist to bind to time.Duration variable (in local time corresponding
|
|
||||||
// to the given Unix time in millisecond precision). Returns error when value does not exist.
|
|
||||||
//
|
|
||||||
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
|
||||||
//
|
|
||||||
// Note:
|
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
|
||||||
func (b *ValueBinder) MustUnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
|
||||||
return b.unixTime(sourceParam, dest, true, time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnixTimeNano binds parameter to time.Time variable (in local time corresponding to the given Unix time in nanosecond precision).
|
|
||||||
//
|
//
|
||||||
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
||||||
// Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00
|
// Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00
|
||||||
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
// - Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||||
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, time.Nanosecond)
|
return b.unixTime(sourceParam, dest, false, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustUnixTimeNano requires parameter value to exist to bind to time.Duration variable (in local Time corresponding
|
// MustUnixTimeNano requires parameter value to exist to be bind to time.Duration variable (in local Time corresponding
|
||||||
// to the given Unix time value in nano second precision). Returns error when value does not exist.
|
// to the given Unix time value in nano second precision). Returns error when value does not exist.
|
||||||
//
|
//
|
||||||
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
||||||
@ -1297,13 +1196,13 @@ func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBi
|
|||||||
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
// - Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||||
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, time.Nanosecond)
|
return b.unixTime(sourceParam, dest, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExist bool, precision time.Duration) *ValueBinder {
|
func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExist bool, isNano bool) *ValueBinder {
|
||||||
if b.failFast && b.errors != nil {
|
if b.failFast && b.errors != nil {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
@ -1322,13 +1221,10 @@ func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExi
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
switch precision {
|
if isNano {
|
||||||
case time.Second:
|
|
||||||
*dest = time.Unix(n, 0)
|
|
||||||
case time.Millisecond:
|
|
||||||
*dest = time.UnixMilli(n)
|
|
||||||
case time.Nanosecond:
|
|
||||||
*dest = time.Unix(0, n)
|
*dest = time.Unix(0, n)
|
||||||
|
} else {
|
||||||
|
*dest = time.Unix(n, 0)
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
328
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
328
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -16,216 +13,200 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context represents the context of the current HTTP request. It holds request and
|
type (
|
||||||
// response objects, path, path parameters, data and registered handler.
|
// Context represents the context of the current HTTP request. It holds request and
|
||||||
type Context interface {
|
// response objects, path, path parameters, data and registered handler.
|
||||||
// Request returns `*http.Request`.
|
Context interface {
|
||||||
Request() *http.Request
|
// Request returns `*http.Request`.
|
||||||
|
Request() *http.Request
|
||||||
|
|
||||||
// SetRequest sets `*http.Request`.
|
// SetRequest sets `*http.Request`.
|
||||||
SetRequest(r *http.Request)
|
SetRequest(r *http.Request)
|
||||||
|
|
||||||
// SetResponse sets `*Response`.
|
// SetResponse sets `*Response`.
|
||||||
SetResponse(r *Response)
|
SetResponse(r *Response)
|
||||||
|
|
||||||
// Response returns `*Response`.
|
// Response returns `*Response`.
|
||||||
Response() *Response
|
Response() *Response
|
||||||
|
|
||||||
// IsTLS returns true if HTTP connection is TLS otherwise false.
|
// IsTLS returns true if HTTP connection is TLS otherwise false.
|
||||||
IsTLS() bool
|
IsTLS() bool
|
||||||
|
|
||||||
// IsWebSocket returns true if HTTP connection is WebSocket otherwise false.
|
// IsWebSocket returns true if HTTP connection is WebSocket otherwise false.
|
||||||
IsWebSocket() bool
|
IsWebSocket() bool
|
||||||
|
|
||||||
// Scheme returns the HTTP protocol scheme, `http` or `https`.
|
// Scheme returns the HTTP protocol scheme, `http` or `https`.
|
||||||
Scheme() string
|
Scheme() string
|
||||||
|
|
||||||
// RealIP returns the client's network address based on `X-Forwarded-For`
|
// RealIP returns the client's network address based on `X-Forwarded-For`
|
||||||
// or `X-Real-IP` request header.
|
// or `X-Real-IP` request header.
|
||||||
// The behavior can be configured using `Echo#IPExtractor`.
|
// The behavior can be configured using `Echo#IPExtractor`.
|
||||||
RealIP() string
|
RealIP() string
|
||||||
|
|
||||||
// Path returns the registered path for the handler.
|
// Path returns the registered path for the handler.
|
||||||
Path() string
|
Path() string
|
||||||
|
|
||||||
// SetPath sets the registered path for the handler.
|
// SetPath sets the registered path for the handler.
|
||||||
SetPath(p string)
|
SetPath(p string)
|
||||||
|
|
||||||
// Param returns path parameter by name.
|
// Param returns path parameter by name.
|
||||||
Param(name string) string
|
Param(name string) string
|
||||||
|
|
||||||
// ParamNames returns path parameter names.
|
// ParamNames returns path parameter names.
|
||||||
ParamNames() []string
|
ParamNames() []string
|
||||||
|
|
||||||
// SetParamNames sets path parameter names.
|
// SetParamNames sets path parameter names.
|
||||||
SetParamNames(names ...string)
|
SetParamNames(names ...string)
|
||||||
|
|
||||||
// ParamValues returns path parameter values.
|
// ParamValues returns path parameter values.
|
||||||
ParamValues() []string
|
ParamValues() []string
|
||||||
|
|
||||||
// SetParamValues sets path parameter values.
|
// SetParamValues sets path parameter values.
|
||||||
SetParamValues(values ...string)
|
SetParamValues(values ...string)
|
||||||
|
|
||||||
// QueryParam returns the query param for the provided name.
|
// QueryParam returns the query param for the provided name.
|
||||||
QueryParam(name string) string
|
QueryParam(name string) string
|
||||||
|
|
||||||
// QueryParams returns the query parameters as `url.Values`.
|
// QueryParams returns the query parameters as `url.Values`.
|
||||||
QueryParams() url.Values
|
QueryParams() url.Values
|
||||||
|
|
||||||
// QueryString returns the URL query string.
|
// QueryString returns the URL query string.
|
||||||
QueryString() string
|
QueryString() string
|
||||||
|
|
||||||
// FormValue returns the form field value for the provided name.
|
// FormValue returns the form field value for the provided name.
|
||||||
FormValue(name string) string
|
FormValue(name string) string
|
||||||
|
|
||||||
// FormParams returns the form parameters as `url.Values`.
|
// FormParams returns the form parameters as `url.Values`.
|
||||||
FormParams() (url.Values, error)
|
FormParams() (url.Values, error)
|
||||||
|
|
||||||
// FormFile returns the multipart form file for the provided name.
|
// FormFile returns the multipart form file for the provided name.
|
||||||
FormFile(name string) (*multipart.FileHeader, error)
|
FormFile(name string) (*multipart.FileHeader, error)
|
||||||
|
|
||||||
// MultipartForm returns the multipart form.
|
// MultipartForm returns the multipart form.
|
||||||
MultipartForm() (*multipart.Form, error)
|
MultipartForm() (*multipart.Form, error)
|
||||||
|
|
||||||
// Cookie returns the named cookie provided in the request.
|
// Cookie returns the named cookie provided in the request.
|
||||||
Cookie(name string) (*http.Cookie, error)
|
Cookie(name string) (*http.Cookie, error)
|
||||||
|
|
||||||
// SetCookie adds a `Set-Cookie` header in HTTP response.
|
// SetCookie adds a `Set-Cookie` header in HTTP response.
|
||||||
SetCookie(cookie *http.Cookie)
|
SetCookie(cookie *http.Cookie)
|
||||||
|
|
||||||
// Cookies returns the HTTP cookies sent with the request.
|
// Cookies returns the HTTP cookies sent with the request.
|
||||||
Cookies() []*http.Cookie
|
Cookies() []*http.Cookie
|
||||||
|
|
||||||
// Get retrieves data from the context.
|
// Get retrieves data from the context.
|
||||||
Get(key string) interface{}
|
Get(key string) interface{}
|
||||||
|
|
||||||
// Set saves data in the context.
|
// Set saves data in the context.
|
||||||
Set(key string, val interface{})
|
Set(key string, val interface{})
|
||||||
|
|
||||||
// Bind binds path params, query params and the request body into provided type `i`. The default binder
|
// Bind binds the request body into provided type `i`. The default binder
|
||||||
// binds body based on Content-Type header.
|
// does it based on Content-Type header.
|
||||||
Bind(i interface{}) error
|
Bind(i interface{}) error
|
||||||
|
|
||||||
// Validate validates provided `i`. It is usually called after `Context#Bind()`.
|
// Validate validates provided `i`. It is usually called after `Context#Bind()`.
|
||||||
// Validator must be registered using `Echo#Validator`.
|
// Validator must be registered using `Echo#Validator`.
|
||||||
Validate(i interface{}) error
|
Validate(i interface{}) error
|
||||||
|
|
||||||
// Render renders a template with data and sends a text/html response with status
|
// Render renders a template with data and sends a text/html response with status
|
||||||
// code. Renderer must be registered using `Echo.Renderer`.
|
// code. Renderer must be registered using `Echo.Renderer`.
|
||||||
Render(code int, name string, data interface{}) error
|
Render(code int, name string, data interface{}) error
|
||||||
|
|
||||||
// HTML sends an HTTP response with status code.
|
// HTML sends an HTTP response with status code.
|
||||||
HTML(code int, html string) error
|
HTML(code int, html string) error
|
||||||
|
|
||||||
// HTMLBlob sends an HTTP blob response with status code.
|
// HTMLBlob sends an HTTP blob response with status code.
|
||||||
HTMLBlob(code int, b []byte) error
|
HTMLBlob(code int, b []byte) error
|
||||||
|
|
||||||
// String sends a string response with status code.
|
// String sends a string response with status code.
|
||||||
String(code int, s string) error
|
String(code int, s string) error
|
||||||
|
|
||||||
// JSON sends a JSON response with status code.
|
// JSON sends a JSON response with status code.
|
||||||
JSON(code int, i interface{}) error
|
JSON(code int, i interface{}) error
|
||||||
|
|
||||||
// JSONPretty sends a pretty-print JSON with status code.
|
// JSONPretty sends a pretty-print JSON with status code.
|
||||||
JSONPretty(code int, i interface{}, indent string) error
|
JSONPretty(code int, i interface{}, indent string) error
|
||||||
|
|
||||||
// JSONBlob sends a JSON blob response with status code.
|
// JSONBlob sends a JSON blob response with status code.
|
||||||
JSONBlob(code int, b []byte) error
|
JSONBlob(code int, b []byte) error
|
||||||
|
|
||||||
// JSONP sends a JSONP response with status code. It uses `callback` to construct
|
// JSONP sends a JSONP response with status code. It uses `callback` to construct
|
||||||
// the JSONP payload.
|
// the JSONP payload.
|
||||||
JSONP(code int, callback string, i interface{}) error
|
JSONP(code int, callback string, i interface{}) error
|
||||||
|
|
||||||
// JSONPBlob sends a JSONP blob response with status code. It uses `callback`
|
// JSONPBlob sends a JSONP blob response with status code. It uses `callback`
|
||||||
// to construct the JSONP payload.
|
// to construct the JSONP payload.
|
||||||
JSONPBlob(code int, callback string, b []byte) error
|
JSONPBlob(code int, callback string, b []byte) error
|
||||||
|
|
||||||
// XML sends an XML response with status code.
|
// XML sends an XML response with status code.
|
||||||
XML(code int, i interface{}) error
|
XML(code int, i interface{}) error
|
||||||
|
|
||||||
// XMLPretty sends a pretty-print XML with status code.
|
// XMLPretty sends a pretty-print XML with status code.
|
||||||
XMLPretty(code int, i interface{}, indent string) error
|
XMLPretty(code int, i interface{}, indent string) error
|
||||||
|
|
||||||
// XMLBlob sends an XML blob response with status code.
|
// XMLBlob sends an XML blob response with status code.
|
||||||
XMLBlob(code int, b []byte) error
|
XMLBlob(code int, b []byte) error
|
||||||
|
|
||||||
// Blob sends a blob response with status code and content type.
|
// Blob sends a blob response with status code and content type.
|
||||||
Blob(code int, contentType string, b []byte) error
|
Blob(code int, contentType string, b []byte) error
|
||||||
|
|
||||||
// Stream sends a streaming response with status code and content type.
|
// Stream sends a streaming response with status code and content type.
|
||||||
Stream(code int, contentType string, r io.Reader) error
|
Stream(code int, contentType string, r io.Reader) error
|
||||||
|
|
||||||
// File sends a response with the content of the file.
|
// File sends a response with the content of the file.
|
||||||
File(file string) error
|
File(file string) error
|
||||||
|
|
||||||
// Attachment sends a response as attachment, prompting client to save the
|
// Attachment sends a response as attachment, prompting client to save the
|
||||||
// file.
|
// file.
|
||||||
Attachment(file string, name string) error
|
Attachment(file string, name string) error
|
||||||
|
|
||||||
// Inline sends a response as inline, opening the file in the browser.
|
// Inline sends a response as inline, opening the file in the browser.
|
||||||
Inline(file string, name string) error
|
Inline(file string, name string) error
|
||||||
|
|
||||||
// NoContent sends a response with no body and a status code.
|
// NoContent sends a response with no body and a status code.
|
||||||
NoContent(code int) error
|
NoContent(code int) error
|
||||||
|
|
||||||
// Redirect redirects the request to a provided URL with status code.
|
// Redirect redirects the request to a provided URL with status code.
|
||||||
Redirect(code int, url string) error
|
Redirect(code int, url string) error
|
||||||
|
|
||||||
// Error invokes the registered global HTTP error handler. Generally used by middleware.
|
// Error invokes the registered HTTP error handler. Generally used by middleware.
|
||||||
// A side-effect of calling global error handler is that now Response has been committed (sent to the client) and
|
Error(err error)
|
||||||
// middlewares up in chain can not change Response status code or Response body anymore.
|
|
||||||
//
|
|
||||||
// Avoid using this method in handlers as no middleware will be able to effectively handle errors after that.
|
|
||||||
Error(err error)
|
|
||||||
|
|
||||||
// Handler returns the matched handler by router.
|
// Handler returns the matched handler by router.
|
||||||
Handler() HandlerFunc
|
Handler() HandlerFunc
|
||||||
|
|
||||||
// SetHandler sets the matched handler by router.
|
// SetHandler sets the matched handler by router.
|
||||||
SetHandler(h HandlerFunc)
|
SetHandler(h HandlerFunc)
|
||||||
|
|
||||||
// Logger returns the `Logger` instance.
|
// Logger returns the `Logger` instance.
|
||||||
Logger() Logger
|
Logger() Logger
|
||||||
|
|
||||||
// SetLogger Set the logger
|
// Set the logger
|
||||||
SetLogger(l Logger)
|
SetLogger(l Logger)
|
||||||
|
|
||||||
// Echo returns the `Echo` instance.
|
// Echo returns the `Echo` instance.
|
||||||
Echo() *Echo
|
Echo() *Echo
|
||||||
|
|
||||||
// Reset resets the context after request completes. It must be called along
|
// Reset resets the context after request completes. It must be called along
|
||||||
// with `Echo#AcquireContext()` and `Echo#ReleaseContext()`.
|
// with `Echo#AcquireContext()` and `Echo#ReleaseContext()`.
|
||||||
// See `Echo#ServeHTTP()`
|
// See `Echo#ServeHTTP()`
|
||||||
Reset(r *http.Request, w http.ResponseWriter)
|
Reset(r *http.Request, w http.ResponseWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
type context struct {
|
context struct {
|
||||||
request *http.Request
|
request *http.Request
|
||||||
response *Response
|
response *Response
|
||||||
query url.Values
|
path string
|
||||||
echo *Echo
|
pnames []string
|
||||||
logger Logger
|
pvalues []string
|
||||||
|
query url.Values
|
||||||
store Map
|
handler HandlerFunc
|
||||||
lock sync.RWMutex
|
store Map
|
||||||
|
echo *Echo
|
||||||
// following fields are set by Router
|
logger Logger
|
||||||
|
lock sync.RWMutex
|
||||||
// path is route path that Router matched. It is empty string where there is no route match.
|
}
|
||||||
// Route registered with RouteNotFound is considered as a match and path therefore is not empty.
|
)
|
||||||
path string
|
|
||||||
|
|
||||||
// pnames length is tied to param count for the matched route
|
|
||||||
pnames []string
|
|
||||||
|
|
||||||
// Usually echo.Echo is sizing pvalues but there could be user created middlewares that decide to
|
|
||||||
// overwrite parameter by calling SetParamNames + SetParamValues.
|
|
||||||
// When echo.Echo allocated that slice it length/capacity is tied to echo.Echo.maxParam value.
|
|
||||||
//
|
|
||||||
// It is important that pvalues size is always equal or bigger to pnames length.
|
|
||||||
pvalues []string
|
|
||||||
handler HandlerFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
|
// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
|
||||||
@ -301,16 +282,11 @@ func (c *context) RealIP() string {
|
|||||||
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
|
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
|
||||||
i := strings.IndexAny(ip, ",")
|
i := strings.IndexAny(ip, ",")
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
xffip := strings.TrimSpace(ip[:i])
|
return strings.TrimSpace(ip[:i])
|
||||||
xffip = strings.TrimPrefix(xffip, "[")
|
|
||||||
xffip = strings.TrimSuffix(xffip, "]")
|
|
||||||
return xffip
|
|
||||||
}
|
}
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
|
if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
|
||||||
ip = strings.TrimPrefix(ip, "[")
|
|
||||||
ip = strings.TrimSuffix(ip, "]")
|
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
ra, _, _ := net.SplitHostPort(c.request.RemoteAddr)
|
ra, _, _ := net.SplitHostPort(c.request.RemoteAddr)
|
||||||
@ -344,9 +320,13 @@ func (c *context) SetParamNames(names ...string) {
|
|||||||
c.pnames = names
|
c.pnames = names
|
||||||
|
|
||||||
l := len(names)
|
l := len(names)
|
||||||
|
if *c.echo.maxParam < l {
|
||||||
|
*c.echo.maxParam = l
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.pvalues) < l {
|
if len(c.pvalues) < l {
|
||||||
// Keeping the old pvalues just for backward compatibility, but it sounds that doesn't make sense to keep them,
|
// Keeping the old pvalues just for backward compatibility, but it sounds that doesn't make sense to keep them,
|
||||||
// probably those values will be overridden in a Context#SetParamValues
|
// probably those values will be overriden in a Context#SetParamValues
|
||||||
newPvalues := make([]string, l)
|
newPvalues := make([]string, l)
|
||||||
copy(newPvalues, c.pvalues)
|
copy(newPvalues, c.pvalues)
|
||||||
c.pvalues = newPvalues
|
c.pvalues = newPvalues
|
||||||
@ -358,11 +338,11 @@ func (c *context) ParamValues() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) SetParamValues(values ...string) {
|
func (c *context) SetParamValues(values ...string) {
|
||||||
// NOTE: Don't just set c.pvalues = values, because it has to have length c.echo.maxParam (or bigger) at all times
|
// NOTE: Don't just set c.pvalues = values, because it has to have length c.echo.maxParam at all times
|
||||||
// It will brake the Router#Find code
|
// It will brake the Router#Find code
|
||||||
limit := len(values)
|
limit := len(values)
|
||||||
if limit > len(c.pvalues) {
|
if limit > *c.echo.maxParam {
|
||||||
c.pvalues = make([]string, limit)
|
limit = *c.echo.maxParam
|
||||||
}
|
}
|
||||||
for i := 0; i < limit; i++ {
|
for i := 0; i < limit; i++ {
|
||||||
c.pvalues[i] = values[i]
|
c.pvalues[i] = values[i]
|
||||||
@ -500,7 +480,7 @@ func (c *context) jsonPBlob(code int, callback string, i interface{}) (err error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) json(code int, i interface{}, indent string) error {
|
func (c *context) json(code int, i interface{}, indent string) error {
|
||||||
c.writeContentType(MIMEApplicationJSON)
|
c.writeContentType(MIMEApplicationJSONCharsetUTF8)
|
||||||
c.response.Status = code
|
c.response.Status = code
|
||||||
return c.echo.JSONSerializer.Serialize(c, i, indent)
|
return c.echo.JSONSerializer.Serialize(c, i, indent)
|
||||||
}
|
}
|
||||||
@ -518,7 +498,7 @@ func (c *context) JSONPretty(code int, i interface{}, indent string) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) JSONBlob(code int, b []byte) (err error) {
|
func (c *context) JSONBlob(code int, b []byte) (err error) {
|
||||||
return c.Blob(code, MIMEApplicationJSON, b)
|
return c.Blob(code, MIMEApplicationJSONCharsetUTF8, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
||||||
@ -595,10 +575,8 @@ func (c *context) Inline(file, name string) error {
|
|||||||
return c.contentDisposition(file, name, "inline")
|
return c.contentDisposition(file, name, "inline")
|
||||||
}
|
}
|
||||||
|
|
||||||
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
|
|
||||||
|
|
||||||
func (c *context) contentDisposition(file, name, dispositionType string) error {
|
func (c *context) contentDisposition(file, name, dispositionType string) error {
|
||||||
c.response.Header().Set(HeaderContentDisposition, fmt.Sprintf(`%s; filename="%s"`, dispositionType, quoteEscaper.Replace(name)))
|
c.response.Header().Set(HeaderContentDisposition, fmt.Sprintf("%s; filename=%q", dispositionType, name))
|
||||||
return c.File(file)
|
return c.File(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,8 +631,8 @@ func (c *context) Reset(r *http.Request, w http.ResponseWriter) {
|
|||||||
c.path = ""
|
c.path = ""
|
||||||
c.pnames = nil
|
c.pnames = nil
|
||||||
c.logger = nil
|
c.logger = nil
|
||||||
// NOTE: Don't reset because it has to have length c.echo.maxParam (or bigger) at all times
|
// NOTE: Don't reset because it has to have length c.echo.maxParam at all times
|
||||||
for i := 0; i < len(c.pvalues); i++ {
|
for i := 0; i < *c.echo.maxParam; i++ {
|
||||||
c.pvalues[i] = ""
|
c.pvalues[i] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
vendor/github.com/labstack/echo/v4/context_fs.go
generated
vendored
43
vendor/github.com/labstack/echo/v4/context_fs.go
generated
vendored
@ -1,52 +1,33 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
//go:build !go1.16
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
// +build !go1.16
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *context) File(file string) error {
|
func (c *context) File(file string) (err error) {
|
||||||
return fsFile(c, file, c.echo.Filesystem)
|
f, err := os.Open(file)
|
||||||
}
|
|
||||||
|
|
||||||
// FileFS serves file from given file system.
|
|
||||||
//
|
|
||||||
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
|
|
||||||
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
|
|
||||||
// including `assets/images` as their prefix.
|
|
||||||
func (c *context) FileFS(file string, filesystem fs.FS) error {
|
|
||||||
return fsFile(c, file, filesystem)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fsFile(c Context, file string, filesystem fs.FS) error {
|
|
||||||
f, err := filesystem.Open(file)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrNotFound
|
return NotFoundHandler(c)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
fi, _ := f.Stat()
|
fi, _ := f.Stat()
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
file = filepath.ToSlash(filepath.Join(file, indexPage)) // ToSlash is necessary for Windows. fs.Open and os.Open are different in that aspect.
|
file = filepath.Join(file, indexPage)
|
||||||
f, err = filesystem.Open(file)
|
f, err = os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrNotFound
|
return NotFoundHandler(c)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if fi, err = f.Stat(); err != nil {
|
if fi, err = f.Stat(); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ff, ok := f.(io.ReadSeeker)
|
http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), f)
|
||||||
if !ok {
|
return
|
||||||
return errors.New("file does not implement io.ReadSeeker")
|
|
||||||
}
|
|
||||||
http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), ff)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
52
vendor/github.com/labstack/echo/v4/context_fs_go1.16.go
generated
vendored
Normal file
52
vendor/github.com/labstack/echo/v4/context_fs_go1.16.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//go:build go1.16
|
||||||
|
// +build go1.16
|
||||||
|
|
||||||
|
package echo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *context) File(file string) error {
|
||||||
|
return fsFile(c, file, c.echo.Filesystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileFS serves file from given file system.
|
||||||
|
//
|
||||||
|
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
|
||||||
|
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
|
||||||
|
// including `assets/images` as their prefix.
|
||||||
|
func (c *context) FileFS(file string, filesystem fs.FS) error {
|
||||||
|
return fsFile(c, file, filesystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fsFile(c Context, file string, filesystem fs.FS) error {
|
||||||
|
f, err := filesystem.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
fi, _ := f.Stat()
|
||||||
|
if fi.IsDir() {
|
||||||
|
file = filepath.ToSlash(filepath.Join(file, indexPage)) // ToSlash is necessary for Windows. fs.Open and os.Open are different in that aspect.
|
||||||
|
f, err = filesystem.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
if fi, err = f.Stat(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ff, ok := f.(io.ReadSeeker)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("file does not implement io.ReadSeeker")
|
||||||
|
}
|
||||||
|
http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), ff)
|
||||||
|
return nil
|
||||||
|
}
|
439
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
439
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@ -1,55 +1,52 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package echo implements high performance, minimalist Go web framework.
|
Package echo implements high performance, minimalist Go web framework.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler
|
// Handler
|
||||||
func hello(c echo.Context) error {
|
func hello(c echo.Context) error {
|
||||||
return c.String(http.StatusOK, "Hello, World!")
|
return c.String(http.StatusOK, "Hello, World!")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Echo instance
|
// Echo instance
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
e.Use(middleware.Logger())
|
e.Use(middleware.Logger())
|
||||||
e.Use(middleware.Recover())
|
e.Use(middleware.Recover())
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
e.GET("/", hello)
|
e.GET("/", hello)
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
e.Logger.Fatal(e.Start(":1323"))
|
e.Logger.Fatal(e.Start(":1323"))
|
||||||
}
|
}
|
||||||
|
|
||||||
Learn more at https://echo.labstack.com
|
Learn more at https://echo.labstack.com
|
||||||
*/
|
*/
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
stdContext "context"
|
stdContext "context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
stdLog "log"
|
stdLog "log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
@ -63,95 +60,86 @@ import (
|
|||||||
"golang.org/x/net/http2/h2c"
|
"golang.org/x/net/http2/h2c"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Echo is the top-level framework instance.
|
type (
|
||||||
//
|
// Echo is the top-level framework instance.
|
||||||
// Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
|
Echo struct {
|
||||||
// fields from handlers/middlewares and changing field values at the same time leads to data-races.
|
filesystem
|
||||||
// Adding new routes after the server has been started is also not safe!
|
common
|
||||||
type Echo struct {
|
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
||||||
filesystem
|
// listener address info (on which interface/port was listener binded) without having data races.
|
||||||
common
|
startupMutex sync.RWMutex
|
||||||
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
StdLogger *stdLog.Logger
|
||||||
// listener address info (on which interface/port was listener bound) without having data races.
|
colorer *color.Color
|
||||||
startupMutex sync.RWMutex
|
premiddleware []MiddlewareFunc
|
||||||
colorer *color.Color
|
middleware []MiddlewareFunc
|
||||||
|
maxParam *int
|
||||||
|
router *Router
|
||||||
|
routers map[string]*Router
|
||||||
|
pool sync.Pool
|
||||||
|
Server *http.Server
|
||||||
|
TLSServer *http.Server
|
||||||
|
Listener net.Listener
|
||||||
|
TLSListener net.Listener
|
||||||
|
AutoTLSManager autocert.Manager
|
||||||
|
DisableHTTP2 bool
|
||||||
|
Debug bool
|
||||||
|
HideBanner bool
|
||||||
|
HidePort bool
|
||||||
|
HTTPErrorHandler HTTPErrorHandler
|
||||||
|
Binder Binder
|
||||||
|
JSONSerializer JSONSerializer
|
||||||
|
Validator Validator
|
||||||
|
Renderer Renderer
|
||||||
|
Logger Logger
|
||||||
|
IPExtractor IPExtractor
|
||||||
|
ListenerNetwork string
|
||||||
|
}
|
||||||
|
|
||||||
// premiddleware are middlewares that are run before routing is done. In case a pre-middleware returns
|
// Route contains a handler and information for matching against requests.
|
||||||
// an error the router is not executed and the request will end up in the global error handler.
|
Route struct {
|
||||||
premiddleware []MiddlewareFunc
|
Method string `json:"method"`
|
||||||
middleware []MiddlewareFunc
|
Path string `json:"path"`
|
||||||
maxParam *int
|
Name string `json:"name"`
|
||||||
router *Router
|
}
|
||||||
routers map[string]*Router
|
|
||||||
pool sync.Pool
|
|
||||||
|
|
||||||
StdLogger *stdLog.Logger
|
// HTTPError represents an error that occurred while handling a request.
|
||||||
Server *http.Server
|
HTTPError struct {
|
||||||
TLSServer *http.Server
|
Code int `json:"-"`
|
||||||
Listener net.Listener
|
Message interface{} `json:"message"`
|
||||||
TLSListener net.Listener
|
Internal error `json:"-"` // Stores the error returned by an external dependency
|
||||||
AutoTLSManager autocert.Manager
|
}
|
||||||
DisableHTTP2 bool
|
|
||||||
Debug bool
|
|
||||||
HideBanner bool
|
|
||||||
HidePort bool
|
|
||||||
HTTPErrorHandler HTTPErrorHandler
|
|
||||||
Binder Binder
|
|
||||||
JSONSerializer JSONSerializer
|
|
||||||
Validator Validator
|
|
||||||
Renderer Renderer
|
|
||||||
Logger Logger
|
|
||||||
IPExtractor IPExtractor
|
|
||||||
ListenerNetwork string
|
|
||||||
|
|
||||||
// OnAddRouteHandler is called when Echo adds new route to specific host router.
|
// MiddlewareFunc defines a function to process middleware.
|
||||||
OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc)
|
MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
||||||
}
|
|
||||||
|
|
||||||
// Route contains a handler and information for matching against requests.
|
// HandlerFunc defines a function to serve HTTP requests.
|
||||||
type Route struct {
|
HandlerFunc func(c Context) error
|
||||||
Method string `json:"method"`
|
|
||||||
Path string `json:"path"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTPError represents an error that occurred while handling a request.
|
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||||
type HTTPError struct {
|
HTTPErrorHandler func(error, Context)
|
||||||
Code int `json:"-"`
|
|
||||||
Message interface{} `json:"message"`
|
|
||||||
Internal error `json:"-"` // Stores the error returned by an external dependency
|
|
||||||
}
|
|
||||||
|
|
||||||
// MiddlewareFunc defines a function to process middleware.
|
// Validator is the interface that wraps the Validate function.
|
||||||
type MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
Validator interface {
|
||||||
|
Validate(i interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
// HandlerFunc defines a function to serve HTTP requests.
|
// JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.
|
||||||
type HandlerFunc func(c Context) error
|
JSONSerializer interface {
|
||||||
|
Serialize(c Context, i interface{}, indent string) error
|
||||||
|
Deserialize(c Context, i interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
// Renderer is the interface that wraps the Render function.
|
||||||
type HTTPErrorHandler func(err error, c Context)
|
Renderer interface {
|
||||||
|
Render(io.Writer, string, interface{}, Context) error
|
||||||
|
}
|
||||||
|
|
||||||
// Validator is the interface that wraps the Validate function.
|
// Map defines a generic map of type `map[string]interface{}`.
|
||||||
type Validator interface {
|
Map map[string]interface{}
|
||||||
Validate(i interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.
|
// Common struct for Echo & Group.
|
||||||
type JSONSerializer interface {
|
common struct{}
|
||||||
Serialize(c Context, i interface{}, indent string) error
|
)
|
||||||
Deserialize(c Context, i interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Renderer is the interface that wraps the Render function.
|
|
||||||
type Renderer interface {
|
|
||||||
Render(io.Writer, string, interface{}, Context) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map defines a generic map of type `map[string]interface{}`.
|
|
||||||
type Map map[string]interface{}
|
|
||||||
|
|
||||||
// Common struct for Echo & Group.
|
|
||||||
type common struct{}
|
|
||||||
|
|
||||||
// HTTP methods
|
// HTTP methods
|
||||||
// NOTE: Deprecated, please use the stdlib constants directly instead.
|
// NOTE: Deprecated, please use the stdlib constants directly instead.
|
||||||
@ -170,12 +158,7 @@ const (
|
|||||||
|
|
||||||
// MIME types
|
// MIME types
|
||||||
const (
|
const (
|
||||||
// MIMEApplicationJSON JavaScript Object Notation (JSON) https://www.rfc-editor.org/rfc/rfc8259
|
MIMEApplicationJSON = "application/json"
|
||||||
MIMEApplicationJSON = "application/json"
|
|
||||||
// Deprecated: Please use MIMEApplicationJSON instead. JSON should be encoded using UTF-8 by default.
|
|
||||||
// No "charset" parameter is defined for this registration.
|
|
||||||
// Adding one really has no effect on compliant recipients.
|
|
||||||
// See RFC 8259, section 8.1. https://datatracker.ietf.org/doc/html/rfc8259#section-8.1
|
|
||||||
MIMEApplicationJSONCharsetUTF8 = MIMEApplicationJSON + "; " + charsetUTF8
|
MIMEApplicationJSONCharsetUTF8 = MIMEApplicationJSON + "; " + charsetUTF8
|
||||||
MIMEApplicationJavaScript = "application/javascript"
|
MIMEApplicationJavaScript = "application/javascript"
|
||||||
MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
|
MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
|
||||||
@ -200,8 +183,6 @@ const (
|
|||||||
PROPFIND = "PROPFIND"
|
PROPFIND = "PROPFIND"
|
||||||
// REPORT Method can be used to get information about a resource, see rfc 3253
|
// REPORT Method can be used to get information about a resource, see rfc 3253
|
||||||
REPORT = "REPORT"
|
REPORT = "REPORT"
|
||||||
// RouteNotFound is special method type for routes handling "route not found" (404) cases
|
|
||||||
RouteNotFound = "echo_route_not_found"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Headers
|
// Headers
|
||||||
@ -265,7 +246,7 @@ const (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Version of Echo
|
// Version of Echo
|
||||||
Version = "4.12.0"
|
Version = "4.7.0"
|
||||||
website = "https://echo.labstack.com"
|
website = "https://echo.labstack.com"
|
||||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||||
banner = `
|
banner = `
|
||||||
@ -280,88 +261,60 @@ ____________________________________O/_______
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
var methods = [...]string{
|
var (
|
||||||
http.MethodConnect,
|
methods = [...]string{
|
||||||
http.MethodDelete,
|
http.MethodConnect,
|
||||||
http.MethodGet,
|
http.MethodDelete,
|
||||||
http.MethodHead,
|
http.MethodGet,
|
||||||
http.MethodOptions,
|
http.MethodHead,
|
||||||
http.MethodPatch,
|
http.MethodOptions,
|
||||||
http.MethodPost,
|
http.MethodPatch,
|
||||||
PROPFIND,
|
http.MethodPost,
|
||||||
http.MethodPut,
|
PROPFIND,
|
||||||
http.MethodTrace,
|
http.MethodPut,
|
||||||
REPORT,
|
http.MethodTrace,
|
||||||
}
|
REPORT,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
var (
|
var (
|
||||||
ErrBadRequest = NewHTTPError(http.StatusBadRequest) // HTTP 400 Bad Request
|
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType)
|
||||||
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized) // HTTP 401 Unauthorized
|
ErrNotFound = NewHTTPError(http.StatusNotFound)
|
||||||
ErrPaymentRequired = NewHTTPError(http.StatusPaymentRequired) // HTTP 402 Payment Required
|
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized)
|
||||||
ErrForbidden = NewHTTPError(http.StatusForbidden) // HTTP 403 Forbidden
|
ErrForbidden = NewHTTPError(http.StatusForbidden)
|
||||||
ErrNotFound = NewHTTPError(http.StatusNotFound) // HTTP 404 Not Found
|
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed)
|
||||||
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed) // HTTP 405 Method Not Allowed
|
ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge)
|
||||||
ErrNotAcceptable = NewHTTPError(http.StatusNotAcceptable) // HTTP 406 Not Acceptable
|
ErrTooManyRequests = NewHTTPError(http.StatusTooManyRequests)
|
||||||
ErrProxyAuthRequired = NewHTTPError(http.StatusProxyAuthRequired) // HTTP 407 Proxy AuthRequired
|
ErrBadRequest = NewHTTPError(http.StatusBadRequest)
|
||||||
ErrRequestTimeout = NewHTTPError(http.StatusRequestTimeout) // HTTP 408 Request Timeout
|
ErrBadGateway = NewHTTPError(http.StatusBadGateway)
|
||||||
ErrConflict = NewHTTPError(http.StatusConflict) // HTTP 409 Conflict
|
ErrInternalServerError = NewHTTPError(http.StatusInternalServerError)
|
||||||
ErrGone = NewHTTPError(http.StatusGone) // HTTP 410 Gone
|
ErrRequestTimeout = NewHTTPError(http.StatusRequestTimeout)
|
||||||
ErrLengthRequired = NewHTTPError(http.StatusLengthRequired) // HTTP 411 Length Required
|
ErrServiceUnavailable = NewHTTPError(http.StatusServiceUnavailable)
|
||||||
ErrPreconditionFailed = NewHTTPError(http.StatusPreconditionFailed) // HTTP 412 Precondition Failed
|
ErrValidatorNotRegistered = errors.New("validator not registered")
|
||||||
ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge) // HTTP 413 Payload Too Large
|
ErrRendererNotRegistered = errors.New("renderer not registered")
|
||||||
ErrRequestURITooLong = NewHTTPError(http.StatusRequestURITooLong) // HTTP 414 URI Too Long
|
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
||||||
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType) // HTTP 415 Unsupported Media Type
|
ErrCookieNotFound = errors.New("cookie not found")
|
||||||
ErrRequestedRangeNotSatisfiable = NewHTTPError(http.StatusRequestedRangeNotSatisfiable) // HTTP 416 Range Not Satisfiable
|
ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte")
|
||||||
ErrExpectationFailed = NewHTTPError(http.StatusExpectationFailed) // HTTP 417 Expectation Failed
|
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
||||||
ErrTeapot = NewHTTPError(http.StatusTeapot) // HTTP 418 I'm a teapot
|
|
||||||
ErrMisdirectedRequest = NewHTTPError(http.StatusMisdirectedRequest) // HTTP 421 Misdirected Request
|
|
||||||
ErrUnprocessableEntity = NewHTTPError(http.StatusUnprocessableEntity) // HTTP 422 Unprocessable Entity
|
|
||||||
ErrLocked = NewHTTPError(http.StatusLocked) // HTTP 423 Locked
|
|
||||||
ErrFailedDependency = NewHTTPError(http.StatusFailedDependency) // HTTP 424 Failed Dependency
|
|
||||||
ErrTooEarly = NewHTTPError(http.StatusTooEarly) // HTTP 425 Too Early
|
|
||||||
ErrUpgradeRequired = NewHTTPError(http.StatusUpgradeRequired) // HTTP 426 Upgrade Required
|
|
||||||
ErrPreconditionRequired = NewHTTPError(http.StatusPreconditionRequired) // HTTP 428 Precondition Required
|
|
||||||
ErrTooManyRequests = NewHTTPError(http.StatusTooManyRequests) // HTTP 429 Too Many Requests
|
|
||||||
ErrRequestHeaderFieldsTooLarge = NewHTTPError(http.StatusRequestHeaderFieldsTooLarge) // HTTP 431 Request Header Fields Too Large
|
|
||||||
ErrUnavailableForLegalReasons = NewHTTPError(http.StatusUnavailableForLegalReasons) // HTTP 451 Unavailable For Legal Reasons
|
|
||||||
ErrInternalServerError = NewHTTPError(http.StatusInternalServerError) // HTTP 500 Internal Server Error
|
|
||||||
ErrNotImplemented = NewHTTPError(http.StatusNotImplemented) // HTTP 501 Not Implemented
|
|
||||||
ErrBadGateway = NewHTTPError(http.StatusBadGateway) // HTTP 502 Bad Gateway
|
|
||||||
ErrServiceUnavailable = NewHTTPError(http.StatusServiceUnavailable) // HTTP 503 Service Unavailable
|
|
||||||
ErrGatewayTimeout = NewHTTPError(http.StatusGatewayTimeout) // HTTP 504 Gateway Timeout
|
|
||||||
ErrHTTPVersionNotSupported = NewHTTPError(http.StatusHTTPVersionNotSupported) // HTTP 505 HTTP Version Not Supported
|
|
||||||
ErrVariantAlsoNegotiates = NewHTTPError(http.StatusVariantAlsoNegotiates) // HTTP 506 Variant Also Negotiates
|
|
||||||
ErrInsufficientStorage = NewHTTPError(http.StatusInsufficientStorage) // HTTP 507 Insufficient Storage
|
|
||||||
ErrLoopDetected = NewHTTPError(http.StatusLoopDetected) // HTTP 508 Loop Detected
|
|
||||||
ErrNotExtended = NewHTTPError(http.StatusNotExtended) // HTTP 510 Not Extended
|
|
||||||
ErrNetworkAuthenticationRequired = NewHTTPError(http.StatusNetworkAuthenticationRequired) // HTTP 511 Network Authentication Required
|
|
||||||
|
|
||||||
ErrValidatorNotRegistered = errors.New("validator not registered")
|
|
||||||
ErrRendererNotRegistered = errors.New("renderer not registered")
|
|
||||||
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
|
||||||
ErrCookieNotFound = errors.New("cookie not found")
|
|
||||||
ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte")
|
|
||||||
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NotFoundHandler is the handler that router uses in case there was no matching route found. Returns an error that results
|
// Error handlers
|
||||||
// HTTP 404 status code.
|
var (
|
||||||
var NotFoundHandler = func(c Context) error {
|
NotFoundHandler = func(c Context) error {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
|
||||||
|
|
||||||
// MethodNotAllowedHandler is the handler thar router uses in case there was no matching route found but there was
|
|
||||||
// another matching routes for that requested URL. Returns an error that results HTTP 405 Method Not Allowed status code.
|
|
||||||
var MethodNotAllowedHandler = func(c Context) error {
|
|
||||||
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
|
||||||
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
|
||||||
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
|
||||||
if ok && routerAllowMethods != "" {
|
|
||||||
c.Response().Header().Set(HeaderAllow, routerAllowMethods)
|
|
||||||
}
|
}
|
||||||
return ErrMethodNotAllowed
|
|
||||||
}
|
MethodNotAllowedHandler = func(c Context) error {
|
||||||
|
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
||||||
|
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
||||||
|
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
||||||
|
if ok && routerAllowMethods != "" {
|
||||||
|
c.Response().Header().Set(HeaderAllow, routerAllowMethods)
|
||||||
|
}
|
||||||
|
return ErrMethodNotAllowed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// New creates an instance of Echo.
|
// New creates an instance of Echo.
|
||||||
func New() (e *Echo) {
|
func New() (e *Echo) {
|
||||||
@ -419,7 +372,7 @@ func (e *Echo) Routers() map[string]*Router {
|
|||||||
//
|
//
|
||||||
// NOTE: In case errors happens in middleware call-chain that is returning from handler (which did not return an error).
|
// NOTE: In case errors happens in middleware call-chain that is returning from handler (which did not return an error).
|
||||||
// When handler has already sent response (ala c.JSON()) and there is error in middleware that is returning from
|
// When handler has already sent response (ala c.JSON()) and there is error in middleware that is returning from
|
||||||
// handler. Then the error that global error handler received will be ignored because we have already "committed" the
|
// handler. Then the error that global error handler received will be ignored because we have already "commited" the
|
||||||
// response and status code header has been sent to the client.
|
// response and status code header has been sent to the client.
|
||||||
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
||||||
|
|
||||||
@ -444,18 +397,12 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
|||||||
// Issue #1426
|
// Issue #1426
|
||||||
code := he.Code
|
code := he.Code
|
||||||
message := he.Message
|
message := he.Message
|
||||||
|
if m, ok := he.Message.(string); ok {
|
||||||
switch m := he.Message.(type) {
|
|
||||||
case string:
|
|
||||||
if e.Debug {
|
if e.Debug {
|
||||||
message = Map{"message": m, "error": err.Error()}
|
message = Map{"message": m, "error": err.Error()}
|
||||||
} else {
|
} else {
|
||||||
message = Map{"message": m}
|
message = Map{"message": m}
|
||||||
}
|
}
|
||||||
case json.Marshaler:
|
|
||||||
// do nothing - this type knows how to format itself to JSON
|
|
||||||
case error:
|
|
||||||
message = Map{"message": m.Error()}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send response
|
// Send response
|
||||||
@ -533,21 +480,8 @@ func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
|||||||
return e.Add(http.MethodTrace, path, h, m...)
|
return e.Add(http.MethodTrace, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouteNotFound registers a special-case route which is executed when no other route is found (i.e. HTTP 404 cases)
|
// Any registers a new route for all HTTP methods and path with matching handler
|
||||||
// for current request URL.
|
|
||||||
// Path supports static and named/any parameters just like other http method is defined. Generally path is ended with
|
|
||||||
// wildcard/match-any character (`/*`, `/download/*` etc).
|
|
||||||
//
|
|
||||||
// Example: `e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })`
|
|
||||||
func (e *Echo) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
|
||||||
return e.Add(RouteNotFound, path, h, m...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any registers a new route for all HTTP methods (supported by Echo) and path with matching handler
|
|
||||||
// in the router with optional route-level middleware.
|
// in the router with optional route-level middleware.
|
||||||
//
|
|
||||||
// Note: this method only adds specific set of supported HTTP methods as handler and is not true
|
|
||||||
// "catch-any-arbitrary-method" way of matching requests.
|
|
||||||
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||||
routes := make([]*Route, len(methods))
|
routes := make([]*Route, len(methods))
|
||||||
for i, m := range methods {
|
for i, m := range methods {
|
||||||
@ -578,20 +512,20 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
|
|||||||
return e.file(path, file, e.GET, m...)
|
return e.file(path, file, e.GET, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Echo) add(host, method, path string, handler HandlerFunc, middlewares ...MiddlewareFunc) *Route {
|
func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||||
router := e.findRouter(host)
|
|
||||||
//FIXME: when handler+middleware are both nil ... make it behave like handler removal
|
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
route := router.add(method, path, name, func(c Context) error {
|
router := e.findRouter(host)
|
||||||
h := applyMiddleware(handler, middlewares...)
|
router.Add(method, path, func(c Context) error {
|
||||||
|
h := applyMiddleware(handler, middleware...)
|
||||||
return h(c)
|
return h(c)
|
||||||
})
|
})
|
||||||
|
r := &Route{
|
||||||
if e.OnAddRouteHandler != nil {
|
Method: method,
|
||||||
e.OnAddRouteHandler(host, *route, handler, middlewares)
|
Path: path,
|
||||||
|
Name: name,
|
||||||
}
|
}
|
||||||
|
e.router.routes[method+path] = r
|
||||||
return route
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add registers a new route for an HTTP method and path with matching handler
|
// Add registers a new route for an HTTP method and path with matching handler
|
||||||
@ -615,7 +549,7 @@ func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI generates an URI from handler.
|
// URI generates a URI from handler.
|
||||||
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
return e.Reverse(name, params...)
|
return e.Reverse(name, params...)
|
||||||
@ -626,15 +560,37 @@ func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
|||||||
return e.URI(h, params...)
|
return e.URI(h, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse generates a URL from route name and provided parameters.
|
// Reverse generates an URL from route name and provided parameters.
|
||||||
func (e *Echo) Reverse(name string, params ...interface{}) string {
|
func (e *Echo) Reverse(name string, params ...interface{}) string {
|
||||||
return e.router.Reverse(name, params...)
|
uri := new(bytes.Buffer)
|
||||||
|
ln := len(params)
|
||||||
|
n := 0
|
||||||
|
for _, r := range e.router.routes {
|
||||||
|
if r.Name == name {
|
||||||
|
for i, l := 0, len(r.Path); i < l; i++ {
|
||||||
|
if (r.Path[i] == ':' || r.Path[i] == '*') && n < ln {
|
||||||
|
for ; i < l && r.Path[i] != '/'; i++ {
|
||||||
|
}
|
||||||
|
uri.WriteString(fmt.Sprintf("%v", params[n]))
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
if i < l {
|
||||||
|
uri.WriteByte(r.Path[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uri.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routes returns the registered routes for default router.
|
// Routes returns the registered routes.
|
||||||
// In case when Echo serves multiple hosts/domains use `e.Routers()["domain2.site"].Routes()` to get specific host routes.
|
|
||||||
func (e *Echo) Routes() []*Route {
|
func (e *Echo) Routes() []*Route {
|
||||||
return e.router.Routes()
|
routes := make([]*Route, 0, len(e.router.routes))
|
||||||
|
for _, v := range e.router.routes {
|
||||||
|
routes = append(routes, v)
|
||||||
|
}
|
||||||
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcquireContext returns an empty `Context` instance from the pool.
|
// AcquireContext returns an empty `Context` instance from the pool.
|
||||||
@ -654,7 +610,7 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Acquire context
|
// Acquire context
|
||||||
c := e.pool.Get().(*context)
|
c := e.pool.Get().(*context)
|
||||||
c.Reset(r, w)
|
c.Reset(r, w)
|
||||||
var h HandlerFunc
|
var h func(Context) error
|
||||||
|
|
||||||
if e.premiddleware == nil {
|
if e.premiddleware == nil {
|
||||||
e.findRouter(r.Host).Find(r.Method, GetPath(r), c)
|
e.findRouter(r.Host).Find(r.Method, GetPath(r), c)
|
||||||
@ -728,7 +684,7 @@ func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err erro
|
|||||||
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
|
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
|
||||||
switch v := fileOrContent.(type) {
|
switch v := fileOrContent.(type) {
|
||||||
case string:
|
case string:
|
||||||
return os.ReadFile(v)
|
return ioutil.ReadFile(v)
|
||||||
case []byte:
|
case []byte:
|
||||||
return v, nil
|
return v, nil
|
||||||
default:
|
default:
|
||||||
@ -776,7 +732,7 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
|||||||
return s.Serve(e.Listener)
|
return s.Serve(e.Listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Echo) configureServer(s *http.Server) error {
|
func (e *Echo) configureServer(s *http.Server) (err error) {
|
||||||
// Setup
|
// Setup
|
||||||
e.colorer.SetOutput(e.Logger.Output())
|
e.colorer.SetOutput(e.Logger.Output())
|
||||||
s.ErrorLog = e.StdLogger
|
s.ErrorLog = e.StdLogger
|
||||||
@ -791,11 +747,10 @@ func (e *Echo) configureServer(s *http.Server) error {
|
|||||||
|
|
||||||
if s.TLSConfig == nil {
|
if s.TLSConfig == nil {
|
||||||
if e.Listener == nil {
|
if e.Listener == nil {
|
||||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.Listener = l
|
|
||||||
}
|
}
|
||||||
if !e.HidePort {
|
if !e.HidePort {
|
||||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||||
@ -836,7 +791,7 @@ func (e *Echo) TLSListenerAddr() net.Addr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StartH2CServer starts a custom http/2 server with h2c (HTTP/2 Cleartext).
|
// StartH2CServer starts a custom http/2 server with h2c (HTTP/2 Cleartext).
|
||||||
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) error {
|
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||||
e.startupMutex.Lock()
|
e.startupMutex.Lock()
|
||||||
// Setup
|
// Setup
|
||||||
s := e.Server
|
s := e.Server
|
||||||
@ -853,12 +808,11 @@ func (e *Echo) StartH2CServer(address string, h2s *http2.Server) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e.Listener == nil {
|
if e.Listener == nil {
|
||||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.startupMutex.Unlock()
|
e.startupMutex.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.Listener = l
|
|
||||||
}
|
}
|
||||||
if !e.HidePort {
|
if !e.HidePort {
|
||||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||||
@ -912,15 +866,6 @@ func (he *HTTPError) SetInternal(err error) *HTTPError {
|
|||||||
return he
|
return he
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithInternal returns clone of HTTPError with err set to HTTPError.Internal field
|
|
||||||
func (he *HTTPError) WithInternal(err error) *HTTPError {
|
|
||||||
return &HTTPError{
|
|
||||||
Code: he.Code,
|
|
||||||
Message: he.Message,
|
|
||||||
Internal: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap satisfies the Go 1.13 error wrapper interface.
|
// Unwrap satisfies the Go 1.13 error wrapper interface.
|
||||||
func (he *HTTPError) Unwrap() error {
|
func (he *HTTPError) Unwrap() error {
|
||||||
return he.Internal
|
return he.Internal
|
||||||
@ -950,8 +895,8 @@ func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc {
|
|||||||
|
|
||||||
// GetPath returns RawPath, if it's empty returns Path from URL
|
// GetPath returns RawPath, if it's empty returns Path from URL
|
||||||
// Difference between RawPath and Path is:
|
// Difference between RawPath and Path is:
|
||||||
// - Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
|
// * Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
|
||||||
// - RawPath is an optional field which only gets set if the default encoding is different from Path.
|
// * RawPath is an optional field which only gets set if the default encoding is different from Path.
|
||||||
func GetPath(r *http.Request) string {
|
func GetPath(r *http.Request) string {
|
||||||
path := r.URL.RawPath
|
path := r.URL.RawPath
|
||||||
if path == "" {
|
if path == "" {
|
||||||
|
164
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
164
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
@ -1,162 +1,62 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
//go:build !go1.16
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
// +build !go1.16
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type filesystem struct {
|
type filesystem struct {
|
||||||
// Filesystem is file system used by Static and File handlers to access files.
|
|
||||||
// Defaults to os.DirFS(".")
|
|
||||||
//
|
|
||||||
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
|
|
||||||
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
|
|
||||||
// including `assets/images` as their prefix.
|
|
||||||
Filesystem fs.FS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFilesystem() filesystem {
|
func createFilesystem() filesystem {
|
||||||
return filesystem{
|
return filesystem{}
|
||||||
Filesystem: newDefaultFS(),
|
}
|
||||||
|
|
||||||
|
// Static registers a new route with path prefix to serve static files from the
|
||||||
|
// provided root directory.
|
||||||
|
func (e *Echo) Static(prefix, root string) *Route {
|
||||||
|
if root == "" {
|
||||||
|
root = "." // For security we want to restrict to CWD.
|
||||||
}
|
}
|
||||||
|
return e.static(prefix, root, e.GET)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static registers a new route with path prefix to serve static files from the provided root directory.
|
func (common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route {
|
||||||
func (e *Echo) Static(pathPrefix, fsRoot string) *Route {
|
h := func(c Context) error {
|
||||||
subFs := MustSubFS(e.Filesystem, fsRoot)
|
p, err := url.PathUnescape(c.Param("*"))
|
||||||
return e.Add(
|
if err != nil {
|
||||||
http.MethodGet,
|
return err
|
||||||
pathPrefix+"*",
|
|
||||||
StaticDirectoryHandler(subFs, false),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StaticFS registers a new route with path prefix to serve static files from the provided file system.
|
|
||||||
//
|
|
||||||
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
|
|
||||||
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
|
|
||||||
// including `assets/images` as their prefix.
|
|
||||||
func (e *Echo) StaticFS(pathPrefix string, filesystem fs.FS) *Route {
|
|
||||||
return e.Add(
|
|
||||||
http.MethodGet,
|
|
||||||
pathPrefix+"*",
|
|
||||||
StaticDirectoryHandler(filesystem, false),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StaticDirectoryHandler creates handler function to serve files from provided file system
|
|
||||||
// When disablePathUnescaping is set then file name from path is not unescaped and is served as is.
|
|
||||||
func StaticDirectoryHandler(fileSystem fs.FS, disablePathUnescaping bool) HandlerFunc {
|
|
||||||
return func(c Context) error {
|
|
||||||
p := c.Param("*")
|
|
||||||
if !disablePathUnescaping { // when router is already unescaping we do not want to do is twice
|
|
||||||
tmpPath, err := url.PathUnescape(p)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to unescape path variable: %w", err)
|
|
||||||
}
|
|
||||||
p = tmpPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fs.FS.Open() already assumes that file names are relative to FS root path and considers name with prefix `/` as invalid
|
name := filepath.Join(root, filepath.Clean("/"+p)) // "/"+ for security
|
||||||
name := filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
|
fi, err := os.Stat(name)
|
||||||
fi, err := fs.Stat(fileSystem, name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrNotFound
|
// The access path does not exist
|
||||||
|
return NotFoundHandler(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the request is for a directory and does not end with "/"
|
// If the request is for a directory and does not end with "/"
|
||||||
p = c.Request().URL.Path // path must not be empty.
|
p = c.Request().URL.Path // path must not be empty.
|
||||||
if fi.IsDir() && len(p) > 0 && p[len(p)-1] != '/' {
|
if fi.IsDir() && p[len(p)-1] != '/' {
|
||||||
// Redirect to ends with "/"
|
// Redirect to ends with "/"
|
||||||
return c.Redirect(http.StatusMovedPermanently, sanitizeURI(p+"/"))
|
return c.Redirect(http.StatusMovedPermanently, p+"/")
|
||||||
}
|
}
|
||||||
return fsFile(c, name, fileSystem)
|
return c.File(name)
|
||||||
}
|
}
|
||||||
}
|
// Handle added routes based on trailing slash:
|
||||||
|
// /prefix => exact route "/prefix" + any route "/prefix/*"
|
||||||
// FileFS registers a new route with path to serve file from the provided file system.
|
// /prefix/ => only any route "/prefix/*"
|
||||||
func (e *Echo) FileFS(path, file string, filesystem fs.FS, m ...MiddlewareFunc) *Route {
|
if prefix != "" {
|
||||||
return e.GET(path, StaticFileHandler(file, filesystem), m...)
|
if prefix[len(prefix)-1] == '/' {
|
||||||
}
|
// Only add any route for intentional trailing slash
|
||||||
|
return get(prefix+"*", h)
|
||||||
// StaticFileHandler creates handler function to serve file from provided file system
|
|
||||||
func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc {
|
|
||||||
return func(c Context) error {
|
|
||||||
return fsFile(c, file, filesystem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// defaultFS exists to preserve pre v4.7.0 behaviour where files were open by `os.Open`.
|
|
||||||
// v4.7 introduced `echo.Filesystem` field which is Go1.16+ `fs.Fs` interface.
|
|
||||||
// Difference between `os.Open` and `fs.Open` is that FS does not allow opening path that start with `.`, `..` or `/`
|
|
||||||
// etc. For example previously you could have `../images` in your application but `fs := os.DirFS("./")` would not
|
|
||||||
// allow you to use `fs.Open("../images")` and this would break all old applications that rely on being able to
|
|
||||||
// traverse up from current executable run path.
|
|
||||||
// NB: private because you really should use fs.FS implementation instances
|
|
||||||
type defaultFS struct {
|
|
||||||
prefix string
|
|
||||||
fs fs.FS
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDefaultFS() *defaultFS {
|
|
||||||
dir, _ := os.Getwd()
|
|
||||||
return &defaultFS{
|
|
||||||
prefix: dir,
|
|
||||||
fs: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fs defaultFS) Open(name string) (fs.File, error) {
|
|
||||||
if fs.fs == nil {
|
|
||||||
return os.Open(name)
|
|
||||||
}
|
|
||||||
return fs.fs.Open(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
|
||||||
root = filepath.ToSlash(filepath.Clean(root)) // note: fs.FS operates only with slashes. `ToSlash` is necessary for Windows
|
|
||||||
if dFS, ok := currentFs.(*defaultFS); ok {
|
|
||||||
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS.
|
|
||||||
// fs.Fs.Open does not like relative paths ("./", "../") and absolute paths at all but prior echo.Filesystem we
|
|
||||||
// were able to use paths like `./myfile.log`, `/etc/hosts` and these would work fine with `os.Open` but not with fs.Fs
|
|
||||||
if !filepath.IsAbs(root) {
|
|
||||||
root = filepath.Join(dFS.prefix, root)
|
|
||||||
}
|
}
|
||||||
return &defaultFS{
|
get(prefix, h)
|
||||||
prefix: root,
|
|
||||||
fs: os.DirFS(root),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
return fs.Sub(currentFs, root)
|
return get(prefix+"/*", h)
|
||||||
}
|
|
||||||
|
|
||||||
// MustSubFS creates sub FS from current filesystem or panic on failure.
|
|
||||||
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
|
|
||||||
//
|
|
||||||
// MustSubFS is helpful when dealing with `embed.FS` because for example `//go:embed assets/images` embeds files with
|
|
||||||
// paths including `assets/images` as their prefix. In that case use `fs := echo.MustSubFS(fs, "rootDirectory") to
|
|
||||||
// create sub fs which uses necessary prefix for directory path.
|
|
||||||
func MustSubFS(currentFs fs.FS, fsRoot string) fs.FS {
|
|
||||||
subFs, err := subFS(currentFs, fsRoot)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("can not create sub FS, invalid root given, err: %w", err))
|
|
||||||
}
|
|
||||||
return subFs
|
|
||||||
}
|
|
||||||
|
|
||||||
func sanitizeURI(uri string) string {
|
|
||||||
// double slash `\\`, `//` or even `\/` is absolute uri for browsers and by redirecting request to that uri
|
|
||||||
// we are vulnerable to open redirect attack. so replace all slashes from the beginning with single slash
|
|
||||||
if len(uri) > 1 && (uri[0] == '\\' || uri[0] == '/') && (uri[1] == '\\' || uri[1] == '/') {
|
|
||||||
uri = "/" + strings.TrimLeft(uri, `/\`)
|
|
||||||
}
|
|
||||||
return uri
|
|
||||||
}
|
}
|
||||||
|
145
vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
generated
vendored
Normal file
145
vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
//go:build go1.16
|
||||||
|
// +build go1.16
|
||||||
|
|
||||||
|
package echo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type filesystem struct {
|
||||||
|
// Filesystem is file system used by Static and File handlers to access files.
|
||||||
|
// Defaults to os.DirFS(".")
|
||||||
|
//
|
||||||
|
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
|
||||||
|
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
|
||||||
|
// including `assets/images` as their prefix.
|
||||||
|
Filesystem fs.FS
|
||||||
|
}
|
||||||
|
|
||||||
|
func createFilesystem() filesystem {
|
||||||
|
return filesystem{
|
||||||
|
Filesystem: newDefaultFS(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static registers a new route with path prefix to serve static files from the provided root directory.
|
||||||
|
func (e *Echo) Static(pathPrefix, fsRoot string) *Route {
|
||||||
|
subFs := MustSubFS(e.Filesystem, fsRoot)
|
||||||
|
return e.Add(
|
||||||
|
http.MethodGet,
|
||||||
|
pathPrefix+"*",
|
||||||
|
StaticDirectoryHandler(subFs, false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticFS registers a new route with path prefix to serve static files from the provided file system.
|
||||||
|
//
|
||||||
|
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
|
||||||
|
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
|
||||||
|
// including `assets/images` as their prefix.
|
||||||
|
func (e *Echo) StaticFS(pathPrefix string, filesystem fs.FS) *Route {
|
||||||
|
return e.Add(
|
||||||
|
http.MethodGet,
|
||||||
|
pathPrefix+"*",
|
||||||
|
StaticDirectoryHandler(filesystem, false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticDirectoryHandler creates handler function to serve files from provided file system
|
||||||
|
// When disablePathUnescaping is set then file name from path is not unescaped and is served as is.
|
||||||
|
func StaticDirectoryHandler(fileSystem fs.FS, disablePathUnescaping bool) HandlerFunc {
|
||||||
|
return func(c Context) error {
|
||||||
|
p := c.Param("*")
|
||||||
|
if !disablePathUnescaping { // when router is already unescaping we do not want to do is twice
|
||||||
|
tmpPath, err := url.PathUnescape(p)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to unescape path variable: %w", err)
|
||||||
|
}
|
||||||
|
p = tmpPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// fs.FS.Open() already assumes that file names are relative to FS root path and considers name with prefix `/` as invalid
|
||||||
|
name := filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
|
||||||
|
fi, err := fs.Stat(fileSystem, name)
|
||||||
|
if err != nil {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the request is for a directory and does not end with "/"
|
||||||
|
p = c.Request().URL.Path // path must not be empty.
|
||||||
|
if fi.IsDir() && len(p) > 0 && p[len(p)-1] != '/' {
|
||||||
|
// Redirect to ends with "/"
|
||||||
|
return c.Redirect(http.StatusMovedPermanently, p+"/")
|
||||||
|
}
|
||||||
|
return fsFile(c, name, fileSystem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileFS registers a new route with path to serve file from the provided file system.
|
||||||
|
func (e *Echo) FileFS(path, file string, filesystem fs.FS, m ...MiddlewareFunc) *Route {
|
||||||
|
return e.GET(path, StaticFileHandler(file, filesystem), m...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticFileHandler creates handler function to serve file from provided file system
|
||||||
|
func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc {
|
||||||
|
return func(c Context) error {
|
||||||
|
return fsFile(c, file, filesystem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaultFS emulates os.Open behaviour with filesystem opened by `os.DirFs`. Difference between `os.Open` and `fs.Open`
|
||||||
|
// is that FS does not allow to open path that start with `..` or `/` etc. For example previously you could have `../images`
|
||||||
|
// in your application but `fs := os.DirFS("./")` would not allow you to use `fs.Open("../images")` and this would break
|
||||||
|
// all old applications that rely on being able to traverse up from current executable run path.
|
||||||
|
// NB: private because you really should use fs.FS implementation instances
|
||||||
|
type defaultFS struct {
|
||||||
|
prefix string
|
||||||
|
fs fs.FS
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDefaultFS() *defaultFS {
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
return &defaultFS{
|
||||||
|
prefix: dir,
|
||||||
|
fs: os.DirFS(dir),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs defaultFS) Open(name string) (fs.File, error) {
|
||||||
|
return fs.fs.Open(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
||||||
|
root = filepath.ToSlash(filepath.Clean(root)) // note: fs.FS operates only with slashes. `ToSlash` is necessary for Windows
|
||||||
|
if dFS, ok := currentFs.(*defaultFS); ok {
|
||||||
|
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS to
|
||||||
|
// allow cases when root is given as `../somepath` which is not valid for fs.FS
|
||||||
|
root = filepath.Join(dFS.prefix, root)
|
||||||
|
return &defaultFS{
|
||||||
|
prefix: root,
|
||||||
|
fs: os.DirFS(root),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return fs.Sub(currentFs, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustSubFS creates sub FS from current filesystem or panic on failure.
|
||||||
|
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
|
||||||
|
//
|
||||||
|
// MustSubFS is helpful when dealing with `embed.FS` because for example `//go:embed assets/images` embeds files with
|
||||||
|
// paths including `assets/images` as their prefix. In that case use `fs := echo.MustSubFS(fs, "rootDirectory") to
|
||||||
|
// create sub fs which uses necessary prefix for directory path.
|
||||||
|
func MustSubFS(currentFs fs.FS, fsRoot string) fs.FS {
|
||||||
|
subFs, err := subFS(currentFs, fsRoot)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("can not create sub FS, invalid root given, err: %w", err))
|
||||||
|
}
|
||||||
|
return subFs
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user