Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
fe13e8dff6 | |||
10d070dd10 | |||
af826ff457 | |||
90bfc25975 | |||
dadb907740 |
39
go.mod
39
go.mod
@ -1,41 +1,42 @@
|
|||||||
module git.paulbsd.com/paulbsd/pki
|
module git.paulbsd.com/paulbsd/pki
|
||||||
|
|
||||||
go 1.21
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-acme/lego/v4 v4.14.2
|
github.com/go-acme/lego/v4 v4.17.4
|
||||||
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/labstack/echo/v4 v4.12.0
|
||||||
github.com/labstack/echo/v4 v4.11.1
|
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
github.com/miekg/dns v1.1.56 // indirect
|
github.com/miekg/dns v1.1.62 // indirect
|
||||||
github.com/onsi/ginkgo v1.16.0 // indirect
|
github.com/onsi/ginkgo v1.16.0 // indirect
|
||||||
github.com/onsi/gomega v1.11.0 // indirect
|
github.com/onsi/gomega v1.11.0 // indirect
|
||||||
golang.org/x/crypto v0.13.0 // indirect
|
golang.org/x/crypto v0.26.0 // indirect
|
||||||
golang.org/x/net v0.15.0 // indirect
|
golang.org/x/net v0.28.0 // indirect
|
||||||
golang.org/x/sys v0.12.0 // indirect
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
golang.org/x/text v0.13.0 // indirect
|
golang.org/x/text v0.17.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.6.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0
|
gopkg.in/ini.v1 v1.67.0
|
||||||
xorm.io/builder v0.3.13 // indirect
|
xorm.io/builder v0.3.13 // indirect
|
||||||
xorm.io/xorm v1.3.3
|
xorm.io/xorm v1.3.9
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
|
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.3 // indirect
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
github.com/golang-jwt/jwt v3.2.2+incompatible // 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.0 // indirect
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.20 // 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/ovh/go-ovh v1.4.2 // indirect
|
github.com/ovh/go-ovh v1.6.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.2 // indirect
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
golang.org/x/mod v0.20.0 // indirect
|
||||||
golang.org/x/tools v0.13.0 // indirect
|
golang.org/x/oauth2 v0.22.0 // indirect
|
||||||
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
|
golang.org/x/tools v0.24.0 // indirect
|
||||||
)
|
)
|
||||||
|
797
go.sum
797
go.sum
@ -1,126 +1,34 @@
|
|||||||
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=
|
||||||
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
|
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
|
|
||||||
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 h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
|
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
|
||||||
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/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
|
||||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
|
||||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
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/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
|
||||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
|
||||||
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/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/go-acme/lego/v4 v4.16.1 h1:JxZ93s4KG0jL27rZ30UsIgxap6VGzKuREsSkkyzeoCQ=
|
||||||
github.com/go-acme/lego/v4 v4.10.2 h1:5eW3qmda5v/LP21v1Hj70edKY1jeFZQwO617tdkwp6Q=
|
github.com/go-acme/lego/v4 v4.16.1/go.mod h1:AVvwdPned/IWpD/ihHhMsKnveF7HHYAz/CmtXi7OZoE=
|
||||||
github.com/go-acme/lego/v4 v4.10.2/go.mod h1:EMbf0Jmqwv94nJ5WL9qWnSXIBZnvsS9gNypansHGc6U=
|
github.com/go-acme/lego/v4 v4.17.4 h1:h0nePd3ObP6o7kAkndtpTzCw8shOZuWckNYeUQwo36Q=
|
||||||
github.com/go-acme/lego/v4 v4.11.0 h1:oIPoU7zBJoTfoVrbqk62+/2NsGCSgCVK1JtZSZZ28SU=
|
github.com/go-acme/lego/v4 v4.17.4/go.mod h1:dU94SvPNqimEeb7EVilGGSnS0nU1O5Exir0pQ4QFL4U=
|
||||||
github.com/go-acme/lego/v4 v4.11.0/go.mod h1:dENL0J3/WughN2NLy0T35otK5k1EWCmXTwCw0+X5ZaE=
|
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
||||||
github.com/go-acme/lego/v4 v4.14.2 h1:/D/jqRgLi8Cbk33sLGtu2pX2jEg3bGJWHyV8kFuUHGM=
|
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||||
github.com/go-acme/lego/v4 v4.14.2/go.mod h1:kBXxbeTg0x9AgaOYjPSwIeJy3Y33zTz+tMD16O4MO6c=
|
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
|
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||||
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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
|
||||||
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-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
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.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
|
||||||
github.com/goccy/go-json v0.10.1 h1:lEs5Ob+oOG/Ze199njvzHbhn6p9T+h64F5hRj69iTTo=
|
|
||||||
github.com/goccy/go-json v0.10.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
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 h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
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-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
|
||||||
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=
|
||||||
@ -129,219 +37,50 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||||||
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.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
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.1/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.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.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
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/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/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/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
|
||||||
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/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
|
||||||
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
|
|
||||||
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/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
|
||||||
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/pgproto3/v2 v2.3.2/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/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
|
||||||
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/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
|
||||||
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
|
||||||
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/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
|
||||||
github.com/jackc/pgx/v4 v4.18.0/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
|
|
||||||
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/jackc/puddle v1.3.0/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.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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||||
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 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/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/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
|
||||||
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
|
|
||||||
github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
|
|
||||||
github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ=
|
|
||||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
|
||||||
github.com/labstack/gommon v0.4.0/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.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
|
||||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/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.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
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/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
|
||||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
|
||||||
github.com/miekg/dns v1.1.52 h1:Bmlc/qsNNULOe6bpXcUTsuOajd0DzRHwup6D9k1An0c=
|
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
||||||
github.com/miekg/dns v1.1.52/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
||||||
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
|
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||||
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||||
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
|
||||||
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
|
||||||
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/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
|
||||||
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=
|
||||||
@ -352,516 +91,138 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
|||||||
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.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
||||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
github.com/ovh/go-ovh v1.5.1 h1:P8O+7H+NQuFK9P/j4sFW5C0fvSS2DnHYGPwdVCp45wI=
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
github.com/ovh/go-ovh v1.5.1/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
||||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI=
|
||||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
||||||
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/ovh/go-ovh v1.3.0 h1:mvZaddk4E4kLcXhzb+cxBsMPYp2pHqiQpWYkInsuZPQ=
|
|
||||||
github.com/ovh/go-ovh v1.3.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
|
|
||||||
github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM=
|
|
||||||
github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M=
|
|
||||||
github.com/ovh/go-ovh v1.4.2 h1:ub4jVK6ERbiBTo4y5wbLCjeKCjGY+K36e7BviW+MaAU=
|
|
||||||
github.com/ovh/go-ovh v1.4.2/go.mod h1:AkPXVtgwB6xlKblMjRKJJmjRp+ogrE7fz2lVgcQY8SY=
|
|
||||||
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/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
|
||||||
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/shopspring/decimal v1.3.1/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/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
|
||||||
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.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
|
||||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.2/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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
|
||||||
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.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
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-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
|
||||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
|
||||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
|
||||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
|
||||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
|
||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
|
||||||
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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
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.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|
||||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
|
||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|
||||||
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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
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.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|
||||||
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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
|
||||||
golang.org/x/time v0.3.0/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/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||||
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
|
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
|
||||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/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-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/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=
|
||||||
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/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
|
||||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/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.2.8/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.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
|
||||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
|
||||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.18 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U=
|
|
||||||
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
|
||||||
modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
|
||||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||||
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
|
|
||||||
modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0=
|
|
||||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
|
||||||
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
|
||||||
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
|
||||||
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
|
|
||||||
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
|
|
||||||
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
|
|
||||||
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
|
|
||||||
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
|
|
||||||
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
|
|
||||||
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
|
|
||||||
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
|
|
||||||
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
|
|
||||||
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
|
|
||||||
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
|
|
||||||
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
|
|
||||||
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
|
|
||||||
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
|
|
||||||
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
|
|
||||||
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
|
|
||||||
modernc.org/ccgo/v3 v3.12.65/go.mod h1:D6hQtKxPNZiY6wDBtehSGKFKmyXn53F8nGTpH+POmS4=
|
|
||||||
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
|
|
||||||
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
|
|
||||||
modernc.org/ccgo/v3 v3.12.82 h1:wudcnJyjLj1aQQCXF3IM9Gz2X6UNjw+afIghzdtn0v8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.82/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
|
|
||||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
|
|
||||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
|
||||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
|
||||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
|
||||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
|
||||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
|
||||||
modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
|
|
||||||
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
|
|
||||||
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
|
|
||||||
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
|
|
||||||
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
|
|
||||||
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
|
|
||||||
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
|
|
||||||
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
|
|
||||||
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
|
|
||||||
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
|
|
||||||
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
|
|
||||||
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
|
|
||||||
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
|
|
||||||
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
|
|
||||||
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
|
|
||||||
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
|
|
||||||
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
|
|
||||||
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
|
|
||||||
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
|
|
||||||
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
|
|
||||||
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
|
|
||||||
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
|
|
||||||
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
|
|
||||||
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
|
|
||||||
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
|
|
||||||
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
|
|
||||||
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
|
|
||||||
modernc.org/libc v1.11.70/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
|
||||||
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
|
||||||
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
|
|
||||||
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
|
|
||||||
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
|
|
||||||
modernc.org/libc v1.11.87 h1:PzIzOqtlzMDDcCzJ5cUP6h/Ku6Fa9iyflP2ccTY64aE=
|
|
||||||
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
|
|
||||||
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
|
|
||||||
modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0=
|
|
||||||
modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
|
||||||
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
|
||||||
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
|
|
||||||
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
||||||
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
||||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
|
||||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
|
||||||
modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
|
|
||||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
|
||||||
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
|
||||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
||||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
|
||||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
|
||||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||||
modernc.org/sqlite v1.14.2 h1:ohsW2+e+Qe2To1W6GNezzKGwjXwSax6R+CrhRxVaFbE=
|
|
||||||
modernc.org/sqlite v1.14.2/go.mod h1:yqfn85u8wVOE6ub5UT8VI9JjhrwBUUCNyTACN0h6Sx8=
|
|
||||||
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
||||||
modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
||||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
|
||||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
|
||||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||||
modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
|
|
||||||
modernc.org/tcl v1.15.0/go.mod h1:xRoGotBZ6dU+Zo2tca+2EqVEeMmOUBzHnhIwq4YrVnE=
|
|
||||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
|
||||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|
||||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
|
|
||||||
modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
|
|
||||||
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.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
|
||||||
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
|
|
||||||
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
|
||||||
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
||||||
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
xorm.io/xorm v1.3.2 h1:uTRRKF2jYzbZ5nsofXVUx6ncMaek+SHjWYtCXyZo1oM=
|
xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
|
||||||
xorm.io/xorm v1.3.2/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
|
||||||
xorm.io/xorm v1.3.3 h1:L5/GOhvgMcwJYYRjzPf3lTTTf6JcaTd1Mb9A/Iqvccw=
|
|
||||||
xorm.io/xorm v1.3.3/go.mod h1:qFJGFoVYbbIdnz2vaL5OxSQ2raleMpyRRalnq3n9OJo=
|
|
||||||
|
@ -2,10 +2,13 @@ package cert
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
|
func (e *Entry) Z() {
|
||||||
|
}
|
||||||
|
|
||||||
// Entry is the main struct for stored certificates
|
// Entry is the main struct for stored certificates
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
ID int `xorm:"pk autoincr"`
|
ID int `xorm:"pk autoincr"`
|
||||||
Domains string `xorm:"notnull"`
|
Domain string `xorm:"notnull"`
|
||||||
Certificate string `xorm:"text notnull"`
|
Certificate string `xorm:"text notnull"`
|
||||||
PrivateKey string `xorm:"text notnull"`
|
PrivateKey string `xorm:"text notnull"`
|
||||||
AuthURL string `xorm:"notnull"`
|
AuthURL string `xorm:"notnull"`
|
||||||
|
@ -60,10 +60,13 @@ func (cfg *Config) GetConfig() error {
|
|||||||
options["ovhas"] = pkisection.Key("ovhas").MustString("")
|
options["ovhas"] = pkisection.Key("ovhas").MustString("")
|
||||||
options["ovhck"] = pkisection.Key("ovhck").MustString("")
|
options["ovhck"] = pkisection.Key("ovhck").MustString("")
|
||||||
|
|
||||||
|
options["pdnsapiurl"] = pkisection.Key("pdnsapiurl").MustString("")
|
||||||
|
options["pdnsapikey"] = pkisection.Key("pdnsapikey").MustString("")
|
||||||
|
|
||||||
cfg.ACME.ProviderOptions = options
|
cfg.ACME.ProviderOptions = options
|
||||||
for k, v := range options {
|
for key, value := range options {
|
||||||
if v == "" {
|
if value == "" {
|
||||||
utils.Advice(fmt.Sprintf("OVH provider parameter %s not set", k))
|
utils.Advice(fmt.Sprintf("Provider parameter %s not set", key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +75,8 @@ func (cfg *Config) GetConfig() error {
|
|||||||
cfg.ACME.AuthURL = lego.LEDirectoryProduction
|
cfg.ACME.AuthURL = lego.LEDirectoryProduction
|
||||||
case "staging":
|
case "staging":
|
||||||
cfg.ACME.AuthURL = lego.LEDirectoryStaging
|
cfg.ACME.AuthURL = lego.LEDirectoryStaging
|
||||||
|
default:
|
||||||
|
cfg.ACME.AuthURL = lego.LEDirectoryStaging
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"git.paulbsd.com/paulbsd/pki/src/cert"
|
"git.paulbsd.com/paulbsd/pki/src/cert"
|
||||||
"git.paulbsd.com/paulbsd/pki/src/config"
|
"git.paulbsd.com/paulbsd/pki/src/config"
|
||||||
|
"git.paulbsd.com/paulbsd/pki/src/domain"
|
||||||
"git.paulbsd.com/paulbsd/pki/src/pki"
|
"git.paulbsd.com/paulbsd/pki/src/pki"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
@ -17,7 +18,7 @@ import (
|
|||||||
func Init(cfg *config.Config) (err error) {
|
func Init(cfg *config.Config) (err error) {
|
||||||
var databaseEngine = "postgres"
|
var databaseEngine = "postgres"
|
||||||
tables := []interface{}{cert.Entry{},
|
tables := []interface{}{cert.Entry{},
|
||||||
pki.User{}}
|
pki.User{}, domain.Domain{}}
|
||||||
|
|
||||||
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",
|
||||||
|
12
src/domain/main.go
Normal file
12
src/domain/main.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// Domain describes a domain
|
||||||
|
type Domain struct {
|
||||||
|
ID int `xorm:"pk autoincr"`
|
||||||
|
Domain string `xorm:"text notnull unique(domain_provider)"`
|
||||||
|
Provider string `xorm:"text notnull unique(domain_provider)"`
|
||||||
|
Created time.Time `xorm:"created notnull"`
|
||||||
|
Updated time.Time `xorm:"updated notnull"`
|
||||||
|
}
|
@ -9,12 +9,13 @@ import (
|
|||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/pki/src/cert"
|
"git.paulbsd.com/paulbsd/pki/src/cert"
|
||||||
"git.paulbsd.com/paulbsd/pki/src/config"
|
"git.paulbsd.com/paulbsd/pki/src/config"
|
||||||
|
"git.paulbsd.com/paulbsd/pki/src/domain"
|
||||||
"github.com/go-acme/lego/v4/certcrypto"
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
"github.com/go-acme/lego/v4/certificate"
|
"github.com/go-acme/lego/v4/certificate"
|
||||||
|
"github.com/go-acme/lego/v4/challenge"
|
||||||
"github.com/go-acme/lego/v4/lego"
|
"github.com/go-acme/lego/v4/lego"
|
||||||
"github.com/go-acme/lego/v4/registration"
|
"github.com/go-acme/lego/v4/registration"
|
||||||
)
|
)
|
||||||
@ -29,9 +30,8 @@ func (u *User) Init(cfg *config.Config) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetEntry returns requested acme ressource in database relative to domain
|
// GetEntry returns requested acme ressource in database relative to domain
|
||||||
func (u *User) GetEntry(cfg *config.Config, domains []string) (Entry cert.Entry, err error) {
|
func (u *User) GetEntry(cfg *config.Config, domain *string) (Entry cert.Entry, err error) {
|
||||||
|
has, err := cfg.Db.Where("domain = ?", domain).And(
|
||||||
has, err := cfg.Db.Where("domains = ?", strings.Join(domains, ",")).And(
|
|
||||||
"auth_url = ?", cfg.ACME.AuthURL).And(
|
"auth_url = ?", cfg.ACME.AuthURL).And(
|
||||||
fmt.Sprintf("validity_end::timestamp-'%d DAY'::INTERVAL >= now()", cfg.ACME.MaxDaysBefore)).Desc(
|
fmt.Sprintf("validity_end::timestamp-'%d DAY'::INTERVAL >= now()", cfg.ACME.MaxDaysBefore)).Desc(
|
||||||
"id").Get(&Entry)
|
"id").Get(&Entry)
|
||||||
@ -66,12 +66,38 @@ func (u *User) HandleRegistration(cfg *config.Config, client *lego.Client) (err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RequestNewCert returns a newly requested certificate to letsencrypt
|
// RequestNewCert returns a newly requested certificate to letsencrypt
|
||||||
func (u *User) RequestNewCert(cfg *config.Config, domains []string) (certificates *certificate.Resource, err error) {
|
func (u *User) RequestNewCert(cfg *config.Config, domainnames *[]string) (certs *certificate.Resource, err error) {
|
||||||
legoconfig := lego.NewConfig(u)
|
legoconfig := lego.NewConfig(u)
|
||||||
legoconfig.CADirURL = cfg.ACME.AuthURL
|
legoconfig.CADirURL = cfg.ACME.AuthURL
|
||||||
legoconfig.Certificate.KeyType = certcrypto.RSA2048
|
legoconfig.Certificate.KeyType = certcrypto.RSA2048
|
||||||
|
|
||||||
ovhprovider, err := initProvider(cfg)
|
var dom domain.Domain
|
||||||
|
var has bool
|
||||||
|
for _, d := range *domainnames {
|
||||||
|
dom = domain.Domain{Domain: d}
|
||||||
|
if has, err = cfg.Db.Get(&dom); has {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has {
|
||||||
|
err = fmt.Errorf("supplied domain not in allowed domains")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider challenge.Provider
|
||||||
|
|
||||||
|
switch dom.Provider {
|
||||||
|
case "ovh":
|
||||||
|
provider, err = initOVHProvider(cfg)
|
||||||
|
case "pdns":
|
||||||
|
provider, err = initPowerDNSProvider(cfg)
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
@ -81,7 +107,7 @@ func (u *User) RequestNewCert(cfg *config.Config, domains []string) (certificate
|
|||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.Challenge.SetDNS01Provider(ovhprovider)
|
err = client.Challenge.SetDNS01Provider(provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
@ -95,14 +121,15 @@ func (u *User) RequestNewCert(cfg *config.Config, domains []string) (certificate
|
|||||||
}
|
}
|
||||||
|
|
||||||
request := certificate.ObtainRequest{
|
request := certificate.ObtainRequest{
|
||||||
Domains: domains,
|
Domains: *domainnames,
|
||||||
Bundle: true,
|
Bundle: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
certificates, err = client.Certificate.Obtain(request)
|
certs, err = client.Certificate.Obtain(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package pki
|
package pki
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/pki/src/config"
|
"git.paulbsd.com/paulbsd/pki/src/config"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/ovh"
|
"github.com/go-acme/lego/v4/providers/dns/ovh"
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns/pdns"
|
||||||
)
|
)
|
||||||
|
|
||||||
// initProvider initialize DNS provider configuration
|
// initOVHProvider initialize DNS provider configuration
|
||||||
func initProvider(cfg *config.Config) (ovhprovider *ovh.DNSProvider, err error) {
|
func initOVHProvider(cfg *config.Config) (ovhprovider *ovh.DNSProvider, err error) {
|
||||||
ovhconfig := ovh.NewDefaultConfig()
|
ovhconfig := ovh.NewDefaultConfig()
|
||||||
|
|
||||||
ovhconfig.APIEndpoint = cfg.ACME.ProviderOptions["ovhendpoint"]
|
ovhconfig.APIEndpoint = cfg.ACME.ProviderOptions["ovhendpoint"]
|
||||||
@ -15,6 +19,24 @@ func initProvider(cfg *config.Config) (ovhprovider *ovh.DNSProvider, err error)
|
|||||||
ovhconfig.ConsumerKey = cfg.ACME.ProviderOptions["ovhck"]
|
ovhconfig.ConsumerKey = cfg.ACME.ProviderOptions["ovhck"]
|
||||||
|
|
||||||
ovhprovider, err = ovh.NewDNSProviderConfig(ovhconfig)
|
ovhprovider, err = ovh.NewDNSProviderConfig(ovhconfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// initPowerDNSProvider initialize DNS provider configuration
|
||||||
|
func initPowerDNSProvider(cfg *config.Config) (pdnsprovider *pdns.DNSProvider, err error) {
|
||||||
|
pdnsconfig := pdns.NewDefaultConfig()
|
||||||
|
|
||||||
|
pdnsconfig.Host, err = url.Parse(cfg.ACME.ProviderOptions["pdnsapiurl"])
|
||||||
|
pdnsconfig.APIKey = cfg.ACME.ProviderOptions["pdnsapikey"]
|
||||||
|
|
||||||
|
pdnsprovider, err = pdns.NewDNSProviderConfig(pdnsconfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/pki/src/config"
|
"git.paulbsd.com/paulbsd/pki/src/config"
|
||||||
"git.paulbsd.com/paulbsd/pki/src/pki"
|
"git.paulbsd.com/paulbsd/pki/src/pki"
|
||||||
@ -30,13 +29,18 @@ func RunServer(cfg *config.Config) (err error) {
|
|||||||
e.GET("/", func(c echo.Context) error {
|
e.GET("/", func(c echo.Context) error {
|
||||||
return c.String(http.StatusOK, "Welcome to PKI software (https://git.paulbsd.com/paulbsd/pki)")
|
return c.String(http.StatusOK, "Welcome to PKI software (https://git.paulbsd.com/paulbsd/pki)")
|
||||||
})
|
})
|
||||||
e.GET("/domain/:domains", func(c echo.Context) (err error) {
|
e.POST("/cert", func(c echo.Context) (err error) {
|
||||||
var result EntryResponse
|
var request = new(EntryRequest)
|
||||||
var domains = strings.Split(c.Param("domains"), ",")
|
var result = make(map[string]EntryResponse)
|
||||||
|
err = c.Bind(&request)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, "error parsing request")
|
||||||
|
}
|
||||||
|
|
||||||
log.Println(fmt.Sprintf("Providing %s to user %s at %s", domains, c.Get("username"), c.RealIP()))
|
log.Printf("Providing %s to user %s at %s\n", request.Domains, c.Get("username"), c.RealIP())
|
||||||
|
|
||||||
result, err = GetCertificate(cfg, c.Get("user").(*pki.User), domains)
|
result, err = GetCertificate(cfg, c.Get("user").(*pki.User), &request.Domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.String(http.StatusInternalServerError, fmt.Sprintf("%s", err))
|
return c.String(http.StatusInternalServerError, fmt.Sprintf("%s", err))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/pki/src/cert"
|
"git.paulbsd.com/paulbsd/pki/src/cert"
|
||||||
@ -14,18 +13,24 @@ import (
|
|||||||
"git.paulbsd.com/paulbsd/pki/src/pki"
|
"git.paulbsd.com/paulbsd/pki/src/pki"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const timeformatstring string = "2006-01-02 15:04:05"
|
||||||
|
|
||||||
|
var domainRegex, err = regexp.Compile(`^[a-z0-9\*]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}$`)
|
||||||
|
|
||||||
// GetCertificate get certificate from database if exists, of request it from ACME
|
// GetCertificate get certificate from database if exists, of request it from ACME
|
||||||
func GetCertificate(cfg *config.Config, user *pki.User, domains []string) (result EntryResponse, err error) {
|
func GetCertificate(cfg *config.Config, user *pki.User, domains *[]string) (result map[string]EntryResponse, err error) {
|
||||||
err = CheckDomains(domains)
|
err = CheckDomains(domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
result = make(map[string]EntryResponse)
|
||||||
|
|
||||||
entry, err := user.GetEntry(cfg, domains)
|
firstdomain := (*domains)[0]
|
||||||
|
entry, err := user.GetEntry(cfg, &firstdomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
certs, err := user.RequestNewCert(cfg, domains)
|
certs, err := user.RequestNewCert(cfg, domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(fmt.Sprintf("Error fetching new certificate %s", err))
|
log.Printf("Error fetching new certificate %s\n", err)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
NotBefore, NotAfter, err := GetDates(certs.Certificate)
|
NotBefore, NotAfter, err := GetDates(certs.Certificate)
|
||||||
@ -33,37 +38,40 @@ func GetCertificate(cfg *config.Config, user *pki.User, domains []string) (resul
|
|||||||
log.Println("Error where parsing dates")
|
log.Println("Error where parsing dates")
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
entry := cert.Entry{Domains: strings.Join(domains, ","),
|
entry := cert.Entry{Domain: certs.Domain,
|
||||||
Certificate: string(certs.Certificate),
|
Certificate: string(certs.Certificate),
|
||||||
PrivateKey: string(certs.PrivateKey),
|
PrivateKey: string(certs.PrivateKey),
|
||||||
ValidityBegin: NotBefore,
|
ValidityBegin: NotBefore,
|
||||||
ValidityEnd: NotAfter,
|
ValidityEnd: NotAfter,
|
||||||
AuthURL: cfg.ACME.AuthURL}
|
AuthURL: cfg.ACME.AuthURL}
|
||||||
cfg.Db.Insert(&entry)
|
cfg.Db.Insert(&entry)
|
||||||
result = convertEntryToResponse(entry)
|
result[firstdomain] = convertEntryToResponse(entry)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
result = convertEntryToResponse(entry)
|
result[firstdomain] = convertEntryToResponse(entry)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckDomains check if requested domains are valid
|
// CheckDomains check if requested domains are valid
|
||||||
func CheckDomains(domains []string) (err error) {
|
func CheckDomains(domains *[]string) (err error) {
|
||||||
domainRegex, err := regexp.Compile(`^[a-z0-9\*]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}$`)
|
for _, domain := range *domains {
|
||||||
|
err = CheckDomain(&domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
for _, d := range domains {
|
|
||||||
res := domainRegex.Match([]byte(d))
|
|
||||||
if !res {
|
|
||||||
return fmt.Errorf(fmt.Sprintf("Domain %s has not a valid syntax %s, please verify", d, err))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckDomain check if requested domain are valid
|
||||||
|
func CheckDomain(domain *string) (err error) {
|
||||||
|
res := domainRegex.Match([]byte(*domain))
|
||||||
|
if !res {
|
||||||
|
return fmt.Errorf("Domain %s has not a valid syntax %s, please verify", *domain, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// GetDates decodes NotBefore and NotAfter date of cert
|
// GetDates decodes NotBefore and NotAfter date of cert
|
||||||
func GetDates(cert []byte) (NotBefore time.Time, NotAfter time.Time, err error) {
|
func GetDates(cert []byte) (NotBefore time.Time, NotAfter time.Time, err error) {
|
||||||
block, _ := pem.Decode(cert)
|
block, _ := pem.Decode(cert)
|
||||||
@ -80,9 +88,7 @@ func GetDates(cert []byte) (NotBefore time.Time, NotAfter time.Time, err error)
|
|||||||
|
|
||||||
// convertEntryToResponse converts database ACME entry to JSON ACME entry
|
// convertEntryToResponse converts database ACME entry to JSON ACME entry
|
||||||
func convertEntryToResponse(in cert.Entry) (out EntryResponse) {
|
func convertEntryToResponse(in cert.Entry) (out EntryResponse) {
|
||||||
timeformatstring := "2006-01-02 15:04:05"
|
out.Domains = append(out.Domains, in.Domain)
|
||||||
|
|
||||||
out.Domains = in.Domains
|
|
||||||
out.Certificate = in.Certificate
|
out.Certificate = in.Certificate
|
||||||
out.PrivateKey = in.PrivateKey
|
out.PrivateKey = in.PrivateKey
|
||||||
out.ValidityBegin = in.ValidityBegin.Format(timeformatstring)
|
out.ValidityBegin = in.ValidityBegin.Format(timeformatstring)
|
||||||
@ -91,11 +97,16 @@ func convertEntryToResponse(in cert.Entry) (out EntryResponse) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EntryRequest
|
||||||
|
type EntryRequest struct {
|
||||||
|
Domains []string `json:"domains"`
|
||||||
|
}
|
||||||
|
|
||||||
// EntryResponse is the struct defining JSON response from webservice
|
// EntryResponse is the struct defining JSON response from webservice
|
||||||
type EntryResponse struct {
|
type EntryResponse struct {
|
||||||
Domains string `json:"domains"`
|
Domains []string `json:"domains"`
|
||||||
Certificate string `json:"certificate"`
|
Certificate string `json:"certificate"`
|
||||||
PrivateKey string `json:"privatekey"`
|
PrivateKey string `json:"privatekey"`
|
||||||
ValidityBegin string `json:"validitybegin"`
|
ValidityBegin string `json:"validitybegin"`
|
||||||
ValidityEnd string `json:"validityend"`
|
ValidityEnd string `json:"validityend"`
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/cenkalti/backoff/v4/README.md
generated
vendored
4
vendor/github.com/cenkalti/backoff/v4/README.md
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls]
|
# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Coverage Status][coveralls image]][coveralls]
|
||||||
|
|
||||||
This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client].
|
This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client].
|
||||||
|
|
||||||
@ -21,8 +21,6 @@ Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation.
|
|||||||
|
|
||||||
[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4
|
[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4
|
||||||
[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png
|
[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png
|
||||||
[travis]: https://travis-ci.org/cenkalti/backoff
|
|
||||||
[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master
|
|
||||||
[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master
|
[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master
|
||||||
[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master
|
[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master
|
||||||
|
|
||||||
|
57
vendor/github.com/cenkalti/backoff/v4/exponential.go
generated
vendored
57
vendor/github.com/cenkalti/backoff/v4/exponential.go
generated
vendored
@ -71,6 +71,9 @@ type Clock interface {
|
|||||||
Now() time.Time
|
Now() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExponentialBackOffOpts is a function type used to configure ExponentialBackOff options.
|
||||||
|
type ExponentialBackOffOpts func(*ExponentialBackOff)
|
||||||
|
|
||||||
// Default values for ExponentialBackOff.
|
// Default values for ExponentialBackOff.
|
||||||
const (
|
const (
|
||||||
DefaultInitialInterval = 500 * time.Millisecond
|
DefaultInitialInterval = 500 * time.Millisecond
|
||||||
@ -81,7 +84,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
|
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
|
||||||
func NewExponentialBackOff() *ExponentialBackOff {
|
func NewExponentialBackOff(opts ...ExponentialBackOffOpts) *ExponentialBackOff {
|
||||||
b := &ExponentialBackOff{
|
b := &ExponentialBackOff{
|
||||||
InitialInterval: DefaultInitialInterval,
|
InitialInterval: DefaultInitialInterval,
|
||||||
RandomizationFactor: DefaultRandomizationFactor,
|
RandomizationFactor: DefaultRandomizationFactor,
|
||||||
@ -91,10 +94,62 @@ func NewExponentialBackOff() *ExponentialBackOff {
|
|||||||
Stop: Stop,
|
Stop: Stop,
|
||||||
Clock: SystemClock,
|
Clock: SystemClock,
|
||||||
}
|
}
|
||||||
|
for _, fn := range opts {
|
||||||
|
fn(b)
|
||||||
|
}
|
||||||
b.Reset()
|
b.Reset()
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithInitialInterval sets the initial interval between retries.
|
||||||
|
func WithInitialInterval(duration time.Duration) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.InitialInterval = duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRandomizationFactor sets the randomization factor to add jitter to intervals.
|
||||||
|
func WithRandomizationFactor(randomizationFactor float64) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.RandomizationFactor = randomizationFactor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMultiplier sets the multiplier for increasing the interval after each retry.
|
||||||
|
func WithMultiplier(multiplier float64) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.Multiplier = multiplier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMaxInterval sets the maximum interval between retries.
|
||||||
|
func WithMaxInterval(duration time.Duration) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.MaxInterval = duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMaxElapsedTime sets the maximum total time for retries.
|
||||||
|
func WithMaxElapsedTime(duration time.Duration) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.MaxElapsedTime = duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRetryStopDuration sets the duration after which retries should stop.
|
||||||
|
func WithRetryStopDuration(duration time.Duration) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.Stop = duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithClockProvider sets the clock used to measure time.
|
||||||
|
func WithClockProvider(clock Clock) ExponentialBackOffOpts {
|
||||||
|
return func(ebo *ExponentialBackOff) {
|
||||||
|
ebo.Clock = clock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type systemClock struct{}
|
type systemClock struct{}
|
||||||
|
|
||||||
func (t systemClock) Now() time.Time {
|
func (t systemClock) Now() time.Time {
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/acme/api/account.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/acme/api/account.go
generated
vendored
@ -16,7 +16,7 @@ func (a *AccountService) New(req acme.Account) (acme.ExtendedAccount, error) {
|
|||||||
resp, err := a.core.post(a.core.GetDirectory().NewAccountURL, req, &account)
|
resp, err := a.core.post(a.core.GetDirectory().NewAccountURL, req, &account)
|
||||||
location := getLocation(resp)
|
location := getLocation(resp)
|
||||||
|
|
||||||
if len(location) > 0 {
|
if location != "" {
|
||||||
a.core.jws.SetKid(location)
|
a.core.jws.SetKid(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/acme/api/internal/secure/jws.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/acme/api/internal/secure/jws.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme/api/internal/nonces"
|
"github.com/go-acme/lego/v4/acme/api/internal/nonces"
|
||||||
jose "github.com/go-jose/go-jose/v3"
|
jose "github.com/go-jose/go-jose/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// JWS Represents a JWS.
|
// JWS Represents a JWS.
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/acme/api/internal/sender/useragent.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/acme/api/internal/sender/useragent.go
generated
vendored
@ -5,7 +5,7 @@ package sender
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// ourUserAgent is the User-Agent of this underlying library package.
|
// ourUserAgent is the User-Agent of this underlying library package.
|
||||||
ourUserAgent = "xenolf-acme/4.14.2"
|
ourUserAgent = "xenolf-acme/4.17.4"
|
||||||
|
|
||||||
// ourUserAgentComment is part of the UA comment linked to the version status of this underlying library package.
|
// ourUserAgentComment is part of the UA comment linked to the version status of this underlying library package.
|
||||||
// values: detach|release
|
// values: detach|release
|
||||||
|
8
vendor/github.com/go-acme/lego/v4/acme/api/order.go
generated
vendored
8
vendor/github.com/go-acme/lego/v4/acme/api/order.go
generated
vendored
@ -13,6 +13,10 @@ import (
|
|||||||
type OrderOptions struct {
|
type OrderOptions struct {
|
||||||
NotBefore time.Time
|
NotBefore time.Time
|
||||||
NotAfter time.Time
|
NotAfter time.Time
|
||||||
|
// A string uniquely identifying a previously-issued certificate which this
|
||||||
|
// order is intended to replace.
|
||||||
|
// - https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5
|
||||||
|
ReplacesCertID string
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderService service
|
type OrderService service
|
||||||
@ -45,6 +49,10 @@ func (o *OrderService) NewWithOptions(domains []string, opts *OrderOptions) (acm
|
|||||||
if !opts.NotBefore.IsZero() {
|
if !opts.NotBefore.IsZero() {
|
||||||
orderReq.NotBefore = opts.NotBefore.Format(time.RFC3339)
|
orderReq.NotBefore = opts.NotBefore.Format(time.RFC3339)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.core.GetDirectory().RenewalInfo != "" {
|
||||||
|
orderReq.Replaces = opts.ReplacesCertID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var order acme.Order
|
var order acme.Order
|
||||||
|
25
vendor/github.com/go-acme/lego/v4/acme/api/renewal.go
generated
vendored
25
vendor/github.com/go-acme/lego/v4/acme/api/renewal.go
generated
vendored
@ -3,8 +3,6 @@ package api
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNoARI is returned when the server does not advertise a renewal info endpoint.
|
// ErrNoARI is returned when the server does not advertise a renewal info endpoint.
|
||||||
@ -28,26 +26,3 @@ func (c *CertificateService) GetRenewalInfo(certID string) (*http.Response, erro
|
|||||||
|
|
||||||
return c.core.HTTPClient.Get(c.core.GetDirectory().RenewalInfo + "/" + certID)
|
return c.core.HTTPClient.Get(c.core.GetDirectory().RenewalInfo + "/" + certID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRenewalInfo POSTs updated renewal information for a certificate to the renewalInfo endpoint.
|
|
||||||
// This is used to indicate that a certificate has been replaced.
|
|
||||||
//
|
|
||||||
// Note: this endpoint is part of a draft specification, not all ACME servers will implement it.
|
|
||||||
// This method will return api.ErrNoARI if the server does not advertise a renewal info endpoint.
|
|
||||||
//
|
|
||||||
// https://datatracker.ietf.org/doc/draft-ietf-acme-ari
|
|
||||||
func (c *CertificateService) UpdateRenewalInfo(req acme.RenewalInfoUpdateRequest) (*http.Response, error) {
|
|
||||||
if c.core.GetDirectory().RenewalInfo == "" {
|
|
||||||
return nil, ErrNoARI
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.CertID == "" {
|
|
||||||
return nil, errors.New("renewalInfo[post]: 'certID' cannot be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !req.Replaced {
|
|
||||||
return nil, errors.New("renewalInfo[post]: 'replaced' cannot be false")
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.core.post(c.core.GetDirectory().RenewalInfo, req, nil)
|
|
||||||
}
|
|
||||||
|
12
vendor/github.com/go-acme/lego/v4/acme/commons.go
generated
vendored
12
vendor/github.com/go-acme/lego/v4/acme/commons.go
generated
vendored
@ -181,6 +181,12 @@ type Order struct {
|
|||||||
// certificate (optional, string):
|
// certificate (optional, string):
|
||||||
// A URL for the certificate that has been issued in response to this order
|
// A URL for the certificate that has been issued in response to this order
|
||||||
Certificate string `json:"certificate,omitempty"`
|
Certificate string `json:"certificate,omitempty"`
|
||||||
|
|
||||||
|
// replaces (optional, string):
|
||||||
|
// replaces (string, optional): A string uniquely identifying a
|
||||||
|
// previously-issued certificate which this order is intended to replace.
|
||||||
|
// - https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5
|
||||||
|
Replaces string `json:"replaces,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authorization the ACME authorization object.
|
// Authorization the ACME authorization object.
|
||||||
@ -329,9 +335,11 @@ type RenewalInfoResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RenewalInfoUpdateRequest is the JWS payload for POST requests made to the renewalInfo endpoint.
|
// RenewalInfoUpdateRequest is the JWS payload for POST requests made to the renewalInfo endpoint.
|
||||||
// - (4.2. Updating Renewal Information) https://datatracker.ietf.org/doc/draft-ietf-acme-ari/
|
// - (4.2. RenewalInfo Objects) https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-4.2
|
||||||
type RenewalInfoUpdateRequest struct {
|
type RenewalInfoUpdateRequest struct {
|
||||||
// CertID is the base64url-encoded [RFC4648] bytes of a DER-encoded CertID ASN.1 sequence [RFC6960] with any trailing '=' characters stripped.
|
// CertID is a composite string in the format: base64url(AKI) || '.' || base64url(Serial), where AKI is the
|
||||||
|
// certificate's authority key identifier and Serial is the certificate's serial number. For details, see:
|
||||||
|
// https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-4.1
|
||||||
CertID string `json:"certID"`
|
CertID string `json:"certID"`
|
||||||
// Replaced is required and indicates whether or not the client considers the certificate to have been replaced.
|
// Replaced is required and indicates whether or not the client considers the certificate to have been replaced.
|
||||||
// A certificate is considered replaced when its revocation would not disrupt any ongoing services,
|
// A certificate is considered replaced when its revocation would not disrupt any ongoing services,
|
||||||
|
34
vendor/github.com/go-acme/lego/v4/certcrypto/crypto.go
generated
vendored
34
vendor/github.com/go-acme/lego/v4/certcrypto/crypto.go
generated
vendored
@ -15,6 +15,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ func ParsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
|
|||||||
func ParsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) {
|
func ParsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) {
|
||||||
keyBlockDER, _ := pem.Decode(key)
|
keyBlockDER, _ := pem.Decode(key)
|
||||||
if keyBlockDER == nil {
|
if keyBlockDER == nil {
|
||||||
return nil, fmt.Errorf("invalid PEM block")
|
return nil, errors.New("invalid PEM block")
|
||||||
}
|
}
|
||||||
|
|
||||||
if keyBlockDER.Type != "PRIVATE KEY" && !strings.HasSuffix(keyBlockDER.Type, " PRIVATE KEY") {
|
if keyBlockDER.Type != "PRIVATE KEY" && !strings.HasSuffix(keyBlockDER.Type, " PRIVATE KEY") {
|
||||||
@ -216,6 +217,26 @@ func ParsePEMCertificate(cert []byte) (*x509.Certificate, error) {
|
|||||||
return x509.ParseCertificate(pemBlock.Bytes)
|
return x509.ParseCertificate(pemBlock.Bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetCertificateMainDomain(cert *x509.Certificate) (string, error) {
|
||||||
|
return getMainDomain(cert.Subject, cert.DNSNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCSRMainDomain(cert *x509.CertificateRequest) (string, error) {
|
||||||
|
return getMainDomain(cert.Subject, cert.DNSNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMainDomain(subject pkix.Name, dnsNames []string) (string, error) {
|
||||||
|
if subject.CommonName == "" && len(dnsNames) == 0 {
|
||||||
|
return "", errors.New("missing domain")
|
||||||
|
}
|
||||||
|
|
||||||
|
if subject.CommonName != "" {
|
||||||
|
return subject.CommonName, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return dnsNames[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
func ExtractDomains(cert *x509.Certificate) []string {
|
func ExtractDomains(cert *x509.Certificate) []string {
|
||||||
var domains []string
|
var domains []string
|
||||||
if cert.Subject.CommonName != "" {
|
if cert.Subject.CommonName != "" {
|
||||||
@ -248,7 +269,7 @@ func ExtractDomainsCSR(csr *x509.CertificateRequest) []string {
|
|||||||
|
|
||||||
// loop over the SubjectAltName DNS names
|
// loop over the SubjectAltName DNS names
|
||||||
for _, sanName := range csr.DNSNames {
|
for _, sanName := range csr.DNSNames {
|
||||||
if containsSAN(domains, sanName) {
|
if slices.Contains(domains, sanName) {
|
||||||
// Duplicate; skip this name
|
// Duplicate; skip this name
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -267,15 +288,6 @@ func ExtractDomainsCSR(csr *x509.CertificateRequest) []string {
|
|||||||
return domains
|
return domains
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsSAN(domains []string, sanName string) bool {
|
|
||||||
for _, existingName := range domains {
|
|
||||||
if existingName == sanName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func GeneratePemCert(privateKey *rsa.PrivateKey, domain string, extensions []pkix.Extension) ([]byte, error) {
|
func GeneratePemCert(privateKey *rsa.PrivateKey, domain string, extensions []pkix.Extension) ([]byte, error) {
|
||||||
derBytes, err := generateDerCert(privateKey, time.Time{}, domain, extensions)
|
derBytes, err := generateDerCert(privateKey, time.Time{}, domain, extensions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
3
vendor/github.com/go-acme/lego/v4/certificate/authorization.go
generated
vendored
3
vendor/github.com/go-acme/lego/v4/certificate/authorization.go
generated
vendored
@ -12,6 +12,7 @@ const (
|
|||||||
// limited on the "new-reg", "new-authz" and "new-cert" endpoints.
|
// limited on the "new-reg", "new-authz" and "new-cert" endpoints.
|
||||||
// From the documentation the limitation is 20 requests per second,
|
// From the documentation the limitation is 20 requests per second,
|
||||||
// but using 20 as value doesn't work but 18 do.
|
// but using 20 as value doesn't work but 18 do.
|
||||||
|
// https://letsencrypt.org/docs/rate-limits/
|
||||||
overallRequestLimit = 18
|
overallRequestLimit = 18
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ func (c *Certifier) getAuthorizations(order acme.ExtendedOrder) ([]acme.Authoriz
|
|||||||
var responses []acme.Authorization
|
var responses []acme.Authorization
|
||||||
|
|
||||||
failures := newObtainError()
|
failures := newObtainError()
|
||||||
for i := 0; i < len(order.Authorizations); i++ {
|
for range len(order.Authorizations) {
|
||||||
select {
|
select {
|
||||||
case res := <-resc:
|
case res := <-resc:
|
||||||
responses = append(responses, res)
|
responses = append(responses, res)
|
||||||
|
41
vendor/github.com/go-acme/lego/v4/certificate/certificates.go
generated
vendored
41
vendor/github.com/go-acme/lego/v4/certificate/certificates.go
generated
vendored
@ -63,6 +63,10 @@ type ObtainRequest struct {
|
|||||||
Bundle bool
|
Bundle bool
|
||||||
PreferredChain string
|
PreferredChain string
|
||||||
AlwaysDeactivateAuthorizations bool
|
AlwaysDeactivateAuthorizations bool
|
||||||
|
// A string uniquely identifying a previously-issued certificate which this
|
||||||
|
// order is intended to replace.
|
||||||
|
// - https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5
|
||||||
|
ReplacesCertID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObtainForCSRRequest The request to obtain a certificate matching the CSR passed into it.
|
// ObtainForCSRRequest The request to obtain a certificate matching the CSR passed into it.
|
||||||
@ -79,6 +83,10 @@ type ObtainForCSRRequest struct {
|
|||||||
Bundle bool
|
Bundle bool
|
||||||
PreferredChain string
|
PreferredChain string
|
||||||
AlwaysDeactivateAuthorizations bool
|
AlwaysDeactivateAuthorizations bool
|
||||||
|
// A string uniquely identifying a previously-issued certificate which this
|
||||||
|
// order is intended to replace.
|
||||||
|
// - https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5
|
||||||
|
ReplacesCertID string
|
||||||
}
|
}
|
||||||
|
|
||||||
type resolver interface {
|
type resolver interface {
|
||||||
@ -124,8 +132,9 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
orderOpts := &api.OrderOptions{
|
orderOpts := &api.OrderOptions{
|
||||||
NotBefore: request.NotBefore,
|
NotBefore: request.NotBefore,
|
||||||
NotAfter: request.NotAfter,
|
NotAfter: request.NotAfter,
|
||||||
|
ReplacesCertID: request.ReplacesCertID,
|
||||||
}
|
}
|
||||||
|
|
||||||
order, err := c.core.Orders.NewWithOptions(domains, orderOpts)
|
order, err := c.core.Orders.NewWithOptions(domains, orderOpts)
|
||||||
@ -189,8 +198,9 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
orderOpts := &api.OrderOptions{
|
orderOpts := &api.OrderOptions{
|
||||||
NotBefore: request.NotBefore,
|
NotBefore: request.NotBefore,
|
||||||
NotAfter: request.NotAfter,
|
NotAfter: request.NotAfter,
|
||||||
|
ReplacesCertID: request.ReplacesCertID,
|
||||||
}
|
}
|
||||||
|
|
||||||
order, err := c.core.Orders.NewWithOptions(domains, orderOpts)
|
order, err := c.core.Orders.NewWithOptions(domains, orderOpts)
|
||||||
@ -243,8 +253,10 @@ func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bund
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine certificate name(s) based on the authorization resources
|
commonName := ""
|
||||||
commonName := domains[0]
|
if len(domains[0]) <= 64 {
|
||||||
|
commonName = domains[0]
|
||||||
|
}
|
||||||
|
|
||||||
// RFC8555 Section 7.4 "Applying for Certificate Issuance"
|
// RFC8555 Section 7.4 "Applying for Certificate Issuance"
|
||||||
// https://www.rfc-editor.org/rfc/rfc8555.html#section-7.4
|
// https://www.rfc-editor.org/rfc/rfc8555.html#section-7.4
|
||||||
@ -252,7 +264,12 @@ func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bund
|
|||||||
// Clients SHOULD NOT make any assumptions about the sort order of
|
// Clients SHOULD NOT make any assumptions about the sort order of
|
||||||
// "identifiers" or "authorizations" elements in the returned order
|
// "identifiers" or "authorizations" elements in the returned order
|
||||||
// object.
|
// object.
|
||||||
san := []string{commonName}
|
|
||||||
|
var san []string
|
||||||
|
if commonName != "" {
|
||||||
|
san = append(san, commonName)
|
||||||
|
}
|
||||||
|
|
||||||
for _, auth := range order.Identifiers {
|
for _, auth := range order.Identifiers {
|
||||||
if auth.Value != commonName {
|
if auth.Value != commonName {
|
||||||
san = append(san, auth.Value)
|
san = append(san, auth.Value)
|
||||||
@ -274,9 +291,8 @@ func (c *Certifier) getForCSR(domains []string, order acme.ExtendedOrder, bundle
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
commonName := domains[0]
|
|
||||||
certRes := &Resource{
|
certRes := &Resource{
|
||||||
Domain: commonName,
|
Domain: domains[0],
|
||||||
CertURL: respOrder.Certificate,
|
CertURL: respOrder.Certificate,
|
||||||
PrivateKey: privateKeyPem,
|
PrivateKey: privateKeyPem,
|
||||||
}
|
}
|
||||||
@ -598,8 +614,13 @@ func (c *Certifier) Get(url string, bundle bool) (*Resource, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
domain, err := certcrypto.GetCertificateMainDomain(x509Certs[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &Resource{
|
return &Resource{
|
||||||
Domain: x509Certs[0].Subject.CommonName,
|
Domain: domain,
|
||||||
Certificate: cert,
|
Certificate: cert,
|
||||||
IssuerCertificate: issuer,
|
IssuerCertificate: issuer,
|
||||||
CertURL: url,
|
CertURL: url,
|
||||||
|
149
vendor/github.com/go-acme/lego/v4/certificate/renewal.go
generated
vendored
149
vendor/github.com/go-acme/lego/v4/certificate/renewal.go
generated
vendored
@ -1,16 +1,13 @@
|
|||||||
package certificate
|
package certificate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto"
|
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme"
|
"github.com/go-acme/lego/v4/acme"
|
||||||
@ -18,16 +15,18 @@ import (
|
|||||||
|
|
||||||
// RenewalInfoRequest contains the necessary renewal information.
|
// RenewalInfoRequest contains the necessary renewal information.
|
||||||
type RenewalInfoRequest struct {
|
type RenewalInfoRequest struct {
|
||||||
Cert *x509.Certificate
|
Cert *x509.Certificate
|
||||||
Issuer *x509.Certificate
|
|
||||||
// HashName must be the string representation of a crypto.Hash constant in the golang.org/x/crypto package (e.g. "SHA-256").
|
|
||||||
// The correct value depends on the algorithm expected by the ACME server's ARI implementation.
|
|
||||||
HashName string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenewalInfoResponse is a wrapper around acme.RenewalInfoResponse that provides a method for determining when to renew a certificate.
|
// RenewalInfoResponse is a wrapper around acme.RenewalInfoResponse that provides a method for determining when to renew a certificate.
|
||||||
type RenewalInfoResponse struct {
|
type RenewalInfoResponse struct {
|
||||||
acme.RenewalInfoResponse
|
acme.RenewalInfoResponse
|
||||||
|
|
||||||
|
// RetryAfter header indicating the polling interval that the ACME server recommends.
|
||||||
|
// Conforming clients SHOULD query the renewalInfo URL again after the RetryAfter period has passed,
|
||||||
|
// as the server may provide a different suggestedWindow.
|
||||||
|
// https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-4.2
|
||||||
|
RetryAfter time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldRenewAt determines the optimal renewal time based on the current time (UTC),renewal window suggest by ARI, and the client's willingness to sleep.
|
// ShouldRenewAt determines the optimal renewal time based on the current time (UTC),renewal window suggest by ARI, and the client's willingness to sleep.
|
||||||
@ -72,7 +71,7 @@ func (r *RenewalInfoResponse) ShouldRenewAt(now time.Time, willingToSleep time.D
|
|||||||
//
|
//
|
||||||
// https://datatracker.ietf.org/doc/draft-ietf-acme-ari
|
// https://datatracker.ietf.org/doc/draft-ietf-acme-ari
|
||||||
func (c *Certifier) GetRenewalInfo(req RenewalInfoRequest) (*RenewalInfoResponse, error) {
|
func (c *Certifier) GetRenewalInfo(req RenewalInfoRequest) (*RenewalInfoResponse, error) {
|
||||||
certID, err := makeCertID(req.Cert, req.Issuer, req.HashName)
|
certID, err := MakeARICertID(req.Cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error making certID: %w", err)
|
return nil, fmt.Errorf("error making certID: %w", err)
|
||||||
}
|
}
|
||||||
@ -88,117 +87,43 @@ func (c *Certifier) GetRenewalInfo(req RenewalInfoRequest) (*RenewalInfoResponse
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if retry := resp.Header.Get("Retry-After"); retry != "" {
|
||||||
|
info.RetryAfter, err = time.ParseDuration(retry + "s")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &info, nil
|
return &info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRenewalInfo sends an update to the ACME server's renewal info endpoint to indicate that the client has successfully replaced a certificate.
|
// MakeARICertID constructs a certificate identifier as described in draft-ietf-acme-ari-03, section 4.1.
|
||||||
// A certificate is considered replaced when its revocation would not disrupt any ongoing services,
|
func MakeARICertID(leaf *x509.Certificate) (string, error) {
|
||||||
// for instance because it has been renewed and the new certificate is in use, or because it is no longer in use.
|
|
||||||
//
|
|
||||||
// Note: this endpoint is part of a draft specification, not all ACME servers will implement it.
|
|
||||||
// This method will return api.ErrNoARI if the server does not advertise a renewal info endpoint.
|
|
||||||
//
|
|
||||||
// https://datatracker.ietf.org/doc/draft-ietf-acme-ari
|
|
||||||
func (c *Certifier) UpdateRenewalInfo(req RenewalInfoRequest) error {
|
|
||||||
certID, err := makeCertID(req.Cert, req.Issuer, req.HashName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error making certID: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = c.core.Certificates.UpdateRenewalInfo(acme.RenewalInfoUpdateRequest{
|
|
||||||
CertID: certID,
|
|
||||||
Replaced: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeCertID returns a base64url-encoded string that uniquely identifies a certificate to endpoints
|
|
||||||
// that implement the draft-ietf-acme-ari specification: https://datatracker.ietf.org/doc/draft-ietf-acme-ari.
|
|
||||||
// hashName must be the string representation of a crypto.Hash constant in the golang.org/x/crypto package.
|
|
||||||
// Supported hash functions are SHA-1, SHA-256, SHA-384, and SHA-512.
|
|
||||||
func makeCertID(leaf, issuer *x509.Certificate, hashName string) (string, error) {
|
|
||||||
if leaf == nil {
|
if leaf == nil {
|
||||||
return "", fmt.Errorf("leaf certificate is nil")
|
return "", errors.New("leaf certificate is nil")
|
||||||
}
|
|
||||||
if issuer == nil {
|
|
||||||
return "", fmt.Errorf("issuer certificate is nil")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashFunc crypto.Hash
|
// Marshal the Serial Number into DER.
|
||||||
var oid asn1.ObjectIdentifier
|
der, err := asn1.Marshal(leaf.SerialNumber)
|
||||||
|
|
||||||
switch hashName {
|
|
||||||
// The following correlation of hashFunc to OID is copied from a private mapping in golang.org/x/crypto/ocsp:
|
|
||||||
// https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.8.0:ocsp/ocsp.go;l=156
|
|
||||||
case crypto.SHA1.String():
|
|
||||||
hashFunc = crypto.SHA1
|
|
||||||
oid = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26})
|
|
||||||
|
|
||||||
case crypto.SHA256.String():
|
|
||||||
hashFunc = crypto.SHA256
|
|
||||||
oid = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1})
|
|
||||||
|
|
||||||
case crypto.SHA384.String():
|
|
||||||
hashFunc = crypto.SHA384
|
|
||||||
oid = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2})
|
|
||||||
|
|
||||||
case crypto.SHA512.String():
|
|
||||||
hashFunc = crypto.SHA512
|
|
||||||
oid = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3})
|
|
||||||
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("hashName %q is not supported by this package", hashName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hashFunc.Available() {
|
|
||||||
// This should never happen.
|
|
||||||
return "", fmt.Errorf("hash function %q is not available on your platform", hashFunc)
|
|
||||||
}
|
|
||||||
|
|
||||||
var spki struct {
|
|
||||||
Algorithm pkix.AlgorithmIdentifier
|
|
||||||
PublicKey asn1.BitString
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &spki)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
h := hashFunc.New()
|
|
||||||
h.Write(spki.PublicKey.RightAlign())
|
|
||||||
issuerKeyHash := h.Sum(nil)
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.Write(issuer.RawSubject)
|
|
||||||
issuerNameHash := h.Sum(nil)
|
|
||||||
|
|
||||||
type certID struct {
|
|
||||||
HashAlgorithm pkix.AlgorithmIdentifier
|
|
||||||
IssuerNameHash []byte
|
|
||||||
IssuerKeyHash []byte
|
|
||||||
SerialNumber *big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
// DER-encode the CertID ASN.1 sequence [RFC6960].
|
|
||||||
certIDBytes, err := asn1.Marshal(certID{
|
|
||||||
HashAlgorithm: pkix.AlgorithmIdentifier{
|
|
||||||
Algorithm: oid,
|
|
||||||
},
|
|
||||||
IssuerNameHash: issuerNameHash,
|
|
||||||
IssuerKeyHash: issuerKeyHash,
|
|
||||||
SerialNumber: leaf.SerialNumber,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// base64url-encode [RFC4648] the bytes of the DER-encoded CertID ASN.1 sequence [RFC6960].
|
// Check if the DER encoded bytes are sufficient (at least 3 bytes: tag,
|
||||||
encodedBytes := base64.URLEncoding.EncodeToString(certIDBytes)
|
// length, and value).
|
||||||
|
if len(der) < 3 {
|
||||||
|
return "", errors.New("invalid DER encoding of serial number")
|
||||||
|
}
|
||||||
|
|
||||||
// Any trailing '=' characters MUST be stripped.
|
// Extract only the integer bytes from the DER encoded Serial Number
|
||||||
return strings.TrimRight(encodedBytes, "="), nil
|
// Skipping the first 2 bytes (tag and length).
|
||||||
|
serial := base64.RawURLEncoding.EncodeToString(der[2:])
|
||||||
|
|
||||||
|
// Convert the Authority Key Identifier to base64url encoding without
|
||||||
|
// padding.
|
||||||
|
aki := base64.RawURLEncoding.EncodeToString(leaf.AuthorityKeyId)
|
||||||
|
|
||||||
|
// Construct the final identifier by concatenating AKI and Serial Number.
|
||||||
|
return fmt.Sprintf("%s.%s", aki, serial), nil
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge.go
generated
vendored
5
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme"
|
"github.com/go-acme/lego/v4/acme"
|
||||||
@ -124,7 +125,7 @@ func (c *Challenge) Solve(authz acme.Authorization) error {
|
|||||||
timeout, interval = DefaultPropagationTimeout, DefaultPollingInterval
|
timeout, interval = DefaultPropagationTimeout, DefaultPollingInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("[%s] acme: Checking DNS record propagation using %+v", domain, recursiveNameservers)
|
log.Infof("[%s] acme: Checking DNS record propagation. [nameservers=%s]", domain, strings.Join(recursiveNameservers, ","))
|
||||||
|
|
||||||
time.Sleep(interval)
|
time.Sleep(interval)
|
||||||
|
|
||||||
@ -214,7 +215,7 @@ func getChallengeFQDN(domain string, followCNAME bool) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// recursion counter so it doesn't spin out of control
|
// recursion counter so it doesn't spin out of control
|
||||||
for limit := 0; limit < 50; limit++ {
|
for range 50 {
|
||||||
// Keep following CNAMEs
|
// Keep following CNAMEs
|
||||||
r, err := dnsQuery(fqdn, dns.TypeCNAME, recursiveNameservers, true)
|
r, err := dnsQuery(fqdn, dns.TypeCNAME, recursiveNameservers, true)
|
||||||
|
|
||||||
|
9
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge_manual.go
generated
vendored
9
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge_manual.go
generated
vendored
@ -25,7 +25,7 @@ func (*DNSProviderManual) Present(domain, token, keyAuth string) error {
|
|||||||
|
|
||||||
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("manual: could not find zone: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("lego: Please create the following TXT record in your %s zone:\n", authZone)
|
fmt.Printf("lego: Please create the following TXT record in your %s zone:\n", authZone)
|
||||||
@ -33,8 +33,11 @@ func (*DNSProviderManual) Present(domain, token, keyAuth string) error {
|
|||||||
fmt.Printf("lego: Press 'Enter' when you are done\n")
|
fmt.Printf("lego: Press 'Enter' when you are done\n")
|
||||||
|
|
||||||
_, err = bufio.NewReader(os.Stdin).ReadBytes('\n')
|
_, err = bufio.NewReader(os.Stdin).ReadBytes('\n')
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("manual: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanUp prints instructions for manually removing the TXT record.
|
// CleanUp prints instructions for manually removing the TXT record.
|
||||||
@ -43,7 +46,7 @@ func (*DNSProviderManual) CleanUp(domain, token, keyAuth string) error {
|
|||||||
|
|
||||||
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("manual: could not find zone: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("lego: You can now remove this TXT record from your %s zone:\n", authZone)
|
fmt.Printf("lego: You can now remove this TXT record from your %s zone:\n", authZone)
|
||||||
|
147
vendor/github.com/go-acme/lego/v4/challenge/dns01/nameserver.go
generated
vendored
147
vendor/github.com/go-acme/lego/v4/challenge/dns01/nameserver.go
generated
vendored
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -98,12 +99,12 @@ func lookupNameservers(fqdn string) ([]string, error) {
|
|||||||
|
|
||||||
zone, err := FindZoneByFqdn(fqdn)
|
zone, err := FindZoneByFqdn(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not determine the zone: %w", err)
|
return nil, fmt.Errorf("could not find zone: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := dnsQuery(zone, dns.TypeNS, recursiveNameservers, true)
|
r, err := dnsQuery(zone, dns.TypeNS, recursiveNameservers, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("NS call failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rr := range r.Answer {
|
for _, rr := range r.Answer {
|
||||||
@ -115,7 +116,8 @@ func lookupNameservers(fqdn string) ([]string, error) {
|
|||||||
if len(authoritativeNss) > 0 {
|
if len(authoritativeNss) > 0 {
|
||||||
return authoritativeNss, nil
|
return authoritativeNss, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("could not determine authoritative nameservers")
|
|
||||||
|
return nil, fmt.Errorf("[zone=%s] could not determine authoritative nameservers", zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindPrimaryNsByFqdn determines the primary nameserver of the zone apex for the given fqdn
|
// FindPrimaryNsByFqdn determines the primary nameserver of the zone apex for the given fqdn
|
||||||
@ -129,7 +131,7 @@ func FindPrimaryNsByFqdn(fqdn string) (string, error) {
|
|||||||
func FindPrimaryNsByFqdnCustom(fqdn string, nameservers []string) (string, error) {
|
func FindPrimaryNsByFqdnCustom(fqdn string, nameservers []string) (string, error) {
|
||||||
soa, err := lookupSoaByFqdn(fqdn, nameservers)
|
soa, err := lookupSoaByFqdn(fqdn, nameservers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("[fqdn=%s] %w", fqdn, err)
|
||||||
}
|
}
|
||||||
return soa.primaryNs, nil
|
return soa.primaryNs, nil
|
||||||
}
|
}
|
||||||
@ -145,7 +147,7 @@ func FindZoneByFqdn(fqdn string) (string, error) {
|
|||||||
func FindZoneByFqdnCustom(fqdn string, nameservers []string) (string, error) {
|
func FindZoneByFqdnCustom(fqdn string, nameservers []string) (string, error) {
|
||||||
soa, err := lookupSoaByFqdn(fqdn, nameservers)
|
soa, err := lookupSoaByFqdn(fqdn, nameservers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("[fqdn=%s] %w", fqdn, err)
|
||||||
}
|
}
|
||||||
return soa.zone, nil
|
return soa.zone, nil
|
||||||
}
|
}
|
||||||
@ -170,35 +172,35 @@ func lookupSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error)
|
|||||||
|
|
||||||
func fetchSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error) {
|
func fetchSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error) {
|
||||||
var err error
|
var err error
|
||||||
var in *dns.Msg
|
var r *dns.Msg
|
||||||
|
|
||||||
labelIndexes := dns.Split(fqdn)
|
labelIndexes := dns.Split(fqdn)
|
||||||
for _, index := range labelIndexes {
|
for _, index := range labelIndexes {
|
||||||
domain := fqdn[index:]
|
domain := fqdn[index:]
|
||||||
|
|
||||||
in, err = dnsQuery(domain, dns.TypeSOA, nameservers, true)
|
r, err = dnsQuery(domain, dns.TypeSOA, nameservers, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if in == nil {
|
if r == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch in.Rcode {
|
switch r.Rcode {
|
||||||
case dns.RcodeSuccess:
|
case dns.RcodeSuccess:
|
||||||
// Check if we got a SOA RR in the answer section
|
// Check if we got a SOA RR in the answer section
|
||||||
if len(in.Answer) == 0 {
|
if len(r.Answer) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// CNAME records cannot/should not exist at the root of a zone.
|
// CNAME records cannot/should not exist at the root of a zone.
|
||||||
// So we skip a domain when a CNAME is found.
|
// So we skip a domain when a CNAME is found.
|
||||||
if dnsMsgContainsCNAME(in) {
|
if dnsMsgContainsCNAME(r) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ans := range in.Answer {
|
for _, ans := range r.Answer {
|
||||||
if soa, ok := ans.(*dns.SOA); ok {
|
if soa, ok := ans.(*dns.SOA); ok {
|
||||||
return newSoaCacheEntry(soa), nil
|
return newSoaCacheEntry(soa), nil
|
||||||
}
|
}
|
||||||
@ -207,36 +209,46 @@ func fetchSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error) {
|
|||||||
// NXDOMAIN
|
// NXDOMAIN
|
||||||
default:
|
default:
|
||||||
// Any response code other than NOERROR and NXDOMAIN is treated as error
|
// Any response code other than NOERROR and NXDOMAIN is treated as error
|
||||||
return nil, fmt.Errorf("unexpected response code '%s' for %s", dns.RcodeToString[in.Rcode], domain)
|
return nil, &DNSError{Message: fmt.Sprintf("unexpected response for '%s'", domain), MsgOut: r}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("could not find the start of authority for %s%s", fqdn, formatDNSError(in, err))
|
return nil, &DNSError{Message: fmt.Sprintf("could not find the start of authority for '%s'", fqdn), MsgOut: r, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dnsMsgContainsCNAME checks for a CNAME answer in msg.
|
// dnsMsgContainsCNAME checks for a CNAME answer in msg.
|
||||||
func dnsMsgContainsCNAME(msg *dns.Msg) bool {
|
func dnsMsgContainsCNAME(msg *dns.Msg) bool {
|
||||||
for _, ans := range msg.Answer {
|
return slices.ContainsFunc(msg.Answer, func(rr dns.RR) bool {
|
||||||
if _, ok := ans.(*dns.CNAME); ok {
|
_, ok := rr.(*dns.CNAME)
|
||||||
return true
|
return ok
|
||||||
}
|
})
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive bool) (*dns.Msg, error) {
|
func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive bool) (*dns.Msg, error) {
|
||||||
m := createDNSMsg(fqdn, rtype, recursive)
|
m := createDNSMsg(fqdn, rtype, recursive)
|
||||||
|
|
||||||
var in *dns.Msg
|
if len(nameservers) == 0 {
|
||||||
|
return nil, &DNSError{Message: "empty list of nameservers"}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r *dns.Msg
|
||||||
var err error
|
var err error
|
||||||
|
var errAll error
|
||||||
|
|
||||||
for _, ns := range nameservers {
|
for _, ns := range nameservers {
|
||||||
in, err = sendDNSQuery(m, ns)
|
r, err = sendDNSQuery(m, ns)
|
||||||
if err == nil && len(in.Answer) > 0 {
|
if err == nil && len(r.Answer) > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errAll = errors.Join(errAll, err)
|
||||||
}
|
}
|
||||||
return in, err
|
|
||||||
|
if err != nil {
|
||||||
|
return r, errAll
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDNSMsg(fqdn string, rtype uint16, recursive bool) *dns.Msg {
|
func createDNSMsg(fqdn string, rtype uint16, recursive bool) *dns.Msg {
|
||||||
@ -254,37 +266,82 @@ func createDNSMsg(fqdn string, rtype uint16, recursive bool) *dns.Msg {
|
|||||||
func sendDNSQuery(m *dns.Msg, ns string) (*dns.Msg, error) {
|
func sendDNSQuery(m *dns.Msg, ns string) (*dns.Msg, error) {
|
||||||
if ok, _ := strconv.ParseBool(os.Getenv("LEGO_EXPERIMENTAL_DNS_TCP_ONLY")); ok {
|
if ok, _ := strconv.ParseBool(os.Getenv("LEGO_EXPERIMENTAL_DNS_TCP_ONLY")); ok {
|
||||||
tcp := &dns.Client{Net: "tcp", Timeout: dnsTimeout}
|
tcp := &dns.Client{Net: "tcp", Timeout: dnsTimeout}
|
||||||
in, _, err := tcp.Exchange(m, ns)
|
r, _, err := tcp.Exchange(m, ns)
|
||||||
|
if err != nil {
|
||||||
|
return r, &DNSError{Message: "DNS call error", MsgIn: m, NS: ns, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
return in, err
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
udp := &dns.Client{Net: "udp", Timeout: dnsTimeout}
|
udp := &dns.Client{Net: "udp", Timeout: dnsTimeout}
|
||||||
in, _, err := udp.Exchange(m, ns)
|
r, _, err := udp.Exchange(m, ns)
|
||||||
|
|
||||||
if in != nil && in.Truncated {
|
if r != nil && r.Truncated {
|
||||||
tcp := &dns.Client{Net: "tcp", Timeout: dnsTimeout}
|
tcp := &dns.Client{Net: "tcp", Timeout: dnsTimeout}
|
||||||
// If the TCP request succeeds, the "err" will reset to nil
|
// If the TCP request succeeds, the "err" will reset to nil
|
||||||
in, _, err = tcp.Exchange(m, ns)
|
r, _, err = tcp.Exchange(m, ns)
|
||||||
}
|
|
||||||
|
|
||||||
return in, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatDNSError(msg *dns.Msg, err error) string {
|
|
||||||
var parts []string
|
|
||||||
|
|
||||||
if msg != nil {
|
|
||||||
parts = append(parts, dns.RcodeToString[msg.Rcode])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
parts = append(parts, err.Error())
|
return r, &DNSError{Message: "DNS call error", MsgIn: m, NS: ns, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(parts) > 0 {
|
return r, nil
|
||||||
return ": " + strings.Join(parts, " ")
|
}
|
||||||
}
|
|
||||||
|
// DNSError error related to DNS calls.
|
||||||
return ""
|
type DNSError struct {
|
||||||
|
Message string
|
||||||
|
NS string
|
||||||
|
MsgIn *dns.Msg
|
||||||
|
MsgOut *dns.Msg
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSError) Error() string {
|
||||||
|
var details []string
|
||||||
|
if d.NS != "" {
|
||||||
|
details = append(details, "ns="+d.NS)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.MsgIn != nil && len(d.MsgIn.Question) > 0 {
|
||||||
|
details = append(details, fmt.Sprintf("question='%s'", formatQuestions(d.MsgIn.Question)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.MsgOut != nil {
|
||||||
|
if d.MsgIn == nil || len(d.MsgIn.Question) == 0 {
|
||||||
|
details = append(details, fmt.Sprintf("question='%s'", formatQuestions(d.MsgOut.Question)))
|
||||||
|
}
|
||||||
|
|
||||||
|
details = append(details, "code="+dns.RcodeToString[d.MsgOut.Rcode])
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := "DNS error"
|
||||||
|
if d.Message != "" {
|
||||||
|
msg = d.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Err != nil {
|
||||||
|
msg += ": " + d.Err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(details) > 0 {
|
||||||
|
msg += " [" + strings.Join(details, ", ") + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSError) Unwrap() error {
|
||||||
|
return d.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatQuestions(questions []dns.Question) string {
|
||||||
|
var parts []string
|
||||||
|
for _, question := range questions {
|
||||||
|
parts = append(parts, strings.ReplaceAll(strings.TrimPrefix(question.String(), ";"), "\t", " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(parts, ";")
|
||||||
}
|
}
|
||||||
|
87
vendor/github.com/go-acme/lego/v4/platform/config/env/env.go
generated
vendored
87
vendor/github.com/go-acme/lego/v4/platform/config/env/env.go
generated
vendored
@ -78,15 +78,26 @@ func GetWithFallback(groups ...[]string) (map[string]string, error) {
|
|||||||
return values, nil
|
return values, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetOneWithFallback[T any](main string, defaultValue T, fn func(string) (T, error), names ...string) T {
|
||||||
|
v, _ := getOneWithFallback(main, names...)
|
||||||
|
|
||||||
|
value, err := fn(v)
|
||||||
|
if err != nil {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
func getOneWithFallback(main string, names ...string) (string, string) {
|
func getOneWithFallback(main string, names ...string) (string, string) {
|
||||||
value := GetOrFile(main)
|
value := GetOrFile(main)
|
||||||
if len(value) > 0 {
|
if value != "" {
|
||||||
return value, main
|
return value, main
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
value := GetOrFile(name)
|
value := GetOrFile(name)
|
||||||
if len(value) > 0 {
|
if value != "" {
|
||||||
return value, main
|
return value, main
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,43 +105,32 @@ func getOneWithFallback(main string, names ...string) (string, string) {
|
|||||||
return "", main
|
return "", main
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrDefaultInt returns the given environment variable value as an integer.
|
|
||||||
// Returns the default if the env var cannot be coopered to an int, or is not found.
|
|
||||||
func GetOrDefaultInt(envVar string, defaultValue int) int {
|
|
||||||
v, err := strconv.Atoi(GetOrFile(envVar))
|
|
||||||
if err != nil {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOrDefaultSecond returns the given environment variable value as a time.Duration (second).
|
|
||||||
// Returns the default if the env var cannot be coopered to an int, or is not found.
|
|
||||||
func GetOrDefaultSecond(envVar string, defaultValue time.Duration) time.Duration {
|
|
||||||
v := GetOrDefaultInt(envVar, -1)
|
|
||||||
if v < 0 {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Duration(v) * time.Second
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOrDefaultString returns the given environment variable value as a string.
|
// GetOrDefaultString returns the given environment variable value as a string.
|
||||||
// Returns the default if the env var cannot be found.
|
// Returns the default if the env var cannot be found.
|
||||||
func GetOrDefaultString(envVar, defaultValue string) string {
|
func GetOrDefaultString(envVar string, defaultValue string) string {
|
||||||
v := GetOrFile(envVar)
|
return getOrDefault(envVar, defaultValue, ParseString)
|
||||||
if v == "" {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrDefaultBool returns the given environment variable value as a boolean.
|
// GetOrDefaultBool returns the given environment variable value as a boolean.
|
||||||
// Returns the default if the env var cannot be coopered to a boolean, or is not found.
|
// Returns the default if the env var cannot be coopered to a boolean, or is not found.
|
||||||
func GetOrDefaultBool(envVar string, defaultValue bool) bool {
|
func GetOrDefaultBool(envVar string, defaultValue bool) bool {
|
||||||
v, err := strconv.ParseBool(GetOrFile(envVar))
|
return getOrDefault(envVar, defaultValue, strconv.ParseBool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrDefaultInt returns the given environment variable value as an integer.
|
||||||
|
// Returns the default if the env var cannot be coopered to an int, or is not found.
|
||||||
|
func GetOrDefaultInt(envVar string, defaultValue int) int {
|
||||||
|
return getOrDefault(envVar, defaultValue, strconv.Atoi)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrDefaultSecond returns the given environment variable value as a time.Duration (second).
|
||||||
|
// Returns the default if the env var cannot be coopered to an int, or is not found.
|
||||||
|
func GetOrDefaultSecond(envVar string, defaultValue time.Duration) time.Duration {
|
||||||
|
return getOrDefault(envVar, defaultValue, ParseSecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOrDefault[T any](envVar string, defaultValue T, fn func(string) (T, error)) T {
|
||||||
|
v, err := fn(GetOrFile(envVar))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
@ -161,3 +161,26 @@ func GetOrFile(envVar string) string {
|
|||||||
|
|
||||||
return strings.TrimSuffix(string(fileContents), "\n")
|
return strings.TrimSuffix(string(fileContents), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseSecond parses env var value (string) to a second (time.Duration).
|
||||||
|
func ParseSecond(s string) (time.Duration, error) {
|
||||||
|
v, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if v < 0 {
|
||||||
|
return 0, fmt.Errorf("unsupported value: %d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Duration(v) * time.Second, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseString parses env var value (string) to a string but throws an error when the string is empty.
|
||||||
|
func ParseString(s string) (string, error) {
|
||||||
|
if s == "" {
|
||||||
|
return "", errors.New("empty string")
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
133
vendor/github.com/go-acme/lego/v4/providers/dns/internal/errutils/client.go
generated
vendored
Normal file
133
vendor/github.com/go-acme/lego/v4/providers/dns/internal/errutils/client.go
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
package errutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const legoDebugClientVerboseError = "LEGO_DEBUG_CLIENT_VERBOSE_ERROR"
|
||||||
|
|
||||||
|
// HTTPDoError uses with `(http.Client).Do` error.
|
||||||
|
type HTTPDoError struct {
|
||||||
|
req *http.Request
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPDoError creates a new HTTPDoError.
|
||||||
|
func NewHTTPDoError(req *http.Request, err error) *HTTPDoError {
|
||||||
|
return &HTTPDoError{req: req, err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPDoError) Error() string {
|
||||||
|
msg := "unable to communicate with the API server:"
|
||||||
|
|
||||||
|
if ok, _ := strconv.ParseBool(os.Getenv(legoDebugClientVerboseError)); ok {
|
||||||
|
msg += fmt.Sprintf(" [request: %s %s]", h.req.Method, h.req.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.err == nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg + fmt.Sprintf(" error: %v", h.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPDoError) Unwrap() error {
|
||||||
|
return h.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadResponseError use with `io.ReadAll` when reading response body.
|
||||||
|
type ReadResponseError struct {
|
||||||
|
req *http.Request
|
||||||
|
StatusCode int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReadResponseError creates a new ReadResponseError.
|
||||||
|
func NewReadResponseError(req *http.Request, statusCode int, err error) *ReadResponseError {
|
||||||
|
return &ReadResponseError{req: req, StatusCode: statusCode, err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ReadResponseError) Error() string {
|
||||||
|
msg := "unable to read response body:"
|
||||||
|
|
||||||
|
if ok, _ := strconv.ParseBool(os.Getenv(legoDebugClientVerboseError)); ok {
|
||||||
|
msg += fmt.Sprintf(" [request: %s %s]", r.req.Method, r.req.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += fmt.Sprintf(" [status code: %d]", r.StatusCode)
|
||||||
|
|
||||||
|
if r.err == nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg + fmt.Sprintf(" error: %v", r.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ReadResponseError) Unwrap() error {
|
||||||
|
return r.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalError uses with `json.Unmarshal` or `xml.Unmarshal` when reading response body.
|
||||||
|
type UnmarshalError struct {
|
||||||
|
req *http.Request
|
||||||
|
StatusCode int
|
||||||
|
Body []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnmarshalError creates a new UnmarshalError.
|
||||||
|
func NewUnmarshalError(req *http.Request, statusCode int, body []byte, err error) *UnmarshalError {
|
||||||
|
return &UnmarshalError{req: req, StatusCode: statusCode, Body: bytes.TrimSpace(body), err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalError) Error() string {
|
||||||
|
msg := "unable to unmarshal response:"
|
||||||
|
|
||||||
|
if ok, _ := strconv.ParseBool(os.Getenv(legoDebugClientVerboseError)); ok {
|
||||||
|
msg += fmt.Sprintf(" [request: %s %s]", u.req.Method, u.req.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += fmt.Sprintf(" [status code: %d] body: %s", u.StatusCode, string(u.Body))
|
||||||
|
|
||||||
|
if u.err == nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg + fmt.Sprintf(" error: %v", u.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalError) Unwrap() error {
|
||||||
|
return u.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnexpectedStatusCodeError use when the status of the response is unexpected but there is no API error type.
|
||||||
|
type UnexpectedStatusCodeError struct {
|
||||||
|
req *http.Request
|
||||||
|
StatusCode int
|
||||||
|
Body []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnexpectedStatusCodeError creates a new UnexpectedStatusCodeError.
|
||||||
|
func NewUnexpectedStatusCodeError(req *http.Request, statusCode int, body []byte) *UnexpectedStatusCodeError {
|
||||||
|
return &UnexpectedStatusCodeError{req: req, StatusCode: statusCode, Body: bytes.TrimSpace(body)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUnexpectedResponseStatusCodeError(req *http.Request, resp *http.Response) *UnexpectedStatusCodeError {
|
||||||
|
raw, _ := io.ReadAll(resp.Body)
|
||||||
|
return &UnexpectedStatusCodeError{req: req, StatusCode: resp.StatusCode, Body: bytes.TrimSpace(raw)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnexpectedStatusCodeError) Error() string {
|
||||||
|
msg := "unexpected status code:"
|
||||||
|
|
||||||
|
if ok, _ := strconv.ParseBool(os.Getenv(legoDebugClientVerboseError)); ok {
|
||||||
|
msg += fmt.Sprintf(" [request: %s %s]", u.req.Method, u.req.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg + fmt.Sprintf(" [status code: %d] body: %s", u.StatusCode, string(u.Body))
|
||||||
|
}
|
158
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.go
generated
vendored
158
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.go
generated
vendored
@ -14,16 +14,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// OVH API reference: https://eu.api.ovh.com/
|
// OVH API reference: https://eu.api.ovh.com/
|
||||||
// Create a Token: https://eu.api.ovh.com/createToken/
|
// Create a Token: https://eu.api.ovh.com/createToken/
|
||||||
|
// Create a OAuth2 client: https://eu.api.ovh.com/console-preview/?section=%2Fme&branch=v1#post-/me/api/oauth2/client
|
||||||
|
|
||||||
// Environment variables names.
|
// Environment variables names.
|
||||||
const (
|
const (
|
||||||
envNamespace = "OVH_"
|
envNamespace = "OVH_"
|
||||||
|
|
||||||
EnvEndpoint = envNamespace + "ENDPOINT"
|
EnvEndpoint = envNamespace + "ENDPOINT"
|
||||||
EnvApplicationKey = envNamespace + "APPLICATION_KEY"
|
|
||||||
EnvApplicationSecret = envNamespace + "APPLICATION_SECRET"
|
|
||||||
EnvConsumerKey = envNamespace + "CONSUMER_KEY"
|
|
||||||
|
|
||||||
EnvTTL = envNamespace + "TTL"
|
EnvTTL = envNamespace + "TTL"
|
||||||
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
||||||
@ -31,6 +29,19 @@ const (
|
|||||||
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
|
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Authenticate using application key.
|
||||||
|
const (
|
||||||
|
EnvApplicationKey = envNamespace + "APPLICATION_KEY"
|
||||||
|
EnvApplicationSecret = envNamespace + "APPLICATION_SECRET"
|
||||||
|
EnvConsumerKey = envNamespace + "CONSUMER_KEY"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Authenticate using OAuth2 client.
|
||||||
|
const (
|
||||||
|
EnvClientID = envNamespace + "CLIENT_ID"
|
||||||
|
EnvClientSecret = envNamespace + "CLIENT_SECRET"
|
||||||
|
)
|
||||||
|
|
||||||
// Record a DNS record.
|
// Record a DNS record.
|
||||||
type Record struct {
|
type Record struct {
|
||||||
ID int64 `json:"id,omitempty"`
|
ID int64 `json:"id,omitempty"`
|
||||||
@ -41,18 +52,32 @@ type Record struct {
|
|||||||
Zone string `json:"zone,omitempty"`
|
Zone string `json:"zone,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OAuth2Config the OAuth2 specific configuration.
|
||||||
|
type OAuth2Config struct {
|
||||||
|
ClientID string
|
||||||
|
ClientSecret string
|
||||||
|
}
|
||||||
|
|
||||||
// Config is used to configure the creation of the DNSProvider.
|
// Config is used to configure the creation of the DNSProvider.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
APIEndpoint string
|
APIEndpoint string
|
||||||
ApplicationKey string
|
|
||||||
ApplicationSecret string
|
ApplicationKey string
|
||||||
ConsumerKey string
|
ApplicationSecret string
|
||||||
|
ConsumerKey string
|
||||||
|
|
||||||
|
OAuth2Config *OAuth2Config
|
||||||
|
|
||||||
PropagationTimeout time.Duration
|
PropagationTimeout time.Duration
|
||||||
PollingInterval time.Duration
|
PollingInterval time.Duration
|
||||||
TTL int
|
TTL int
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) hasAppKeyAuth() bool {
|
||||||
|
return c.ApplicationKey != "" || c.ApplicationSecret != "" || c.ConsumerKey != ""
|
||||||
|
}
|
||||||
|
|
||||||
// NewDefaultConfig returns a default configuration for the DNSProvider.
|
// NewDefaultConfig returns a default configuration for the DNSProvider.
|
||||||
func NewDefaultConfig() *Config {
|
func NewDefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
@ -77,17 +102,11 @@ type DNSProvider struct {
|
|||||||
// Credentials must be passed in the environment variables:
|
// Credentials must be passed in the environment variables:
|
||||||
// OVH_ENDPOINT (must be either "ovh-eu" or "ovh-ca"), OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY.
|
// OVH_ENDPOINT (must be either "ovh-eu" or "ovh-ca"), OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY.
|
||||||
func NewDNSProvider() (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
values, err := env.Get(EnvEndpoint, EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey)
|
config, err := createConfigFromEnvVars()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ovh: %w", err)
|
return nil, fmt.Errorf("ovh: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := NewDefaultConfig()
|
|
||||||
config.APIEndpoint = values[EnvEndpoint]
|
|
||||||
config.ApplicationKey = values[EnvApplicationKey]
|
|
||||||
config.ApplicationSecret = values[EnvApplicationSecret]
|
|
||||||
config.ConsumerKey = values[EnvConsumerKey]
|
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,16 +116,11 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
|||||||
return nil, errors.New("ovh: the configuration of the DNS provider is nil")
|
return nil, errors.New("ovh: the configuration of the DNS provider is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.APIEndpoint == "" || config.ApplicationKey == "" || config.ApplicationSecret == "" || config.ConsumerKey == "" {
|
if config.OAuth2Config != nil && config.hasAppKeyAuth() {
|
||||||
return nil, errors.New("ovh: credentials missing")
|
return nil, errors.New("ovh: can't use both authentication systems (ApplicationKey and OAuth2)")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := ovh.NewClient(
|
client, err := newClient(config)
|
||||||
config.APIEndpoint,
|
|
||||||
config.ApplicationKey,
|
|
||||||
config.ApplicationSecret,
|
|
||||||
config.ConsumerKey,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ovh: %w", err)
|
return nil, fmt.Errorf("ovh: %w", err)
|
||||||
}
|
}
|
||||||
@ -127,7 +141,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||||||
// Parse domain name
|
// Parse domain name
|
||||||
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ovh: could not find zone for domain %q (%s): %w", domain, info.EffectiveFQDN, err)
|
return fmt.Errorf("ovh: could not find zone for domain %q: %w", domain, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authZone = dns01.UnFqdn(authZone)
|
authZone = dns01.UnFqdn(authZone)
|
||||||
@ -175,7 +189,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
|||||||
|
|
||||||
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ovh: could not find zone for domain %q (%s): %w", domain, info.EffectiveFQDN, err)
|
return fmt.Errorf("ovh: could not find zone for domain %q: %w", domain, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authZone = dns01.UnFqdn(authZone)
|
authZone = dns01.UnFqdn(authZone)
|
||||||
@ -207,3 +221,95 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
|||||||
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
return d.config.PropagationTimeout, d.config.PollingInterval
|
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createConfigFromEnvVars() (*Config, error) {
|
||||||
|
firstAppKeyEnvVar := findFirstValuedEnvVar(EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey)
|
||||||
|
firstOAuth2EnvVar := findFirstValuedEnvVar(EnvClientID, EnvClientSecret)
|
||||||
|
|
||||||
|
if firstAppKeyEnvVar != "" && firstOAuth2EnvVar != "" {
|
||||||
|
return nil, fmt.Errorf("can't use both %s and %s at the same time", firstAppKeyEnvVar, firstOAuth2EnvVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
|
||||||
|
if firstOAuth2EnvVar != "" {
|
||||||
|
values, err := env.Get(EnvEndpoint, EnvClientID, EnvClientSecret)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config.APIEndpoint = values[EnvEndpoint]
|
||||||
|
config.OAuth2Config = &OAuth2Config{
|
||||||
|
ClientID: values[EnvClientID],
|
||||||
|
ClientSecret: values[EnvClientSecret],
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := env.Get(EnvEndpoint, EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config.APIEndpoint = values[EnvEndpoint]
|
||||||
|
|
||||||
|
config.ApplicationKey = values[EnvApplicationKey]
|
||||||
|
config.ApplicationSecret = values[EnvApplicationSecret]
|
||||||
|
config.ConsumerKey = values[EnvConsumerKey]
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findFirstValuedEnvVar(envVars ...string) string {
|
||||||
|
for _, envVar := range envVars {
|
||||||
|
if env.GetOrFile(envVar) != "" {
|
||||||
|
return envVar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClient(config *Config) (*ovh.Client, error) {
|
||||||
|
if config.OAuth2Config == nil {
|
||||||
|
return newClientApplicationKey(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newClientOAuth2(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClientApplicationKey(config *Config) (*ovh.Client, error) {
|
||||||
|
if config.APIEndpoint == "" || config.ApplicationKey == "" || config.ApplicationSecret == "" || config.ConsumerKey == "" {
|
||||||
|
return nil, errors.New("credentials are missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := ovh.NewClient(
|
||||||
|
config.APIEndpoint,
|
||||||
|
config.ApplicationKey,
|
||||||
|
config.ApplicationSecret,
|
||||||
|
config.ConsumerKey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("new client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClientOAuth2(config *Config) (*ovh.Client, error) {
|
||||||
|
if config.APIEndpoint == "" || config.OAuth2Config.ClientID == "" || config.OAuth2Config.ClientSecret == "" {
|
||||||
|
return nil, errors.New("credentials are missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := ovh.NewOAuth2Client(
|
||||||
|
config.APIEndpoint,
|
||||||
|
config.OAuth2Config.ClientID,
|
||||||
|
config.OAuth2Config.ClientSecret,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("new OAuth2 client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
33
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.toml
generated
vendored
33
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.toml
generated
vendored
@ -5,11 +5,20 @@ Code = "ovh"
|
|||||||
Since = "v0.4.0"
|
Since = "v0.4.0"
|
||||||
|
|
||||||
Example = '''
|
Example = '''
|
||||||
|
# Application Key authentication:
|
||||||
|
|
||||||
OVH_APPLICATION_KEY=1234567898765432 \
|
OVH_APPLICATION_KEY=1234567898765432 \
|
||||||
OVH_APPLICATION_SECRET=b9841238feb177a84330febba8a832089 \
|
OVH_APPLICATION_SECRET=b9841238feb177a84330febba8a832089 \
|
||||||
OVH_CONSUMER_KEY=256vfsd347245sdfg \
|
OVH_CONSUMER_KEY=256vfsd347245sdfg \
|
||||||
OVH_ENDPOINT=ovh-eu \
|
OVH_ENDPOINT=ovh-eu \
|
||||||
lego --email you@example.com --dns ovh --domains my.example.org run
|
lego --email you@example.com --dns ovh --domains my.example.org run
|
||||||
|
|
||||||
|
# Or OAuth2:
|
||||||
|
|
||||||
|
OVH_CLIENT_ID=yyy \
|
||||||
|
OVH_CLIENT_SECRET=xxx \
|
||||||
|
OVH_ENDPOINT=ovh-eu \
|
||||||
|
lego --email you@example.com --dns ovh --domains my.example.org run
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Additional = '''
|
Additional = '''
|
||||||
@ -33,14 +42,32 @@ When requesting the consumer key, the following configuration can be used to def
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## OAuth2 Client Credentials
|
||||||
|
|
||||||
|
Another method for authentication is by using OAuth2 client credentials.
|
||||||
|
|
||||||
|
An IAM policy and service account can be created by following the [OVH guide](https://help.ovhcloud.com/csm/en-manage-service-account?id=kb_article_view&sysparm_article=KB0059343).
|
||||||
|
|
||||||
|
Following IAM policies need to be authorized for the affected domain:
|
||||||
|
|
||||||
|
* dnsZone:apiovh:record/create
|
||||||
|
* dnsZone:apiovh:record/delete
|
||||||
|
* dnsZone:apiovh:refresh
|
||||||
|
|
||||||
|
## Important Note
|
||||||
|
|
||||||
|
Both authentication methods cannot be used at the same time.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[Configuration]
|
[Configuration]
|
||||||
[Configuration.Credentials]
|
[Configuration.Credentials]
|
||||||
OVH_ENDPOINT = "Endpoint URL (ovh-eu or ovh-ca)"
|
OVH_ENDPOINT = "Endpoint URL (ovh-eu or ovh-ca)"
|
||||||
OVH_APPLICATION_KEY = "Application key"
|
OVH_APPLICATION_KEY = "Application key (Application Key authentication)"
|
||||||
OVH_APPLICATION_SECRET = "Application secret"
|
OVH_APPLICATION_SECRET = "Application secret (Application Key authentication)"
|
||||||
OVH_CONSUMER_KEY = "Consumer key"
|
OVH_CONSUMER_KEY = "Consumer key (Application Key authentication)"
|
||||||
|
OVH_CLIENT_ID = "Client ID (OAuth2)"
|
||||||
|
OVH_CLIENT_SECRET = "Client secret (OAuth2)"
|
||||||
[Configuration.Additional]
|
[Configuration.Additional]
|
||||||
OVH_POLLING_INTERVAL = "Time between DNS propagation check"
|
OVH_POLLING_INTERVAL = "Time between DNS propagation check"
|
||||||
OVH_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
|
OVH_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
|
||||||
|
228
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/internal/client.go
generated
vendored
Normal file
228
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/internal/client.go
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns/internal/errutils"
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client the PowerDNS API client.
|
||||||
|
type Client struct {
|
||||||
|
serverName string
|
||||||
|
apiKey string
|
||||||
|
|
||||||
|
apiVersion int
|
||||||
|
|
||||||
|
Host *url.URL
|
||||||
|
HTTPClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new Client.
|
||||||
|
func NewClient(host *url.URL, serverName string, apiVersion int, apiKey string) *Client {
|
||||||
|
return &Client{
|
||||||
|
serverName: serverName,
|
||||||
|
apiKey: apiKey,
|
||||||
|
apiVersion: apiVersion,
|
||||||
|
Host: host,
|
||||||
|
HTTPClient: &http.Client{Timeout: 5 * time.Second},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) APIVersion() int {
|
||||||
|
return c.apiVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) SetAPIVersion(ctx context.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
c.apiVersion, err = c.getAPIVersion(ctx)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getAPIVersion(ctx context.Context) (int, error) {
|
||||||
|
endpoint := c.joinPath("/", "api")
|
||||||
|
|
||||||
|
req, err := newJSONRequest(ctx, http.MethodGet, endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := c.do(req)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var versions []apiVersion
|
||||||
|
err = json.Unmarshal(result, &versions)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
latestVersion := 0
|
||||||
|
for _, v := range versions {
|
||||||
|
if v.Version > latestVersion {
|
||||||
|
latestVersion = v.Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return latestVersion, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetHostedZone(ctx context.Context, authZone string) (*HostedZone, error) {
|
||||||
|
endpoint := c.joinPath("/", "servers", c.serverName, "zones", dns.Fqdn(authZone))
|
||||||
|
|
||||||
|
req, err := newJSONRequest(ctx, http.MethodGet, endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := c.do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var zone HostedZone
|
||||||
|
err = json.Unmarshal(result, &zone)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert pre-v1 API result
|
||||||
|
if len(zone.Records) > 0 {
|
||||||
|
zone.RRSets = []RRSet{}
|
||||||
|
for _, record := range zone.Records {
|
||||||
|
set := RRSet{
|
||||||
|
Name: record.Name,
|
||||||
|
Type: record.Type,
|
||||||
|
Records: []Record{record},
|
||||||
|
}
|
||||||
|
zone.RRSets = append(zone.RRSets, set)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &zone, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) UpdateRecords(ctx context.Context, zone *HostedZone, sets RRSets) error {
|
||||||
|
endpoint := c.joinPath("/", "servers", c.serverName, "zones", zone.ID)
|
||||||
|
|
||||||
|
req, err := newJSONRequest(ctx, http.MethodPatch, endpoint, sets)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Notify(ctx context.Context, zone *HostedZone) error {
|
||||||
|
if c.apiVersion < 1 || zone.Kind != "Master" && zone.Kind != "Slave" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint := c.joinPath("/", "servers", c.serverName, "zones", zone.ID, "notify")
|
||||||
|
|
||||||
|
req, err := newJSONRequest(ctx, http.MethodPut, endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) joinPath(elem ...string) *url.URL {
|
||||||
|
p := path.Join(elem...)
|
||||||
|
|
||||||
|
if p != "/api" && c.apiVersion > 0 && !strings.HasPrefix(p, "/api/v") {
|
||||||
|
p = path.Join("/api", "v"+strconv.Itoa(c.apiVersion), p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Host.JoinPath(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) do(req *http.Request) (json.RawMessage, error) {
|
||||||
|
req.Header.Set("X-API-Key", c.apiKey)
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errutils.NewHTTPDoError(req, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusUnprocessableEntity && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
|
||||||
|
return nil, errutils.NewUnexpectedResponseStatusCodeError(req, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg json.RawMessage
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&msg)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
// empty body
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
// other error
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for PowerDNS error message
|
||||||
|
if len(msg) > 0 && msg[0] == '{' {
|
||||||
|
var errInfo apiError
|
||||||
|
err = json.Unmarshal(msg, &errInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errutils.NewUnmarshalError(req, resp.StatusCode, msg, err)
|
||||||
|
}
|
||||||
|
if errInfo.ShortMsg != "" {
|
||||||
|
return nil, fmt.Errorf("error talking to PDNS API: %w", errInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newJSONRequest(ctx context.Context, method string, endpoint *url.URL, payload any) (*http.Request, error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
if payload != nil {
|
||||||
|
err := json.NewEncoder(buf).Encode(payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create request JSON body: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, method, strings.TrimSuffix(endpoint.String(), "/"), buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to create request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Accept", "application/json")
|
||||||
|
|
||||||
|
// PowerDNS doesn't follow HTTP convention about the "Content-Type" header.
|
||||||
|
if method != http.MethodGet && method != http.MethodDelete {
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
}
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
}
|
48
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/internal/types.go
generated
vendored
Normal file
48
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/internal/types.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
type Record struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
Disabled bool `json:"disabled"`
|
||||||
|
|
||||||
|
// pre-v1 API
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
TTL int `json:"ttl,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostedZone struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
RRSets []RRSet `json:"rrsets"`
|
||||||
|
|
||||||
|
// pre-v1 API
|
||||||
|
Records []Record `json:"records"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RRSet struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
ChangeType string `json:"changetype"`
|
||||||
|
Records []Record `json:"records,omitempty"`
|
||||||
|
TTL int `json:"ttl,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RRSets struct {
|
||||||
|
RRSets []RRSet `json:"rrsets"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type apiError struct {
|
||||||
|
ShortMsg string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a apiError) Error() string {
|
||||||
|
return a.ShortMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
type apiVersion struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
}
|
228
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/pdns.go
generated
vendored
Normal file
228
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/pdns.go
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
// Package pdns implements a DNS provider for solving the DNS-01 challenge using PowerDNS nameserver.
|
||||||
|
package pdns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||||
|
"github.com/go-acme/lego/v4/log"
|
||||||
|
"github.com/go-acme/lego/v4/platform/config/env"
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns/pdns/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Environment variables names.
|
||||||
|
const (
|
||||||
|
envNamespace = "PDNS_"
|
||||||
|
|
||||||
|
EnvAPIKey = envNamespace + "API_KEY"
|
||||||
|
EnvAPIURL = envNamespace + "API_URL"
|
||||||
|
|
||||||
|
EnvTTL = envNamespace + "TTL"
|
||||||
|
EnvAPIVersion = envNamespace + "API_VERSION"
|
||||||
|
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
||||||
|
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
|
||||||
|
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
|
||||||
|
EnvServerName = envNamespace + "SERVER_NAME"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is used to configure the creation of the DNSProvider.
|
||||||
|
type Config struct {
|
||||||
|
APIKey string
|
||||||
|
Host *url.URL
|
||||||
|
ServerName string
|
||||||
|
APIVersion int
|
||||||
|
PropagationTimeout time.Duration
|
||||||
|
PollingInterval time.Duration
|
||||||
|
TTL int
|
||||||
|
HTTPClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultConfig returns a default configuration for the DNSProvider.
|
||||||
|
func NewDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
ServerName: env.GetOrDefaultString(EnvServerName, "localhost"),
|
||||||
|
APIVersion: env.GetOrDefaultInt(EnvAPIVersion, 0),
|
||||||
|
TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL),
|
||||||
|
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 120*time.Second),
|
||||||
|
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 2*time.Second),
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSProvider implements the challenge.Provider interface.
|
||||||
|
type DNSProvider struct {
|
||||||
|
config *Config
|
||||||
|
client *internal.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a DNSProvider instance configured for pdns.
|
||||||
|
// Credentials must be passed in the environment variable:
|
||||||
|
// PDNS_API_URL and PDNS_API_KEY.
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
values, err := env.Get(EnvAPIKey, EnvAPIURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("pdns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hostURL, err := url.Parse(values[EnvAPIURL])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("pdns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.Host = hostURL
|
||||||
|
config.APIKey = values[EnvAPIKey]
|
||||||
|
|
||||||
|
return NewDNSProviderConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderConfig return a DNSProvider instance configured for pdns.
|
||||||
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.New("pdns: the configuration of the DNS provider is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.APIKey == "" {
|
||||||
|
return nil, errors.New("pdns: API key missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Host == nil || config.Host.Host == "" {
|
||||||
|
return nil, errors.New("pdns: API URL missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := internal.NewClient(config.Host, config.ServerName, config.APIVersion, config.APIKey)
|
||||||
|
|
||||||
|
if config.APIVersion <= 0 {
|
||||||
|
err := client.SetAPIVersion(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("pdns: failed to get API version %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DNSProvider{config: config, client: client}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
|
// Adjusting here to cope with spikes in propagation times.
|
||||||
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
|
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present creates a TXT record to fulfill the dns-01 challenge.
|
||||||
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
info := dns01.GetChallengeInfo(domain, keyAuth)
|
||||||
|
|
||||||
|
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("pdns: could not find zone for domain %q: %w", domain, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
zone, err := d.client.GetHostedZone(ctx, authZone)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("pdns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := info.EffectiveFQDN
|
||||||
|
if d.client.APIVersion() == 0 {
|
||||||
|
// pre-v1 API wants non-fqdn
|
||||||
|
name = dns01.UnFqdn(info.EffectiveFQDN)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for existing records.
|
||||||
|
existingRRSet := findTxtRecord(zone, info.EffectiveFQDN)
|
||||||
|
|
||||||
|
// merge the existing and new records
|
||||||
|
var records []internal.Record
|
||||||
|
if existingRRSet != nil {
|
||||||
|
records = existingRRSet.Records
|
||||||
|
}
|
||||||
|
|
||||||
|
rec := internal.Record{
|
||||||
|
Content: "\"" + info.Value + "\"",
|
||||||
|
Disabled: false,
|
||||||
|
|
||||||
|
// pre-v1 API
|
||||||
|
Type: "TXT",
|
||||||
|
Name: name,
|
||||||
|
TTL: d.config.TTL,
|
||||||
|
}
|
||||||
|
|
||||||
|
rrSets := internal.RRSets{
|
||||||
|
RRSets: []internal.RRSet{
|
||||||
|
{
|
||||||
|
Name: name,
|
||||||
|
ChangeType: "REPLACE",
|
||||||
|
Type: "TXT",
|
||||||
|
Kind: "Master",
|
||||||
|
TTL: d.config.TTL,
|
||||||
|
Records: append(records, rec),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.client.UpdateRecords(ctx, zone, rrSets)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("pdns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.client.Notify(ctx, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUp removes the TXT record matching the specified parameters.
|
||||||
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
info := dns01.GetChallengeInfo(domain, keyAuth)
|
||||||
|
|
||||||
|
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("pdns: could not find zone for domain %q: %w", domain, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
zone, err := d.client.GetHostedZone(ctx, authZone)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("pdns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
set := findTxtRecord(zone, info.EffectiveFQDN)
|
||||||
|
|
||||||
|
if set == nil {
|
||||||
|
return fmt.Errorf("pdns: no existing record found for %s", info.EffectiveFQDN)
|
||||||
|
}
|
||||||
|
|
||||||
|
rrSets := internal.RRSets{
|
||||||
|
RRSets: []internal.RRSet{
|
||||||
|
{
|
||||||
|
Name: set.Name,
|
||||||
|
Type: set.Type,
|
||||||
|
ChangeType: "DELETE",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.client.UpdateRecords(ctx, zone, rrSets)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("pdns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.client.Notify(ctx, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
func findTxtRecord(zone *internal.HostedZone, fqdn string) *internal.RRSet {
|
||||||
|
for _, set := range zone.RRSets {
|
||||||
|
if set.Type == "TXT" && (set.Name == dns01.UnFqdn(fqdn) || set.Name == fqdn) {
|
||||||
|
return &set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
37
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/pdns.toml
generated
vendored
Normal file
37
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/pdns.toml
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Name = "PowerDNS"
|
||||||
|
Description = ''''''
|
||||||
|
URL = "https://www.powerdns.com/"
|
||||||
|
Code = "pdns"
|
||||||
|
Since = "v0.4.0"
|
||||||
|
|
||||||
|
Example = '''
|
||||||
|
PDNS_API_URL=http://pdns-server:80/ \
|
||||||
|
PDNS_API_KEY=xxxx \
|
||||||
|
lego --email you@example.com --dns pdns --domains my.example.org run
|
||||||
|
'''
|
||||||
|
|
||||||
|
Additional = '''
|
||||||
|
## Information
|
||||||
|
|
||||||
|
Tested and confirmed to work with PowerDNS authoritative server 3.4.8 and 4.0.1. Refer to [PowerDNS documentation](https://doc.powerdns.com/md/httpapi/README/) instructions on how to enable the built-in API interface.
|
||||||
|
|
||||||
|
PowerDNS Notes:
|
||||||
|
- PowerDNS API does not currently support SSL, therefore you should take care to ensure that traffic between lego and the PowerDNS API is over a trusted network, VPN etc.
|
||||||
|
- In order to have the SOA serial automatically increment each time the `_acme-challenge` record is added/modified via the API, set `SOA-EDIT-API` to `INCEPTION-INCREMENT` for the zone in the `domainmetadata` table
|
||||||
|
- Some PowerDNS servers doesn't have root API endpoints enabled and API version autodetection will not work. In that case version number can be defined using `PDNS_API_VERSION`.
|
||||||
|
'''
|
||||||
|
|
||||||
|
[Configuration]
|
||||||
|
[Configuration.Credentials]
|
||||||
|
PDNS_API_KEY = "API key"
|
||||||
|
PDNS_API_URL = "API URL"
|
||||||
|
[Configuration.Additional]
|
||||||
|
PDNS_SERVER_NAME = "Name of the server in the URL, 'localhost' by default"
|
||||||
|
PDNS_API_VERSION = "Skip API version autodetection and use the provided version number."
|
||||||
|
PDNS_POLLING_INTERVAL = "Time between DNS propagation check"
|
||||||
|
PDNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
|
||||||
|
PDNS_TTL = "The TTL of the TXT record used for the DNS challenge"
|
||||||
|
PDNS_HTTP_TIMEOUT = "API request timeout"
|
||||||
|
|
||||||
|
[Links]
|
||||||
|
API = "https://doc.powerdns.com/md/httpapi/README/"
|
8
vendor/github.com/go-acme/lego/v4/registration/registar.go
generated
vendored
8
vendor/github.com/go-acme/lego/v4/registration/registar.go
generated
vendored
@ -9,6 +9,8 @@ import (
|
|||||||
"github.com/go-acme/lego/v4/log"
|
"github.com/go-acme/lego/v4/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const mailTo = "mailto:"
|
||||||
|
|
||||||
// Resource represents all important information about a registration
|
// Resource represents all important information about a registration
|
||||||
// of which the client needs to keep track itself.
|
// of which the client needs to keep track itself.
|
||||||
// WARNING: will be removed in the future (acme.ExtendedAccount), https://github.com/go-acme/lego/issues/855.
|
// WARNING: will be removed in the future (acme.ExtendedAccount), https://github.com/go-acme/lego/issues/855.
|
||||||
@ -52,7 +54,7 @@ func (r *Registrar) Register(options RegisterOptions) (*Resource, error) {
|
|||||||
|
|
||||||
if r.user.GetEmail() != "" {
|
if r.user.GetEmail() != "" {
|
||||||
log.Infof("acme: Registering account for %s", r.user.GetEmail())
|
log.Infof("acme: Registering account for %s", r.user.GetEmail())
|
||||||
accMsg.Contact = []string{"mailto:" + r.user.GetEmail()}
|
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err := r.core.Accounts.New(accMsg)
|
account, err := r.core.Accounts.New(accMsg)
|
||||||
@ -76,7 +78,7 @@ func (r *Registrar) RegisterWithExternalAccountBinding(options RegisterEABOption
|
|||||||
|
|
||||||
if r.user.GetEmail() != "" {
|
if r.user.GetEmail() != "" {
|
||||||
log.Infof("acme: Registering account for %s", r.user.GetEmail())
|
log.Infof("acme: Registering account for %s", r.user.GetEmail())
|
||||||
accMsg.Contact = []string{"mailto:" + r.user.GetEmail()}
|
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err := r.core.Accounts.NewEAB(accMsg, options.Kid, options.HmacEncoded)
|
account, err := r.core.Accounts.NewEAB(accMsg, options.Kid, options.HmacEncoded)
|
||||||
@ -128,7 +130,7 @@ func (r *Registrar) UpdateRegistration(options RegisterOptions) (*Resource, erro
|
|||||||
|
|
||||||
if r.user.GetEmail() != "" {
|
if r.user.GetEmail() != "" {
|
||||||
log.Infof("acme: Registering account for %s", r.user.GetEmail())
|
log.Infof("acme: Registering account for %s", r.user.GetEmail())
|
||||||
accMsg.Contact = []string{"mailto:" + r.user.GetEmail()}
|
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
|
||||||
}
|
}
|
||||||
|
|
||||||
accountURL := r.user.GetRegistration().URI
|
accountURL := r.user.GetRegistration().URI
|
||||||
|
10
vendor/github.com/go-jose/go-jose/v3/BUG-BOUNTY.md
generated
vendored
10
vendor/github.com/go-jose/go-jose/v3/BUG-BOUNTY.md
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
Serious about security
|
|
||||||
======================
|
|
||||||
|
|
||||||
Square recognizes the important contributions the security research community
|
|
||||||
can make. We therefore encourage reporting security issues with the code
|
|
||||||
contained in this repository.
|
|
||||||
|
|
||||||
If you believe you have discovered a security vulnerability, please follow the
|
|
||||||
guidelines at <https://bugcrowd.com/squareopensource>.
|
|
||||||
|
|
96
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
generated
vendored
Normal file
96
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# v4.0.4
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Reverted "Allow unmarshalling JSONWebKeySets with unsupported key types" as a
|
||||||
|
breaking change. See #136 / #137.
|
||||||
|
|
||||||
|
# v4.0.3
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Allow unmarshalling JSONWebKeySets with unsupported key types (#130)
|
||||||
|
- Document that OpaqueKeyEncrypter can't be implemented (for now) (#129)
|
||||||
|
- Dependency updates
|
||||||
|
|
||||||
|
# v4.0.2
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Improved documentation of Verify() to note that JSONWebKeySet is a supported
|
||||||
|
argument type (#104)
|
||||||
|
- Defined exported error values for missing x5c header and unsupported elliptic
|
||||||
|
curves error cases (#117)
|
||||||
|
|
||||||
|
# v4.0.1
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- An attacker could send a JWE containing compressed data that used large
|
||||||
|
amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
|
||||||
|
Those functions now return an error if the decompressed data would exceed
|
||||||
|
250kB or 10x the compressed size (whichever is larger). Thanks to
|
||||||
|
Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
|
||||||
|
for reporting.
|
||||||
|
|
||||||
|
# v4.0.0
|
||||||
|
|
||||||
|
This release makes some breaking changes in order to more thoroughly
|
||||||
|
address the vulnerabilities discussed in [Three New Attacks Against JSON Web
|
||||||
|
Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
|
||||||
|
token".
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Limit JWT encryption types (exclude password or public key types) (#78)
|
||||||
|
- Enforce minimum length for HMAC keys (#85)
|
||||||
|
- jwt: match any audience in a list, rather than requiring all audiences (#81)
|
||||||
|
- jwt: accept only Compact Serialization (#75)
|
||||||
|
- jws: Add expected algorithms for signatures (#74)
|
||||||
|
- Require specifying expected algorithms for ParseEncrypted,
|
||||||
|
ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
|
||||||
|
jwt.ParseSignedAndEncrypted (#69, #74)
|
||||||
|
- Usually there is a small, known set of appropriate algorithms for a program
|
||||||
|
to use and it's a mistake to allow unexpected algorithms. For instance the
|
||||||
|
"billion hash attack" relies in part on programs accepting the PBES2
|
||||||
|
encryption algorithm and doing the necessary work even if they weren't
|
||||||
|
specifically configured to allow PBES2.
|
||||||
|
- Revert "Strip padding off base64 strings" (#82)
|
||||||
|
- The specs require base64url encoding without padding.
|
||||||
|
- Minimum supported Go version is now 1.21
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
|
||||||
|
- These allow parsing a specific serialization, as opposed to ParseSigned and
|
||||||
|
ParseEncrypted, which try to automatically detect which serialization was
|
||||||
|
provided. It's common to require a specific serialization for a specific
|
||||||
|
protocol - for instance JWT requires Compact serialization.
|
||||||
|
|
||||||
|
[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
|
||||||
|
|
||||||
|
# v3.0.2
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- DecryptMulti: handle decompression error (#19)
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- jwe/CompactSerialize: improve performance (#67)
|
||||||
|
- Increase the default number of PBKDF2 iterations to 600k (#48)
|
||||||
|
- Return the proper algorithm for ECDSA keys (#45)
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Add Thumbprint support for opaque signers (#38)
|
||||||
|
|
||||||
|
# v3.0.1
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Security issue: an attacker specifying a large "p2c" value can cause
|
||||||
|
JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
|
||||||
|
amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
|
||||||
|
disclosure and to Tom Tervoort for originally publishing the category of attack.
|
||||||
|
https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
|
@ -1,10 +1,9 @@
|
|||||||
# Go JOSE
|
# Go JOSE
|
||||||
|
|
||||||
[![godoc](http://img.shields.io/badge/godoc-jose_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2)
|
[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
|
||||||
[![godoc](http://img.shields.io/badge/godoc-jwt_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2/jwt)
|
[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
|
||||||
[![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)
|
[![license](https://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)
|
||||||
[![build](https://travis-ci.org/go-jose/go-jose.svg?branch=master)](https://travis-ci.org/go-jose/go-jose)
|
[![test](https://img.shields.io/github/checks-status/go-jose/go-jose/v4)](https://github.com/go-jose/go-jose/actions)
|
||||||
[![coverage](https://coveralls.io/repos/github/go-jose/go-jose/badge.svg?branch=master)](https://coveralls.io/r/go-jose/go-jose)
|
|
||||||
|
|
||||||
Package jose aims to provide an implementation of the Javascript Object Signing
|
Package jose aims to provide an implementation of the Javascript Object Signing
|
||||||
and Encryption set of standards. This includes support for JSON Web Encryption,
|
and Encryption set of standards. This includes support for JSON Web Encryption,
|
||||||
@ -21,13 +20,13 @@ US maintained blocked list.
|
|||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The implementation follows the
|
The implementation follows the
|
||||||
[JSON Web Encryption](http://dx.doi.org/10.17487/RFC7516) (RFC 7516),
|
[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516),
|
||||||
[JSON Web Signature](http://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
|
[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
|
||||||
[JSON Web Token](http://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
|
[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
|
||||||
Tables of supported algorithms are shown below. The library supports both
|
Tables of supported algorithms are shown below. The library supports both
|
||||||
the compact and JWS/JWE JSON Serialization formats, and has optional support for
|
the compact and JWS/JWE JSON Serialization formats, and has optional support for
|
||||||
multiple recipients. It also comes with a small command-line utility
|
multiple recipients. It also comes with a small command-line utility
|
||||||
([`jose-util`](https://github.com/go-jose/go-jose/tree/master/jose-util))
|
([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util))
|
||||||
for dealing with JOSE messages in a shell.
|
for dealing with JOSE messages in a shell.
|
||||||
|
|
||||||
**Note**: We use a forked version of the `encoding/json` package from the Go
|
**Note**: We use a forked version of the `encoding/json` package from the Go
|
||||||
@ -38,29 +37,22 @@ libraries in other languages.
|
|||||||
|
|
||||||
### Versions
|
### Versions
|
||||||
|
|
||||||
[Version 2](https://gopkg.in/go-jose/go-jose.v2)
|
[Version 4](https://github.com/go-jose/go-jose)
|
||||||
([branch](https://github.com/go-jose/go-jose/tree/v2),
|
([branch](https://github.com/go-jose/go-jose/tree/main),
|
||||||
[doc](https://godoc.org/gopkg.in/go-jose/go-jose.v2)) is the current stable version:
|
[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version:
|
||||||
|
|
||||||
import "gopkg.in/go-jose/go-jose.v2"
|
import "github.com/go-jose/go-jose/v4"
|
||||||
|
|
||||||
[Version 3](https://github.com/go-jose/go-jose)
|
The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which
|
||||||
([branch](https://github.com/go-jose/go-jose/tree/master),
|
are still useable but not actively developed anymore.
|
||||||
[doc](https://godoc.org/github.com/go-jose/go-jose)) is the under development/unstable version (not released yet):
|
|
||||||
|
|
||||||
import "github.com/go-jose/go-jose/v3"
|
Version 3, in this repo, is still receiving security fixes but not functionality
|
||||||
|
updates.
|
||||||
All new feature development takes place on the `master` branch, which we are
|
|
||||||
preparing to release as version 3 soon. Version 2 will continue to receive
|
|
||||||
critical bug and security fixes. Note that starting with version 3 we are
|
|
||||||
using Go modules for versioning instead of `gopkg.in` as before. Version 3 also will require Go version 1.13 or higher.
|
|
||||||
|
|
||||||
Version 1 (on the `v1` branch) is frozen and not supported anymore.
|
|
||||||
|
|
||||||
### Supported algorithms
|
### Supported algorithms
|
||||||
|
|
||||||
See below for a table of supported algorithms. Algorithm identifiers match
|
See below for a table of supported algorithms. Algorithm identifiers match
|
||||||
the names in the [JSON Web Algorithms](http://dx.doi.org/10.17487/RFC7518)
|
the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)
|
||||||
standard where possible. The Godoc reference has a list of constants.
|
standard where possible. The Godoc reference has a list of constants.
|
||||||
|
|
||||||
Key encryption | Algorithm identifier(s)
|
Key encryption | Algorithm identifier(s)
|
||||||
@ -103,20 +95,20 @@ allows attaching a key id.
|
|||||||
|
|
||||||
Algorithm(s) | Corresponding types
|
Algorithm(s) | Corresponding types
|
||||||
:------------------------- | -------------------------------
|
:------------------------- | -------------------------------
|
||||||
RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey)
|
RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)
|
||||||
ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey)
|
ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)
|
||||||
EdDSA<sup>1</sup> | [ed25519.PublicKey](https://godoc.org/pkg/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://godoc.org/pkg/crypto/ed25519#PrivateKey)
|
EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey)
|
||||||
AES, HMAC | []byte
|
AES, HMAC | []byte
|
||||||
|
|
||||||
<sup>1. Only available in version 2 or later of the package</sup>
|
<sup>1. Only available in version 2 or later of the package</sup>
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
[![godoc](http://img.shields.io/badge/godoc-jose_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2)
|
[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
|
||||||
[![godoc](http://img.shields.io/badge/godoc-jwt_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2/jwt)
|
[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
|
||||||
|
|
||||||
Examples can be found in the Godoc
|
Examples can be found in the Godoc
|
||||||
reference for this package. The
|
reference for this package. The
|
||||||
[`jose-util`](https://github.com/go-jose/go-jose/tree/master/jose-util)
|
[`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util)
|
||||||
subdirectory also contains a small command-line utility which might be useful
|
subdirectory also contains a small command-line utility which might be useful
|
||||||
as an example as well.
|
as an example as well.
|
13
vendor/github.com/go-jose/go-jose/v4/SECURITY.md
generated
vendored
Normal file
13
vendor/github.com/go-jose/go-jose/v4/SECURITY.md
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Security Policy
|
||||||
|
This document explains how to contact the Let's Encrypt security team to report security vulnerabilities.
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ----------|
|
||||||
|
| >= v3 | ✓ |
|
||||||
|
| v2 | ✗ |
|
||||||
|
| v1 | ✗ |
|
||||||
|
|
||||||
|
## Reporting a vulnerability
|
||||||
|
|
||||||
|
Please see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email.
|
@ -29,8 +29,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
josecipher "github.com/go-jose/go-jose/v3/cipher"
|
josecipher "github.com/go-jose/go-jose/v4/cipher"
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A generic RSA-based encrypter/verifier
|
// A generic RSA-based encrypter/verifier
|
||||||
@ -285,6 +285,9 @@ func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm
|
|||||||
|
|
||||||
switch alg {
|
switch alg {
|
||||||
case RS256, RS384, RS512:
|
case RS256, RS384, RS512:
|
||||||
|
// TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the
|
||||||
|
// random parameter is legacy and ignored, and it can be nil.
|
||||||
|
// https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1
|
||||||
out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
|
out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
|
||||||
case PS256, PS384, PS512:
|
case PS256, PS384, PS512:
|
||||||
out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
|
out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
|
@ -21,9 +21,8 @@ import (
|
|||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Encrypter represents an encrypter which produces an encrypted JWE object.
|
// Encrypter represents an encrypter which produces an encrypted JWE object.
|
||||||
@ -76,14 +75,24 @@ type recipientKeyInfo struct {
|
|||||||
type EncrypterOptions struct {
|
type EncrypterOptions struct {
|
||||||
Compression CompressionAlgorithm
|
Compression CompressionAlgorithm
|
||||||
|
|
||||||
// Optional map of additional keys to be inserted into the protected header
|
// Optional map of name/value pairs to be inserted into the protected
|
||||||
// of a JWS object. Some specifications which make use of JWS like to insert
|
// header of a JWS object. Some specifications which make use of
|
||||||
// additional values here. All values must be JSON-serializable.
|
// JWS require additional values here.
|
||||||
|
//
|
||||||
|
// Values will be serialized by [json.Marshal] and must be valid inputs to
|
||||||
|
// that function.
|
||||||
|
//
|
||||||
|
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
|
||||||
ExtraHeaders map[HeaderKey]interface{}
|
ExtraHeaders map[HeaderKey]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
|
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
|
||||||
// if necessary. It returns itself and so can be used in a fluent style.
|
// if necessary, and returns the updated EncrypterOptions.
|
||||||
|
//
|
||||||
|
// The v parameter will be serialized by [json.Marshal] and must be a valid
|
||||||
|
// input to that function.
|
||||||
|
//
|
||||||
|
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
|
||||||
func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {
|
func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {
|
||||||
if eo.ExtraHeaders == nil {
|
if eo.ExtraHeaders == nil {
|
||||||
eo.ExtraHeaders = map[HeaderKey]interface{}{}
|
eo.ExtraHeaders = map[HeaderKey]interface{}{}
|
||||||
@ -111,7 +120,17 @@ func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions {
|
|||||||
// default of 100000 will be used for the count and a 128-bit random salt will
|
// default of 100000 will be used for the count and a 128-bit random salt will
|
||||||
// be generated.
|
// be generated.
|
||||||
type Recipient struct {
|
type Recipient struct {
|
||||||
Algorithm KeyAlgorithm
|
Algorithm KeyAlgorithm
|
||||||
|
// Key must have one of these types:
|
||||||
|
// - ed25519.PublicKey
|
||||||
|
// - *ecdsa.PublicKey
|
||||||
|
// - *rsa.PublicKey
|
||||||
|
// - *JSONWebKey
|
||||||
|
// - JSONWebKey
|
||||||
|
// - []byte (a symmetric key)
|
||||||
|
// - Any type that satisfies the OpaqueKeyEncrypter interface
|
||||||
|
//
|
||||||
|
// The type of Key must match the value of Algorithm.
|
||||||
Key interface{}
|
Key interface{}
|
||||||
KeyID string
|
KeyID string
|
||||||
PBES2Count int
|
PBES2Count int
|
||||||
@ -150,16 +169,17 @@ func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions)
|
|||||||
switch rcpt.Algorithm {
|
switch rcpt.Algorithm {
|
||||||
case DIRECT:
|
case DIRECT:
|
||||||
// Direct encryption mode must be treated differently
|
// Direct encryption mode must be treated differently
|
||||||
if reflect.TypeOf(rawKey) != reflect.TypeOf([]byte{}) {
|
keyBytes, ok := rawKey.([]byte)
|
||||||
|
if !ok {
|
||||||
return nil, ErrUnsupportedKeyType
|
return nil, ErrUnsupportedKeyType
|
||||||
}
|
}
|
||||||
if encrypter.cipher.keySize() != len(rawKey.([]byte)) {
|
if encrypter.cipher.keySize() != len(keyBytes) {
|
||||||
return nil, ErrInvalidKeySize
|
return nil, ErrInvalidKeySize
|
||||||
}
|
}
|
||||||
encrypter.keyGenerator = staticKeyGenerator{
|
encrypter.keyGenerator = staticKeyGenerator{
|
||||||
key: rawKey.([]byte),
|
key: keyBytes,
|
||||||
}
|
}
|
||||||
recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, rawKey.([]byte))
|
recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes)
|
||||||
recipientInfo.keyID = keyID
|
recipientInfo.keyID = keyID
|
||||||
if rcpt.KeyID != "" {
|
if rcpt.KeyID != "" {
|
||||||
recipientInfo.keyID = rcpt.KeyID
|
recipientInfo.keyID = rcpt.KeyID
|
||||||
@ -168,16 +188,16 @@ func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions)
|
|||||||
return encrypter, nil
|
return encrypter, nil
|
||||||
case ECDH_ES:
|
case ECDH_ES:
|
||||||
// ECDH-ES (w/o key wrapping) is similar to DIRECT mode
|
// ECDH-ES (w/o key wrapping) is similar to DIRECT mode
|
||||||
typeOf := reflect.TypeOf(rawKey)
|
keyDSA, ok := rawKey.(*ecdsa.PublicKey)
|
||||||
if typeOf != reflect.TypeOf(&ecdsa.PublicKey{}) {
|
if !ok {
|
||||||
return nil, ErrUnsupportedKeyType
|
return nil, ErrUnsupportedKeyType
|
||||||
}
|
}
|
||||||
encrypter.keyGenerator = ecKeyGenerator{
|
encrypter.keyGenerator = ecKeyGenerator{
|
||||||
size: encrypter.cipher.keySize(),
|
size: encrypter.cipher.keySize(),
|
||||||
algID: string(enc),
|
algID: string(enc),
|
||||||
publicKey: rawKey.(*ecdsa.PublicKey),
|
publicKey: keyDSA,
|
||||||
}
|
}
|
||||||
recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, rawKey.(*ecdsa.PublicKey))
|
recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA)
|
||||||
recipientInfo.keyID = keyID
|
recipientInfo.keyID = keyID
|
||||||
if rcpt.KeyID != "" {
|
if rcpt.KeyID != "" {
|
||||||
recipientInfo.keyID = rcpt.KeyID
|
recipientInfo.keyID = rcpt.KeyID
|
||||||
@ -270,9 +290,8 @@ func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKey
|
|||||||
recipient, err := makeJWERecipient(alg, encryptionKey.Key)
|
recipient, err := makeJWERecipient(alg, encryptionKey.Key)
|
||||||
recipient.keyID = encryptionKey.KeyID
|
recipient.keyID = encryptionKey.KeyID
|
||||||
return recipient, err
|
return recipient, err
|
||||||
}
|
case OpaqueKeyEncrypter:
|
||||||
if encrypter, ok := encryptionKey.(OpaqueKeyEncrypter); ok {
|
return newOpaqueKeyEncrypter(alg, encryptionKey)
|
||||||
return newOpaqueKeyEncrypter(alg, encrypter)
|
|
||||||
}
|
}
|
||||||
return recipientKeyInfo{}, ErrUnsupportedKeyType
|
return recipientKeyInfo{}, ErrUnsupportedKeyType
|
||||||
}
|
}
|
||||||
@ -300,11 +319,11 @@ func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {
|
|||||||
return newDecrypter(decryptionKey.Key)
|
return newDecrypter(decryptionKey.Key)
|
||||||
case *JSONWebKey:
|
case *JSONWebKey:
|
||||||
return newDecrypter(decryptionKey.Key)
|
return newDecrypter(decryptionKey.Key)
|
||||||
|
case OpaqueKeyDecrypter:
|
||||||
|
return &opaqueKeyDecrypter{decrypter: decryptionKey}, nil
|
||||||
|
default:
|
||||||
|
return nil, ErrUnsupportedKeyType
|
||||||
}
|
}
|
||||||
if okd, ok := decryptionKey.(OpaqueKeyDecrypter); ok {
|
|
||||||
return &opaqueKeyDecrypter{decrypter: okd}, nil
|
|
||||||
}
|
|
||||||
return nil, ErrUnsupportedKeyType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation of encrypt method producing a JWE object.
|
// Implementation of encrypt method producing a JWE object.
|
||||||
@ -403,9 +422,27 @@ func (ctx *genericEncrypter) Options() EncrypterOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt and validate the object and return the plaintext. Note that this
|
// Decrypt and validate the object and return the plaintext. This
|
||||||
// function does not support multi-recipient, if you desire multi-recipient
|
// function does not support multi-recipient. If you desire multi-recipient
|
||||||
// decryption use DecryptMulti instead.
|
// decryption use DecryptMulti instead.
|
||||||
|
//
|
||||||
|
// The decryptionKey argument must contain a private or symmetric key
|
||||||
|
// and must have one of these types:
|
||||||
|
// - *ecdsa.PrivateKey
|
||||||
|
// - *rsa.PrivateKey
|
||||||
|
// - *JSONWebKey
|
||||||
|
// - JSONWebKey
|
||||||
|
// - *JSONWebKeySet
|
||||||
|
// - JSONWebKeySet
|
||||||
|
// - []byte (a symmetric key)
|
||||||
|
// - string (a symmetric key)
|
||||||
|
// - Any type that satisfies the OpaqueKeyDecrypter interface.
|
||||||
|
//
|
||||||
|
// Note that ed25519 is only available for signatures, not encryption, so is
|
||||||
|
// not an option here.
|
||||||
|
//
|
||||||
|
// Automatically decompresses plaintext, but returns an error if the decompressed
|
||||||
|
// data would be >250kB or >10x the size of the compressed data, whichever is larger.
|
||||||
func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
|
func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
|
||||||
headers := obj.mergedHeaders(nil)
|
headers := obj.mergedHeaders(nil)
|
||||||
|
|
||||||
@ -422,7 +459,10 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
|||||||
return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
||||||
}
|
}
|
||||||
|
|
||||||
key := tryJWKS(decryptionKey, obj.Header)
|
key, err := tryJWKS(decryptionKey, obj.Header)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
decrypter, err := newDecrypter(key)
|
decrypter, err := newDecrypter(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -462,15 +502,24 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
|||||||
// The "zip" header parameter may only be present in the protected header.
|
// The "zip" header parameter may only be present in the protected header.
|
||||||
if comp := obj.protected.getCompression(); comp != "" {
|
if comp := obj.protected.getCompression(); comp != "" {
|
||||||
plaintext, err = decompress(comp, plaintext)
|
plaintext, err = decompress(comp, plaintext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return plaintext, err
|
return plaintext, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptMulti decrypts and validates the object and returns the plaintexts,
|
// DecryptMulti decrypts and validates the object and returns the plaintexts,
|
||||||
// with support for multiple recipients. It returns the index of the recipient
|
// with support for multiple recipients. It returns the index of the recipient
|
||||||
// for which the decryption was successful, the merged headers for that recipient,
|
// for which the decryption was successful, the merged headers for that recipient,
|
||||||
// and the plaintext.
|
// and the plaintext.
|
||||||
|
//
|
||||||
|
// The decryptionKey argument must have one of the types allowed for the
|
||||||
|
// decryptionKey argument of Decrypt().
|
||||||
|
//
|
||||||
|
// Automatically decompresses plaintext, but returns an error if the decompressed
|
||||||
|
// data would be >250kB or >3x the size of the compressed data, whichever is larger.
|
||||||
func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
|
func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
|
||||||
globalHeaders := obj.mergedHeaders(nil)
|
globalHeaders := obj.mergedHeaders(nil)
|
||||||
|
|
||||||
@ -483,7 +532,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
|
|||||||
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
||||||
}
|
}
|
||||||
|
|
||||||
key := tryJWKS(decryptionKey, obj.Header)
|
key, err := tryJWKS(decryptionKey, obj.Header)
|
||||||
|
if err != nil {
|
||||||
|
return -1, Header{}, nil, err
|
||||||
|
}
|
||||||
decrypter, err := newDecrypter(key)
|
decrypter, err := newDecrypter(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, Header{}, nil, err
|
return -1, Header{}, nil, err
|
||||||
@ -532,7 +584,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
|
|||||||
|
|
||||||
// The "zip" header parameter may only be present in the protected header.
|
// The "zip" header parameter may only be present in the protected header.
|
||||||
if comp := obj.protected.getCompression(); comp != "" {
|
if comp := obj.protected.getCompression(); comp != "" {
|
||||||
plaintext, _ = decompress(comp, plaintext)
|
plaintext, err = decompress(comp, plaintext)
|
||||||
|
if err != nil {
|
||||||
|
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sanitized, err := headers.sanitized()
|
sanitized, err := headers.sanitized()
|
@ -15,13 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Package jose aims to provide an implementation of the Javascript Object Signing
|
Package jose aims to provide an implementation of the Javascript Object Signing
|
||||||
and Encryption set of standards. It implements encryption and signing based on
|
and Encryption set of standards. It implements encryption and signing based on
|
||||||
the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web
|
the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web
|
||||||
Token support available in a sub-package. The library supports both the compact
|
Token support available in a sub-package. The library supports both the compact
|
||||||
and JWS/JWE JSON Serialization formats, and has optional support for multiple
|
and JWS/JWE JSON Serialization formats, and has optional support for multiple
|
||||||
recipients.
|
recipients.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package jose
|
package jose
|
@ -21,12 +21,13 @@ import (
|
|||||||
"compress/flate"
|
"compress/flate"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Helper function to serialize known-good objects.
|
// Helper function to serialize known-good objects.
|
||||||
@ -85,7 +86,7 @@ func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress with DEFLATE
|
// deflate compresses the input.
|
||||||
func deflate(input []byte) ([]byte, error) {
|
func deflate(input []byte) ([]byte, error) {
|
||||||
output := new(bytes.Buffer)
|
output := new(bytes.Buffer)
|
||||||
|
|
||||||
@ -97,15 +98,24 @@ func deflate(input []byte) ([]byte, error) {
|
|||||||
return output.Bytes(), err
|
return output.Bytes(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decompress with DEFLATE
|
// inflate decompresses the input.
|
||||||
|
//
|
||||||
|
// Errors if the decompressed data would be >250kB or >10x the size of the
|
||||||
|
// compressed data, whichever is larger.
|
||||||
func inflate(input []byte) ([]byte, error) {
|
func inflate(input []byte) ([]byte, error) {
|
||||||
output := new(bytes.Buffer)
|
output := new(bytes.Buffer)
|
||||||
reader := flate.NewReader(bytes.NewBuffer(input))
|
reader := flate.NewReader(bytes.NewBuffer(input))
|
||||||
|
|
||||||
_, err := io.Copy(output, reader)
|
maxCompressedSize := max(250_000, 10*int64(len(input)))
|
||||||
if err != nil {
|
|
||||||
|
limit := maxCompressedSize + 1
|
||||||
|
n, err := io.CopyN(output, reader, limit)
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if n == limit {
|
||||||
|
return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize)
|
||||||
|
}
|
||||||
|
|
||||||
err = reader.Close()
|
err = reader.Close()
|
||||||
return output.Bytes(), err
|
return output.Bytes(), err
|
||||||
@ -154,7 +164,7 @@ func (b *byteBuffer) UnmarshalJSON(data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
decoded, err := base64URLDecode(encoded)
|
decoded, err := base64.RawURLEncoding.DecodeString(encoded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -184,8 +194,35 @@ func (b byteBuffer) toInt() int {
|
|||||||
return int(b.bigInt().Int64())
|
return int(b.bigInt().Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C
|
func base64EncodeLen(sl []byte) int {
|
||||||
func base64URLDecode(value string) ([]byte, error) {
|
return base64.RawURLEncoding.EncodedLen(len(sl))
|
||||||
value = strings.TrimRight(value, "=")
|
}
|
||||||
return base64.RawURLEncoding.DecodeString(value)
|
|
||||||
|
func base64JoinWithDots(inputs ...[]byte) string {
|
||||||
|
if len(inputs) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count of dots.
|
||||||
|
totalCount := len(inputs) - 1
|
||||||
|
|
||||||
|
for _, input := range inputs {
|
||||||
|
totalCount += base64EncodeLen(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]byte, totalCount)
|
||||||
|
startEncode := 0
|
||||||
|
for i, input := range inputs {
|
||||||
|
base64.RawURLEncoding.Encode(out[startEncode:], input)
|
||||||
|
|
||||||
|
if i == len(inputs)-1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
startEncode += base64EncodeLen(input)
|
||||||
|
out[startEncode] = '.'
|
||||||
|
startEncode++
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(out)
|
||||||
}
|
}
|
@ -75,14 +75,13 @@ import (
|
|||||||
//
|
//
|
||||||
// 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 {
|
||||||
// Check for well-formedness.
|
// Check for well-formedness.
|
||||||
// Avoids filling out half a data structure
|
// Avoids filling out half a data structure
|
@ -58,6 +58,7 @@ import (
|
|||||||
// becomes a member of the object unless
|
// becomes a member of the object unless
|
||||||
// - the field's tag is "-", or
|
// - the field's tag is "-", or
|
||||||
// - the field is empty and its tag specifies the "omitempty" option.
|
// - the field is empty and its tag specifies the "omitempty" option.
|
||||||
|
//
|
||||||
// The empty values are false, 0, any
|
// The empty values are false, 0, any
|
||||||
// nil pointer or interface value, and any array, slice, map, or string of
|
// nil pointer or interface value, and any array, slice, map, or string of
|
||||||
// length zero. The object's default key string is the struct field name
|
// length zero. The object's default key string is the struct field name
|
||||||
@ -65,28 +66,28 @@ import (
|
|||||||
// the struct field's tag value is the key name, followed by an optional comma
|
// the struct field's tag value is the key name, followed by an optional comma
|
||||||
// and options. Examples:
|
// and options. Examples:
|
||||||
//
|
//
|
||||||
// // Field is ignored by this package.
|
// // Field is ignored by this package.
|
||||||
// Field int `json:"-"`
|
// Field int `json:"-"`
|
||||||
//
|
//
|
||||||
// // 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"`
|
||||||
//
|
//
|
||||||
// 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, dollar signs, percent signs, hyphens,
|
// only Unicode letters, digits, dollar signs, percent signs, hyphens,
|
||||||
@ -133,7 +134,6 @@ import (
|
|||||||
// 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) {
|
||||||
e := &encodeState{}
|
e := &encodeState{}
|
||||||
err := e.marshal(v)
|
err := e.marshal(v)
|
@ -240,7 +240,6 @@ var _ Unmarshaler = (*RawMessage)(nil)
|
|||||||
// 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 interface{}
|
type Token interface{}
|
||||||
|
|
||||||
const (
|
const (
|
148
vendor/github.com/go-jose/go-jose/v3/jwe.go → vendor/github.com/go-jose/go-jose/v4/jwe.go
generated
vendored
148
vendor/github.com/go-jose/go-jose/v3/jwe.go → vendor/github.com/go-jose/go-jose/v4/jwe.go
generated
vendored
@ -18,10 +18,11 @@ package jose
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
|
// rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
|
||||||
@ -104,29 +105,75 @@ func (obj JSONWebEncryption) computeAuthData() []byte {
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseEncrypted parses an encrypted message in compact or JWE JSON Serialization format.
|
func containsKeyAlgorithm(haystack []KeyAlgorithm, needle KeyAlgorithm) bool {
|
||||||
func ParseEncrypted(input string) (*JSONWebEncryption, error) {
|
for _, algorithm := range haystack {
|
||||||
input = stripWhitespace(input)
|
if algorithm == needle {
|
||||||
if strings.HasPrefix(input, "{") {
|
return true
|
||||||
return parseEncryptedFull(input)
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
return parseEncryptedCompact(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseEncryptedFull parses a message in compact format.
|
func containsContentEncryption(haystack []ContentEncryption, needle ContentEncryption) bool {
|
||||||
func parseEncryptedFull(input string) (*JSONWebEncryption, error) {
|
for _, algorithm := range haystack {
|
||||||
|
if algorithm == needle {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseEncrypted parses an encrypted message in JWE Compact or JWE JSON Serialization.
|
||||||
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2
|
||||||
|
//
|
||||||
|
// The keyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc"
|
||||||
|
// header parameters respectively. They must be nonempty, and each "alg" or "enc" header in
|
||||||
|
// parsed data must contain a value that is present in the corresponding parameter. That
|
||||||
|
// includes the protected and unprotected headers as well as all recipients. To accept
|
||||||
|
// multiple algorithms, pass a slice of all the algorithms you want to accept.
|
||||||
|
func ParseEncrypted(input string,
|
||||||
|
keyEncryptionAlgorithms []KeyAlgorithm,
|
||||||
|
contentEncryption []ContentEncryption,
|
||||||
|
) (*JSONWebEncryption, error) {
|
||||||
|
input = stripWhitespace(input)
|
||||||
|
if strings.HasPrefix(input, "{") {
|
||||||
|
return ParseEncryptedJSON(input, keyEncryptionAlgorithms, contentEncryption)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseEncryptedCompact(input, keyEncryptionAlgorithms, contentEncryption)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseEncryptedJSON parses a message in JWE JSON Serialization.
|
||||||
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2
|
||||||
|
func ParseEncryptedJSON(
|
||||||
|
input string,
|
||||||
|
keyEncryptionAlgorithms []KeyAlgorithm,
|
||||||
|
contentEncryption []ContentEncryption,
|
||||||
|
) (*JSONWebEncryption, error) {
|
||||||
var parsed rawJSONWebEncryption
|
var parsed rawJSONWebEncryption
|
||||||
err := json.Unmarshal([]byte(input), &parsed)
|
err := json.Unmarshal([]byte(input), &parsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed.sanitized()
|
return parsed.sanitized(keyEncryptionAlgorithms, contentEncryption)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitized produces a cleaned-up JWE object from the raw JSON.
|
// sanitized produces a cleaned-up JWE object from the raw JSON.
|
||||||
func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
|
func (parsed *rawJSONWebEncryption) sanitized(
|
||||||
|
keyEncryptionAlgorithms []KeyAlgorithm,
|
||||||
|
contentEncryption []ContentEncryption,
|
||||||
|
) (*JSONWebEncryption, error) {
|
||||||
|
if len(keyEncryptionAlgorithms) == 0 {
|
||||||
|
return nil, errors.New("go-jose/go-jose: no key algorithms provided")
|
||||||
|
}
|
||||||
|
if len(contentEncryption) == 0 {
|
||||||
|
return nil, errors.New("go-jose/go-jose: no content encryption algorithms provided")
|
||||||
|
}
|
||||||
|
|
||||||
obj := &JSONWebEncryption{
|
obj := &JSONWebEncryption{
|
||||||
original: parsed,
|
original: parsed,
|
||||||
unprotected: parsed.Unprotected,
|
unprotected: parsed.Unprotected,
|
||||||
@ -170,7 +217,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
|
|||||||
} else {
|
} else {
|
||||||
obj.recipients = make([]recipientInfo, len(parsed.Recipients))
|
obj.recipients = make([]recipientInfo, len(parsed.Recipients))
|
||||||
for r := range parsed.Recipients {
|
for r := range parsed.Recipients {
|
||||||
encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey)
|
encryptedKey, err := base64.RawURLEncoding.DecodeString(parsed.Recipients[r].EncryptedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -185,10 +232,31 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, recipient := range obj.recipients {
|
for i, recipient := range obj.recipients {
|
||||||
headers := obj.mergedHeaders(&recipient)
|
headers := obj.mergedHeaders(&recipient)
|
||||||
if headers.getAlgorithm() == "" || headers.getEncryption() == "" {
|
if headers.getAlgorithm() == "" {
|
||||||
return nil, fmt.Errorf("go-jose/go-jose: message is missing alg/enc headers")
|
return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "alg"`, i)
|
||||||
|
}
|
||||||
|
if headers.getEncryption() == "" {
|
||||||
|
return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "enc"`, i)
|
||||||
|
}
|
||||||
|
err := validateAlgEnc(headers, keyEncryptionAlgorithms, contentEncryption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: recipient %d: %s", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if obj.protected != nil {
|
||||||
|
err := validateAlgEnc(*obj.protected, keyEncryptionAlgorithms, contentEncryption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: protected header: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if obj.unprotected != nil {
|
||||||
|
err := validateAlgEnc(*obj.unprotected, keyEncryptionAlgorithms, contentEncryption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: unprotected header: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,34 +268,52 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
|
|||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseEncryptedCompact parses a message in compact format.
|
func validateAlgEnc(headers rawHeader, keyAlgorithms []KeyAlgorithm, contentEncryption []ContentEncryption) error {
|
||||||
func parseEncryptedCompact(input string) (*JSONWebEncryption, error) {
|
alg := headers.getAlgorithm()
|
||||||
|
enc := headers.getEncryption()
|
||||||
|
if alg != "" && !containsKeyAlgorithm(keyAlgorithms, alg) {
|
||||||
|
return fmt.Errorf("unexpected key algorithm %q; expected %q", alg, keyAlgorithms)
|
||||||
|
}
|
||||||
|
if alg != "" && !containsContentEncryption(contentEncryption, enc) {
|
||||||
|
return fmt.Errorf("unexpected content encryption algorithm %q; expected %q", enc, contentEncryption)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseEncryptedCompact parses a message in JWE Compact Serialization.
|
||||||
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1
|
||||||
|
func ParseEncryptedCompact(
|
||||||
|
input string,
|
||||||
|
keyAlgorithms []KeyAlgorithm,
|
||||||
|
contentEncryption []ContentEncryption,
|
||||||
|
) (*JSONWebEncryption, error) {
|
||||||
parts := strings.Split(input, ".")
|
parts := strings.Split(input, ".")
|
||||||
if len(parts) != 5 {
|
if len(parts) != 5 {
|
||||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
|
return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
|
||||||
}
|
}
|
||||||
|
|
||||||
rawProtected, err := base64URLDecode(parts[0])
|
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedKey, err := base64URLDecode(parts[1])
|
encryptedKey, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
iv, err := base64URLDecode(parts[2])
|
iv, err := base64.RawURLEncoding.DecodeString(parts[2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ciphertext, err := base64URLDecode(parts[3])
|
ciphertext, err := base64.RawURLEncoding.DecodeString(parts[3])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tag, err := base64URLDecode(parts[4])
|
tag, err := base64.RawURLEncoding.DecodeString(parts[4])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -240,7 +326,7 @@ func parseEncryptedCompact(input string) (*JSONWebEncryption, error) {
|
|||||||
Tag: newBuffer(tag),
|
Tag: newBuffer(tag),
|
||||||
}
|
}
|
||||||
|
|
||||||
return raw.sanitized()
|
return raw.sanitized(keyAlgorithms, contentEncryption)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompactSerialize serializes an object using the compact serialization format.
|
// CompactSerialize serializes an object using the compact serialization format.
|
||||||
@ -252,13 +338,13 @@ func (obj JSONWebEncryption) CompactSerialize() (string, error) {
|
|||||||
|
|
||||||
serializedProtected := mustSerializeJSON(obj.protected)
|
serializedProtected := mustSerializeJSON(obj.protected)
|
||||||
|
|
||||||
return fmt.Sprintf(
|
return base64JoinWithDots(
|
||||||
"%s.%s.%s.%s.%s",
|
serializedProtected,
|
||||||
base64.RawURLEncoding.EncodeToString(serializedProtected),
|
obj.recipients[0].encryptedKey,
|
||||||
base64.RawURLEncoding.EncodeToString(obj.recipients[0].encryptedKey),
|
obj.iv,
|
||||||
base64.RawURLEncoding.EncodeToString(obj.iv),
|
obj.ciphertext,
|
||||||
base64.RawURLEncoding.EncodeToString(obj.ciphertext),
|
obj.tag,
|
||||||
base64.RawURLEncoding.EncodeToString(obj.tag)), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullSerialize serializes an object using the full JSON serialization format.
|
// FullSerialize serializes an object using the full JSON serialization format.
|
@ -35,7 +35,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing.
|
// rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing.
|
||||||
@ -67,9 +67,21 @@ type rawJSONWebKey struct {
|
|||||||
X5tSHA256 string `json:"x5t#S256,omitempty"`
|
X5tSHA256 string `json:"x5t#S256,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONWebKey represents a public or private key in JWK format.
|
// JSONWebKey represents a public or private key in JWK format. It can be
|
||||||
|
// marshaled into JSON and unmarshaled from JSON.
|
||||||
type JSONWebKey struct {
|
type JSONWebKey struct {
|
||||||
// Cryptographic key, can be a symmetric or asymmetric key.
|
// Key is the Go in-memory representation of this key. It must have one
|
||||||
|
// of these types:
|
||||||
|
// - ed25519.PublicKey
|
||||||
|
// - ed25519.PrivateKey
|
||||||
|
// - *ecdsa.PublicKey
|
||||||
|
// - *ecdsa.PrivateKey
|
||||||
|
// - *rsa.PublicKey
|
||||||
|
// - *rsa.PrivateKey
|
||||||
|
// - []byte (a symmetric key)
|
||||||
|
//
|
||||||
|
// When marshaling this JSONWebKey into JSON, the "kty" header parameter
|
||||||
|
// will be automatically set based on the type of this field.
|
||||||
Key interface{}
|
Key interface{}
|
||||||
// Key identifier, parsed from `kid` header.
|
// Key identifier, parsed from `kid` header.
|
||||||
KeyID string
|
KeyID string
|
||||||
@ -254,7 +266,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
|
|||||||
|
|
||||||
// x5t parameters are base64url-encoded SHA thumbprints
|
// x5t parameters are base64url-encoded SHA thumbprints
|
||||||
// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8
|
// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8
|
||||||
x5tSHA1bytes, err := base64URLDecode(raw.X5tSHA1)
|
x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding")
|
return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding")
|
||||||
}
|
}
|
||||||
@ -274,7 +286,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
|
|||||||
|
|
||||||
k.CertificateThumbprintSHA1 = x5tSHA1bytes
|
k.CertificateThumbprintSHA1 = x5tSHA1bytes
|
||||||
|
|
||||||
x5tSHA256bytes, err := base64URLDecode(raw.X5tSHA256)
|
x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding")
|
return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding")
|
||||||
}
|
}
|
||||||
@ -389,6 +401,8 @@ func (k *JSONWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
|
|||||||
input, err = rsaThumbprintInput(key.N, key.E)
|
input, err = rsaThumbprintInput(key.N, key.E)
|
||||||
case ed25519.PrivateKey:
|
case ed25519.PrivateKey:
|
||||||
input, err = edThumbprintInput(ed25519.PublicKey(key[32:]))
|
input, err = edThumbprintInput(ed25519.PublicKey(key[32:]))
|
||||||
|
case OpaqueSigner:
|
||||||
|
return key.Public().Thumbprint(hash)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
|
return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
|
||||||
}
|
}
|
||||||
@ -765,7 +779,13 @@ func (key rawJSONWebKey) symmetricKey() ([]byte, error) {
|
|||||||
return key.K.bytes(), nil
|
return key.K.bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func tryJWKS(key interface{}, headers ...Header) interface{} {
|
var (
|
||||||
|
// ErrJWKSKidNotFound is returned when a JWKS does not contain a JWK with a
|
||||||
|
// key ID which matches one in the provided tokens headers.
|
||||||
|
ErrJWKSKidNotFound = errors.New("go-jose/go-jose: JWK with matching kid not found in JWK Set")
|
||||||
|
)
|
||||||
|
|
||||||
|
func tryJWKS(key interface{}, headers ...Header) (interface{}, error) {
|
||||||
var jwks JSONWebKeySet
|
var jwks JSONWebKeySet
|
||||||
|
|
||||||
switch jwksType := key.(type) {
|
switch jwksType := key.(type) {
|
||||||
@ -774,9 +794,11 @@ func tryJWKS(key interface{}, headers ...Header) interface{} {
|
|||||||
case JSONWebKeySet:
|
case JSONWebKeySet:
|
||||||
jwks = jwksType
|
jwks = jwksType
|
||||||
default:
|
default:
|
||||||
return key
|
// If the specified key is not a JWKS, return as is.
|
||||||
|
return key, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine the KID to search for from the headers.
|
||||||
var kid string
|
var kid string
|
||||||
for _, header := range headers {
|
for _, header := range headers {
|
||||||
if header.KeyID != "" {
|
if header.KeyID != "" {
|
||||||
@ -785,14 +807,17 @@ func tryJWKS(key interface{}, headers ...Header) interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no KID is specified in the headers, reject.
|
||||||
if kid == "" {
|
if kid == "" {
|
||||||
return key
|
return nil, ErrJWKSKidNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the JWK with the matching KID. If no JWK with the specified KID is
|
||||||
|
// found, reject.
|
||||||
keys := jwks.Key(kid)
|
keys := jwks.Key(kid)
|
||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return key
|
return nil, ErrJWKSKidNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return keys[0].Key
|
return keys[0].Key, nil
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
|
// rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
|
||||||
@ -75,22 +75,41 @@ type Signature struct {
|
|||||||
original *rawSignatureInfo
|
original *rawSignatureInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseSigned parses a signed message in compact or JWS JSON Serialization format.
|
// ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization.
|
||||||
func ParseSigned(signature string) (*JSONWebSignature, error) {
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7515#section-7
|
||||||
|
func ParseSigned(
|
||||||
|
signature string,
|
||||||
|
signatureAlgorithms []SignatureAlgorithm,
|
||||||
|
) (*JSONWebSignature, error) {
|
||||||
signature = stripWhitespace(signature)
|
signature = stripWhitespace(signature)
|
||||||
if strings.HasPrefix(signature, "{") {
|
if strings.HasPrefix(signature, "{") {
|
||||||
return parseSignedFull(signature)
|
return ParseSignedJSON(signature, signatureAlgorithms)
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseSignedCompact(signature, nil)
|
return parseSignedCompact(signature, nil, signatureAlgorithms)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSignedCompact parses a message in JWS Compact Serialization.
|
||||||
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7515#section-7.1
|
||||||
|
func ParseSignedCompact(
|
||||||
|
signature string,
|
||||||
|
signatureAlgorithms []SignatureAlgorithm,
|
||||||
|
) (*JSONWebSignature, error) {
|
||||||
|
return parseSignedCompact(signature, nil, signatureAlgorithms)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseDetached parses a signed message in compact serialization format with detached payload.
|
// ParseDetached parses a signed message in compact serialization format with detached payload.
|
||||||
func ParseDetached(signature string, payload []byte) (*JSONWebSignature, error) {
|
func ParseDetached(
|
||||||
|
signature string,
|
||||||
|
payload []byte,
|
||||||
|
signatureAlgorithms []SignatureAlgorithm,
|
||||||
|
) (*JSONWebSignature, error) {
|
||||||
if payload == nil {
|
if payload == nil {
|
||||||
return nil, errors.New("go-jose/go-jose: nil payload")
|
return nil, errors.New("go-jose/go-jose: nil payload")
|
||||||
}
|
}
|
||||||
return parseSignedCompact(stripWhitespace(signature), payload)
|
return parseSignedCompact(stripWhitespace(signature), payload, signatureAlgorithms)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a header value
|
// Get a header value
|
||||||
@ -137,19 +156,36 @@ func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature
|
|||||||
return authData.Bytes(), nil
|
return authData.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseSignedFull parses a message in full format.
|
// ParseSignedJSON parses a message in JWS JSON Serialization.
|
||||||
func parseSignedFull(input string) (*JSONWebSignature, error) {
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7515#section-7.2
|
||||||
|
func ParseSignedJSON(
|
||||||
|
input string,
|
||||||
|
signatureAlgorithms []SignatureAlgorithm,
|
||||||
|
) (*JSONWebSignature, error) {
|
||||||
var parsed rawJSONWebSignature
|
var parsed rawJSONWebSignature
|
||||||
err := json.Unmarshal([]byte(input), &parsed)
|
err := json.Unmarshal([]byte(input), &parsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed.sanitized()
|
return parsed.sanitized(signatureAlgorithms)
|
||||||
|
}
|
||||||
|
|
||||||
|
func containsSignatureAlgorithm(haystack []SignatureAlgorithm, needle SignatureAlgorithm) bool {
|
||||||
|
for _, algorithm := range haystack {
|
||||||
|
if algorithm == needle {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitized produces a cleaned-up JWS object from the raw JSON.
|
// sanitized produces a cleaned-up JWS object from the raw JSON.
|
||||||
func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
|
func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgorithm) (*JSONWebSignature, error) {
|
||||||
|
if len(signatureAlgorithms) == 0 {
|
||||||
|
return nil, errors.New("go-jose/go-jose: no signature algorithms specified")
|
||||||
|
}
|
||||||
if parsed.Payload == nil {
|
if parsed.Payload == nil {
|
||||||
return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message")
|
return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message")
|
||||||
}
|
}
|
||||||
@ -198,6 +234,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alg := SignatureAlgorithm(signature.Header.Algorithm)
|
||||||
|
if !containsSignatureAlgorithm(signatureAlgorithms, alg) {
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q",
|
||||||
|
alg, signatureAlgorithms)
|
||||||
|
}
|
||||||
|
|
||||||
if signature.header != nil {
|
if signature.header != nil {
|
||||||
signature.Unprotected, err = signature.header.sanitized()
|
signature.Unprotected, err = signature.header.sanitized()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,6 +283,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alg := SignatureAlgorithm(obj.Signatures[i].Header.Algorithm)
|
||||||
|
if !containsSignatureAlgorithm(signatureAlgorithms, alg) {
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q",
|
||||||
|
alg, signatureAlgorithms)
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Signatures[i].header != nil {
|
if obj.Signatures[i].header != nil {
|
||||||
obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized()
|
obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -274,7 +322,11 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parseSignedCompact parses a message in compact format.
|
// parseSignedCompact parses a message in compact format.
|
||||||
func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) {
|
func parseSignedCompact(
|
||||||
|
input string,
|
||||||
|
payload []byte,
|
||||||
|
signatureAlgorithms []SignatureAlgorithm,
|
||||||
|
) (*JSONWebSignature, error) {
|
||||||
parts := strings.Split(input, ".")
|
parts := strings.Split(input, ".")
|
||||||
if len(parts) != 3 {
|
if len(parts) != 3 {
|
||||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
|
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
|
||||||
@ -284,19 +336,19 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error)
|
|||||||
return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
|
return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
|
||||||
}
|
}
|
||||||
|
|
||||||
rawProtected, err := base64URLDecode(parts[0])
|
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload == nil {
|
if payload == nil {
|
||||||
payload, err = base64URLDecode(parts[1])
|
payload, err = base64.RawURLEncoding.DecodeString(parts[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature, err := base64URLDecode(parts[2])
|
signature, err := base64.RawURLEncoding.DecodeString(parts[2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -306,7 +358,7 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error)
|
|||||||
Protected: newBuffer(rawProtected),
|
Protected: newBuffer(rawProtected),
|
||||||
Signature: newBuffer(signature),
|
Signature: newBuffer(signature),
|
||||||
}
|
}
|
||||||
return raw.sanitized()
|
return raw.sanitized(signatureAlgorithms)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {
|
func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {
|
||||||
@ -314,15 +366,18 @@ func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {
|
|||||||
return "", ErrNotSupported
|
return "", ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
serializedProtected := base64.RawURLEncoding.EncodeToString(mustSerializeJSON(obj.Signatures[0].protected))
|
serializedProtected := mustSerializeJSON(obj.Signatures[0].protected)
|
||||||
payload := ""
|
|
||||||
signature := base64.RawURLEncoding.EncodeToString(obj.Signatures[0].Signature)
|
|
||||||
|
|
||||||
|
var payload []byte
|
||||||
if !detached {
|
if !detached {
|
||||||
payload = base64.RawURLEncoding.EncodeToString(obj.payload)
|
payload = obj.payload
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s.%s.%s", serializedProtected, payload, signature), nil
|
return base64JoinWithDots(
|
||||||
|
serializedProtected,
|
||||||
|
payload,
|
||||||
|
obj.Signatures[0].Signature,
|
||||||
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompactSerialize serializes an object using the compact serialization format.
|
// CompactSerialize serializes an object using the compact serialization format.
|
@ -83,6 +83,9 @@ func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg Sig
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key.
|
// OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key.
|
||||||
|
//
|
||||||
|
// Note: this cannot currently be implemented outside this package because of its
|
||||||
|
// unexported method.
|
||||||
type OpaqueKeyEncrypter interface {
|
type OpaqueKeyEncrypter interface {
|
||||||
// KeyID returns the kid
|
// KeyID returns the kid
|
||||||
KeyID() string
|
KeyID() string
|
||||||
@ -121,7 +124,7 @@ func (oke *opaqueKeyEncrypter) encryptKey(cek []byte, alg KeyAlgorithm) (recipie
|
|||||||
return oke.encrypter.encryptKey(cek, alg)
|
return oke.encrypter.encryptKey(cek, alg)
|
||||||
}
|
}
|
||||||
|
|
||||||
//OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key.
|
// OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key.
|
||||||
type OpaqueKeyDecrypter interface {
|
type OpaqueKeyDecrypter interface {
|
||||||
DecryptKey(encryptedKey []byte, header Header) ([]byte, error)
|
DecryptKey(encryptedKey []byte, header Header) ([]byte, error)
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// KeyAlgorithm represents a key management algorithm.
|
// KeyAlgorithm represents a key management algorithm.
|
||||||
@ -71,6 +71,12 @@ var (
|
|||||||
// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
|
// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
|
||||||
// nonce header parameter was included in an unprotected header object.
|
// nonce header parameter was included in an unprotected header object.
|
||||||
ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header")
|
ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header")
|
||||||
|
|
||||||
|
// ErrMissingX5cHeader indicates that the JWT header is missing x5c headers.
|
||||||
|
ErrMissingX5cHeader = errors.New("go-jose/go-jose: no x5c header present in message")
|
||||||
|
|
||||||
|
// ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found.
|
||||||
|
ErrUnsupportedEllipticCurve = errors.New("go-jose/go-jose: unsupported/unknown elliptic curve")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Key management algorithms
|
// Key management algorithms
|
||||||
@ -183,8 +189,13 @@ type Header struct {
|
|||||||
// Unverified certificate chain parsed from x5c header.
|
// Unverified certificate chain parsed from x5c header.
|
||||||
certificates []*x509.Certificate
|
certificates []*x509.Certificate
|
||||||
|
|
||||||
// Any headers not recognised above get unmarshalled
|
// At parse time, each header parameter with a name other than "kid",
|
||||||
// from JSON in a generic manner and placed in this map.
|
// "jwk", "alg", "nonce", or "x5c" will have its value passed to
|
||||||
|
// [json.Unmarshal] to unmarshal it into an interface value.
|
||||||
|
// The resulting value will be stored in this map, with the header
|
||||||
|
// parameter name as the key.
|
||||||
|
//
|
||||||
|
// [json.Unmarshal]: https://pkg.go.dev/encoding/json#Unmarshal
|
||||||
ExtraHeaders map[HeaderKey]interface{}
|
ExtraHeaders map[HeaderKey]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +205,7 @@ type Header struct {
|
|||||||
// not be validated with the given verify options.
|
// not be validated with the given verify options.
|
||||||
func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
|
func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
|
||||||
if len(h.certificates) == 0 {
|
if len(h.certificates) == 0 {
|
||||||
return nil, errors.New("go-jose/go-jose: no x5c header present in message")
|
return nil, ErrMissingX5cHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf := h.certificates[0]
|
leaf := h.certificates[0]
|
||||||
@ -496,7 +507,7 @@ func curveName(crv elliptic.Curve) (string, error) {
|
|||||||
case elliptic.P521():
|
case elliptic.P521():
|
||||||
return "P-521", nil
|
return "P-521", nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve")
|
return "", ErrUnsupportedEllipticCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/json"
|
"github.com/go-jose/go-jose/v4/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NonceSource represents a source of random nonces to go into JWS objects
|
// NonceSource represents a source of random nonces to go into JWS objects
|
||||||
@ -40,6 +40,20 @@ type Signer interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SigningKey represents an algorithm/key used to sign a message.
|
// SigningKey represents an algorithm/key used to sign a message.
|
||||||
|
//
|
||||||
|
// Key must have one of these types:
|
||||||
|
// - ed25519.PrivateKey
|
||||||
|
// - *ecdsa.PrivateKey
|
||||||
|
// - *rsa.PrivateKey
|
||||||
|
// - *JSONWebKey
|
||||||
|
// - JSONWebKey
|
||||||
|
// - []byte (an HMAC key)
|
||||||
|
// - Any type that satisfies the OpaqueSigner interface
|
||||||
|
//
|
||||||
|
// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output:
|
||||||
|
// - HS256: 32 bytes
|
||||||
|
// - HS384: 48 bytes
|
||||||
|
// - HS512: 64 bytes
|
||||||
type SigningKey struct {
|
type SigningKey struct {
|
||||||
Algorithm SignatureAlgorithm
|
Algorithm SignatureAlgorithm
|
||||||
Key interface{}
|
Key interface{}
|
||||||
@ -52,12 +66,22 @@ type SignerOptions struct {
|
|||||||
|
|
||||||
// Optional map of additional keys to be inserted into the protected header
|
// Optional map of additional keys to be inserted into the protected header
|
||||||
// of a JWS object. Some specifications which make use of JWS like to insert
|
// of a JWS object. Some specifications which make use of JWS like to insert
|
||||||
// additional values here. All values must be JSON-serializable.
|
// additional values here.
|
||||||
|
//
|
||||||
|
// Values will be serialized by [json.Marshal] and must be valid inputs to
|
||||||
|
// that function.
|
||||||
|
//
|
||||||
|
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
|
||||||
ExtraHeaders map[HeaderKey]interface{}
|
ExtraHeaders map[HeaderKey]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
|
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
|
||||||
// if necessary. It returns itself and so can be used in a fluent style.
|
// if necessary, and returns the updated SignerOptions.
|
||||||
|
//
|
||||||
|
// The v argument will be serialized by [json.Marshal] and must be a valid
|
||||||
|
// input to that function.
|
||||||
|
//
|
||||||
|
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
|
||||||
func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {
|
func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {
|
||||||
if so.ExtraHeaders == nil {
|
if so.ExtraHeaders == nil {
|
||||||
so.ExtraHeaders = map[HeaderKey]interface{}{}
|
so.ExtraHeaders = map[HeaderKey]interface{}{}
|
||||||
@ -173,11 +197,11 @@ func newVerifier(verificationKey interface{}) (payloadVerifier, error) {
|
|||||||
return newVerifier(verificationKey.Key)
|
return newVerifier(verificationKey.Key)
|
||||||
case *JSONWebKey:
|
case *JSONWebKey:
|
||||||
return newVerifier(verificationKey.Key)
|
return newVerifier(verificationKey.Key)
|
||||||
|
case OpaqueVerifier:
|
||||||
|
return &opaqueVerifier{verifier: verificationKey}, nil
|
||||||
|
default:
|
||||||
|
return nil, ErrUnsupportedKeyType
|
||||||
}
|
}
|
||||||
if ov, ok := verificationKey.(OpaqueVerifier); ok {
|
|
||||||
return &opaqueVerifier{verifier: ov}, nil
|
|
||||||
}
|
|
||||||
return nil, ErrUnsupportedKeyType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
|
func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
|
||||||
@ -204,11 +228,11 @@ func makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipient
|
|||||||
return newJWKSigner(alg, signingKey)
|
return newJWKSigner(alg, signingKey)
|
||||||
case *JSONWebKey:
|
case *JSONWebKey:
|
||||||
return newJWKSigner(alg, *signingKey)
|
return newJWKSigner(alg, *signingKey)
|
||||||
|
case OpaqueSigner:
|
||||||
|
return newOpaqueSigner(alg, signingKey)
|
||||||
|
default:
|
||||||
|
return recipientSigInfo{}, ErrUnsupportedKeyType
|
||||||
}
|
}
|
||||||
if signer, ok := signingKey.(OpaqueSigner); ok {
|
|
||||||
return newOpaqueSigner(alg, signer)
|
|
||||||
}
|
|
||||||
return recipientSigInfo{}, ErrUnsupportedKeyType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {
|
func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {
|
||||||
@ -321,12 +345,28 @@ func (ctx *genericSigner) Options() SignerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify validates the signature on the object and returns the payload.
|
// Verify validates the signature on the object and returns the payload.
|
||||||
// This function does not support multi-signature, if you desire multi-sig
|
// This function does not support multi-signature. If you desire multi-signature
|
||||||
// verification use VerifyMulti instead.
|
// verification use VerifyMulti instead.
|
||||||
//
|
//
|
||||||
// Be careful when verifying signatures based on embedded JWKs inside the
|
// Be careful when verifying signatures based on embedded JWKs inside the
|
||||||
// payload header. You cannot assume that the key received in a payload is
|
// payload header. You cannot assume that the key received in a payload is
|
||||||
// trusted.
|
// trusted.
|
||||||
|
//
|
||||||
|
// The verificationKey argument must have one of these types:
|
||||||
|
// - ed25519.PublicKey
|
||||||
|
// - *ecdsa.PublicKey
|
||||||
|
// - *rsa.PublicKey
|
||||||
|
// - *JSONWebKey
|
||||||
|
// - JSONWebKey
|
||||||
|
// - *JSONWebKeySet
|
||||||
|
// - JSONWebKeySet
|
||||||
|
// - []byte (an HMAC key)
|
||||||
|
// - Any type that implements the OpaqueVerifier interface.
|
||||||
|
//
|
||||||
|
// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output:
|
||||||
|
// - HS256: 32 bytes
|
||||||
|
// - HS384: 48 bytes
|
||||||
|
// - HS512: 64 bytes
|
||||||
func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
|
func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
|
||||||
err := obj.DetachedVerify(obj.payload, verificationKey)
|
err := obj.DetachedVerify(obj.payload, verificationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -346,8 +386,14 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {
|
|||||||
// most cases, you will probably want to use Verify instead. DetachedVerify
|
// most cases, you will probably want to use Verify instead. DetachedVerify
|
||||||
// is only useful if you have a payload and signature that are separated from
|
// is only useful if you have a payload and signature that are separated from
|
||||||
// each other.
|
// each other.
|
||||||
|
//
|
||||||
|
// The verificationKey argument must have one of the types allowed for the
|
||||||
|
// verificationKey argument of JSONWebSignature.Verify().
|
||||||
func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
|
func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
|
||||||
key := tryJWKS(verificationKey, obj.headers()...)
|
key, err := tryJWKS(verificationKey, obj.headers()...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
verifier, err := newVerifier(key)
|
verifier, err := newVerifier(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -388,6 +434,9 @@ func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey inter
|
|||||||
// returns the index of the signature that was verified, along with the signature
|
// returns the index of the signature that was verified, along with the signature
|
||||||
// object and the payload. We return the signature and index to guarantee that
|
// object and the payload. We return the signature and index to guarantee that
|
||||||
// callers are getting the verified value.
|
// callers are getting the verified value.
|
||||||
|
//
|
||||||
|
// The verificationKey argument must have one of the types allowed for the
|
||||||
|
// verificationKey argument of JSONWebSignature.Verify().
|
||||||
func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {
|
func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {
|
||||||
idx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey)
|
idx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -405,8 +454,14 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa
|
|||||||
// DetachedVerifyMulti is only useful if you have a payload and signature that are
|
// DetachedVerifyMulti is only useful if you have a payload and signature that are
|
||||||
// separated from each other, and the signature can have multiple signers at the
|
// separated from each other, and the signature can have multiple signers at the
|
||||||
// same time.
|
// same time.
|
||||||
|
//
|
||||||
|
// The verificationKey argument must have one of the types allowed for the
|
||||||
|
// verificationKey argument of JSONWebSignature.Verify().
|
||||||
func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
|
func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
|
||||||
key := tryJWKS(verificationKey, obj.headers()...)
|
key, err := tryJWKS(verificationKey, obj.headers()...)
|
||||||
|
if err != nil {
|
||||||
|
return -1, Signature{}, err
|
||||||
|
}
|
||||||
verifier, err := newVerifier(key)
|
verifier, err := newVerifier(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, Signature{}, err
|
return -1, Signature{}, err
|
@ -32,7 +32,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
|
|
||||||
josecipher "github.com/go-jose/go-jose/v3/cipher"
|
josecipher "github.com/go-jose/go-jose/v4/cipher"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RandReader is a cryptographically secure random number generator (stubbed out in tests).
|
// RandReader is a cryptographically secure random number generator (stubbed out in tests).
|
||||||
@ -40,12 +40,17 @@ var RandReader = rand.Reader
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// RFC7518 recommends a minimum of 1,000 iterations:
|
// RFC7518 recommends a minimum of 1,000 iterations:
|
||||||
// https://tools.ietf.org/html/rfc7518#section-4.8.1.2
|
// - https://tools.ietf.org/html/rfc7518#section-4.8.1.2
|
||||||
|
//
|
||||||
// NIST recommends a minimum of 10,000:
|
// NIST recommends a minimum of 10,000:
|
||||||
// https://pages.nist.gov/800-63-3/sp800-63b.html
|
// - https://pages.nist.gov/800-63-3/sp800-63b.html
|
||||||
// 1Password uses 100,000:
|
//
|
||||||
// https://support.1password.com/pbkdf2/
|
// 1Password increased in 2023 from 100,000 to 650,000:
|
||||||
defaultP2C = 100000
|
// - https://support.1password.com/pbkdf2/
|
||||||
|
//
|
||||||
|
// OWASP recommended 600,000 in Dec 2022:
|
||||||
|
// - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2
|
||||||
|
defaultP2C = 600000
|
||||||
// Default salt size: 128 bits
|
// Default salt size: 128 bits
|
||||||
defaultP2SSize = 16
|
defaultP2SSize = 16
|
||||||
)
|
)
|
||||||
@ -415,6 +420,11 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
|
|||||||
if p2c <= 0 {
|
if p2c <= 0 {
|
||||||
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer")
|
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer")
|
||||||
}
|
}
|
||||||
|
if p2c > 1000000 {
|
||||||
|
// An unauthenticated attacker can set a high P2C value. Set an upper limit to avoid
|
||||||
|
// DoS attacks.
|
||||||
|
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: too high")
|
||||||
|
}
|
||||||
|
|
||||||
// salt is UTF8(Alg) || 0x00 || Salt Input
|
// salt is UTF8(Alg) || 0x00 || Salt Input
|
||||||
alg := headers.getAlgorithm()
|
alg := headers.getAlgorithm()
|
||||||
@ -444,7 +454,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
|
|||||||
func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
|
func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
|
||||||
mac, err := ctx.hmac(payload, alg)
|
mac, err := ctx.hmac(payload, alg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Signature{}, errors.New("go-jose/go-jose: failed to compute hmac")
|
return Signature{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return Signature{
|
return Signature{
|
||||||
@ -476,12 +486,24 @@ func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureA
|
|||||||
func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) {
|
func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) {
|
||||||
var hash func() hash.Hash
|
var hash func() hash.Hash
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7518#section-3.2
|
||||||
|
// A key of the same size as the hash output (for instance, 256 bits for
|
||||||
|
// "HS256") or larger MUST be used
|
||||||
switch alg {
|
switch alg {
|
||||||
case HS256:
|
case HS256:
|
||||||
|
if len(ctx.key)*8 < 256 {
|
||||||
|
return nil, ErrInvalidKeySize
|
||||||
|
}
|
||||||
hash = sha256.New
|
hash = sha256.New
|
||||||
case HS384:
|
case HS384:
|
||||||
|
if len(ctx.key)*8 < 384 {
|
||||||
|
return nil, ErrInvalidKeySize
|
||||||
|
}
|
||||||
hash = sha512.New384
|
hash = sha512.New384
|
||||||
case HS512:
|
case HS512:
|
||||||
|
if len(ctx.key)*8 < 512 {
|
||||||
|
return nil, ErrInvalidKeySize
|
||||||
|
}
|
||||||
hash = sha512.New
|
hash = sha512.New
|
||||||
default:
|
default:
|
||||||
return nil, ErrUnsupportedAlgorithm
|
return nil, ErrUnsupportedAlgorithm
|
3
vendor/github.com/goccy/go-json/.golangci.yml
generated
vendored
3
vendor/github.com/goccy/go-json/.golangci.yml
generated
vendored
@ -56,6 +56,9 @@ linters:
|
|||||||
- cyclop
|
- cyclop
|
||||||
- containedctx
|
- containedctx
|
||||||
- revive
|
- revive
|
||||||
|
- nosnakecase
|
||||||
|
- exhaustruct
|
||||||
|
- depguard
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
|
2
vendor/github.com/goccy/go-json/Makefile
generated
vendored
2
vendor/github.com/goccy/go-json/Makefile
generated
vendored
@ -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.48.0; \
|
GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2; \
|
||||||
rm -rf $$GOLANGCI_LINT_TMP_DIR; \
|
rm -rf $$GOLANGCI_LINT_TMP_DIR; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
vendor/github.com/goccy/go-json/encode.go
generated
vendored
4
vendor/github.com/goccy/go-json/encode.go
generated
vendored
@ -52,7 +52,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...)
|
err := e.encodeWithOption(rctx, v, optFuncs...) //nolint: contextcheck
|
||||||
|
|
||||||
encoder.ReleaseRuntimeContext(rctx)
|
encoder.ReleaseRuntimeContext(rctx)
|
||||||
return err
|
return err
|
||||||
@ -120,7 +120,7 @@ func marshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOption
|
|||||||
optFunc(rctx.Option)
|
optFunc(rctx.Option)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := encode(rctx, v)
|
buf, err := encode(rctx, v) //nolint: contextcheck
|
||||||
if err != nil {
|
if err != nil {
|
||||||
encoder.ReleaseRuntimeContext(rctx)
|
encoder.ReleaseRuntimeContext(rctx)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/decoder/ptr.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/decoder/ptr.go
generated
vendored
@ -85,6 +85,7 @@ 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
|
||||||
|
2
vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go
generated
vendored
2
vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go
generated
vendored
@ -147,7 +147,7 @@ func (d *unmarshalTextDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int
|
|||||||
return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path")
|
return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path")
|
||||||
}
|
}
|
||||||
|
|
||||||
func unquoteBytes(s []byte) (t []byte, ok bool) {
|
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
|
||||||
|
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])
|
||||||
cursor += 2
|
|
||||||
start = cursor + 3
|
start = cursor + 3
|
||||||
|
cursor += 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch c {
|
switch c {
|
||||||
|
2
vendor/github.com/goccy/go-json/internal/encoder/compiler.go
generated
vendored
2
vendor/github.com/goccy/go-json/internal/encoder/compiler.go
generated
vendored
@ -480,7 +480,7 @@ 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.isPtrMarshalJSONType(typ):
|
case c.implementsMarshalJSONType(typ) || c.implementsMarshalJSONType(runtime.PtrTo(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)
|
||||||
|
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,3 +1,27 @@
|
|||||||
|
// 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 (
|
||||||
|
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,3 +1,27 @@
|
|||||||
|
// 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 (
|
||||||
|
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,7 +252,6 @@ 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
|
||||||
|
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,7 +166,6 @@ 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)
|
||||||
}
|
}
|
||||||
@ -264,14 +263,13 @@ 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)
|
||||||
}
|
}
|
||||||
@ -299,7 +297,6 @@ 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.
|
||||||
|
72
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
72
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,5 +1,77 @@
|
|||||||
# 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
|
## v4.11.1 - 2023-07-16
|
||||||
|
|
||||||
**Fixes**
|
**Fixes**
|
||||||
|
4
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
4
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
@ -31,6 +31,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.17"
|
goversion ?= "1.19"
|
||||||
test_version: ## Run tests inside Docker with given version (defaults to 1.17 oldest supported). Example: make test_version goversion=1.17
|
test_version: ## Run tests inside Docker with given version (defaults to 1.19 oldest supported). Example: make test_version goversion=1.19
|
||||||
@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"
|
||||||
|
35
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
35
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
@ -3,26 +3,24 @@
|
|||||||
[![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)
|
||||||
[![Build Status](http://img.shields.io/travis/labstack/echo.svg?style=flat-square)](https://travis-ci.org/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)
|
||||||
[![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)
|
||||||
|
|
||||||
## Supported Go versions
|
## Echo
|
||||||
|
|
||||||
Latest version of Echo supports last four Go major [releases](https://go.dev/doc/devel/release) and might work with
|
High performance, extensible, minimalist Go web framework.
|
||||||
older versions.
|
|
||||||
|
|
||||||
As of version 4.0.0, Echo is available as a [Go module](https://github.com/golang/go/wiki/Modules).
|
* [Official website](https://echo.labstack.com)
|
||||||
Therefore a Go version capable of understanding /vN suffixed imports is required:
|
* [Quick start](https://echo.labstack.com/docs/quick-start)
|
||||||
|
* [Middlewares](https://echo.labstack.com/docs/category/middleware)
|
||||||
|
|
||||||
Any of these versions will allow you to import Echo as `github.com/labstack/echo/v4` which is the recommended
|
Help and questions: [Github Discussions](https://github.com/labstack/echo/discussions)
|
||||||
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
|
||||||
@ -38,6 +36,18 @@ For older versions, please use the latest v3 tag.
|
|||||||
- 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>
|
||||||
@ -57,6 +67,7 @@ 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
|
||||||
|
|
||||||
@ -117,10 +128,6 @@ of middlewares in this list.
|
|||||||
|
|
||||||
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**
|
||||||
|
148
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
148
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -11,23 +14,28 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// Binder is the interface that wraps the Bind method.
|
||||||
// Binder is the interface that wraps the Bind method.
|
type Binder interface {
|
||||||
Binder interface {
|
Bind(i interface{}, c Context) error
|
||||||
Bind(i interface{}, c Context) error
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultBinder is the default implementation of the Binder interface.
|
// DefaultBinder is the default implementation of the Binder interface.
|
||||||
DefaultBinder struct{}
|
type 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.
|
||||||
BindUnmarshaler interface {
|
type 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 {
|
||||||
@ -131,10 +139,29 @@ 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()
|
||||||
|
|
||||||
// Map
|
// Support binding to limited Map destinations:
|
||||||
if typ.Kind() == reflect.Map {
|
// - map[string][]string,
|
||||||
|
// - 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 {
|
||||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
if isElemString {
|
||||||
|
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
||||||
|
} else {
|
||||||
|
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -161,14 +188,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 && structField.Kind() == reflect.Struct && inputFieldName != "" {
|
if typeField.Anonymous && structFieldKind == 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 binded only when they have explicit tag
|
// structs that implement BindUnmarshaler are bound 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
|
||||||
@ -197,27 +224,46 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this first, in case we're dealing with an alias to an array type
|
// NOTE: algorithm here is not particularly sophisticated. It probably does not work with absurd types like `**[]*int`
|
||||||
if ok, err := unmarshalField(typeField.Type.Kind(), inputValue[0], structField); ok {
|
// but it is smart enough to handle niche cases like `*int`,`*[]string`,`[]*int` .
|
||||||
|
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
numElems := len(inputValue)
|
if ok, err := unmarshalInputToField(typeField.Type.Kind(), inputValue[0], structField); ok {
|
||||||
if structFieldKind == reflect.Slice && numElems > 0 {
|
if err != nil {
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val.Field(i).Set(slice)
|
structField.Set(slice)
|
||||||
} else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
|
continue
|
||||||
return err
|
}
|
||||||
|
|
||||||
|
if err := setWithProperType(structFieldKind, inputValue[0], structField); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -225,7 +271,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 := unmarshalField(valueKind, val, structField); ok {
|
if ok, err := unmarshalInputToField(valueKind, val, structField); ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,35 +312,41 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalField(valueKind reflect.Kind, val string, field reflect.Value) (bool, error) {
|
func unmarshalInputsToField(valueKind reflect.Kind, values []string, field reflect.Value) (bool, error) {
|
||||||
switch valueKind {
|
if valueKind == reflect.Ptr {
|
||||||
case reflect.Ptr:
|
if field.IsNil() {
|
||||||
return unmarshalFieldPtr(val, field)
|
field.Set(reflect.New(field.Type().Elem()))
|
||||||
default:
|
}
|
||||||
return unmarshalFieldNonPtr(val, field)
|
field = field.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fieldIValue := field.Addr().Interface()
|
||||||
|
unmarshaler, ok := fieldIValue.(bindMultipleUnmarshaler)
|
||||||
|
if !ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, unmarshaler.UnmarshalParams(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalFieldNonPtr(value string, field reflect.Value) (bool, error) {
|
func unmarshalInputToField(valueKind reflect.Kind, val string, field reflect.Value) (bool, error) {
|
||||||
fieldIValue := field.Addr().Interface()
|
if valueKind == reflect.Ptr {
|
||||||
if unmarshaler, ok := fieldIValue.(BindUnmarshaler); ok {
|
if field.IsNil() {
|
||||||
return true, unmarshaler.UnmarshalParam(value)
|
field.Set(reflect.New(field.Type().Elem()))
|
||||||
|
}
|
||||||
|
field = field.Elem()
|
||||||
}
|
}
|
||||||
if unmarshaler, ok := fieldIValue.(encoding.TextUnmarshaler); ok {
|
|
||||||
return true, unmarshaler.UnmarshalText([]byte(value))
|
fieldIValue := field.Addr().Interface()
|
||||||
|
switch unmarshaler := fieldIValue.(type) {
|
||||||
|
case BindUnmarshaler:
|
||||||
|
return true, unmarshaler.UnmarshalParam(val)
|
||||||
|
case encoding.TextUnmarshaler:
|
||||||
|
return true, unmarshaler.UnmarshalText([]byte(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
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"
|
||||||
|
5
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
5
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -1323,7 +1326,7 @@ func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExi
|
|||||||
case time.Second:
|
case time.Second:
|
||||||
*dest = time.Unix(n, 0)
|
*dest = time.Unix(n, 0)
|
||||||
case time.Millisecond:
|
case time.Millisecond:
|
||||||
*dest = time.Unix(n/1e3, (n%1e3)*1e6) // TODO: time.UnixMilli(n) exists since Go1.17 switch to that when min version allows
|
*dest = time.UnixMilli(n)
|
||||||
case time.Nanosecond:
|
case time.Nanosecond:
|
||||||
*dest = time.Unix(0, n)
|
*dest = time.Unix(0, n)
|
||||||
}
|
}
|
||||||
|
325
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
325
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -13,204 +16,216 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// Context represents the context of the current HTTP request. It holds request and
|
||||||
// Context represents the context of the current HTTP request. It holds request and
|
// response objects, path, path parameters, data and registered handler.
|
||||||
// response objects, path, path parameters, data and registered handler.
|
type Context interface {
|
||||||
Context interface {
|
// Request returns `*http.Request`.
|
||||||
// Request returns `*http.Request`.
|
Request() *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 path params, query params and the request body into provided type `i`. The default binder
|
||||||
// binds body based on Content-Type header.
|
// binds body 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 global 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
|
// A side-effect of calling global error handler is that now Response has been committed (sent to the client) and
|
||||||
// middlewares up in chain can not change Response status code or Response body anymore.
|
// 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.
|
// Avoid using this method in handlers as no middleware will be able to effectively handle errors after that.
|
||||||
Error(err error)
|
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
|
// SetLogger 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
context struct {
|
type context struct {
|
||||||
request *http.Request
|
request *http.Request
|
||||||
response *Response
|
response *Response
|
||||||
path string
|
query url.Values
|
||||||
pnames []string
|
echo *Echo
|
||||||
pvalues []string
|
logger Logger
|
||||||
query url.Values
|
|
||||||
handler HandlerFunc
|
store Map
|
||||||
store Map
|
lock sync.RWMutex
|
||||||
echo *Echo
|
|
||||||
logger Logger
|
// following fields are set by Router
|
||||||
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.
|
||||||
@ -329,13 +344,9 @@ 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 overriden in a Context#SetParamValues
|
// probably those values will be overridden 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
|
||||||
@ -347,11 +358,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 at all times
|
// NOTE: Don't just set c.pvalues = values, because it has to have length c.echo.maxParam (or bigger) 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 > *c.echo.maxParam {
|
if limit > len(c.pvalues) {
|
||||||
limit = *c.echo.maxParam
|
c.pvalues = make([]string, limit)
|
||||||
}
|
}
|
||||||
for i := 0; i < limit; i++ {
|
for i := 0; i < limit; i++ {
|
||||||
c.pvalues[i] = values[i]
|
c.pvalues[i] = values[i]
|
||||||
@ -489,7 +500,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(MIMEApplicationJSONCharsetUTF8)
|
c.writeContentType(MIMEApplicationJSON)
|
||||||
c.response.Status = code
|
c.response.Status = code
|
||||||
return c.echo.JSONSerializer.Serialize(c, i, indent)
|
return c.echo.JSONSerializer.Serialize(c, i, indent)
|
||||||
}
|
}
|
||||||
@ -507,7 +518,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, MIMEApplicationJSONCharsetUTF8, b)
|
return c.Blob(code, MIMEApplicationJSON, 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) {
|
||||||
@ -584,8 +595,10 @@ 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=%q", dispositionType, name))
|
c.response.Header().Set(HeaderContentDisposition, fmt.Sprintf(`%s; filename="%s"`, dispositionType, quoteEscaper.Replace(name)))
|
||||||
return c.File(file)
|
return c.File(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,8 +653,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 at all times
|
// NOTE: Don't reset because it has to have length c.echo.maxParam (or bigger) at all times
|
||||||
for i := 0; i < *c.echo.maxParam; i++ {
|
for i := 0; i < len(c.pvalues); i++ {
|
||||||
c.pvalues[i] = ""
|
c.pvalues[i] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/labstack/echo/v4/context_fs.go
generated
vendored
3
vendor/github.com/labstack/echo/v4/context_fs.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
225
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
225
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
@ -60,97 +63,95 @@ import (
|
|||||||
"golang.org/x/net/http2/h2c"
|
"golang.org/x/net/http2/h2c"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// Echo is the top-level framework instance.
|
||||||
// Echo is the top-level framework instance.
|
//
|
||||||
//
|
// Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
|
||||||
// Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
|
// fields from handlers/middlewares and changing field values at the same time leads to data-races.
|
||||||
// fields from handlers/middlewares and changing field values at the same time leads to data-races.
|
// Adding new routes after the server has been started is also not safe!
|
||||||
// Adding new routes after the server has been started is also not safe!
|
type Echo struct {
|
||||||
Echo struct {
|
filesystem
|
||||||
filesystem
|
common
|
||||||
common
|
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
||||||
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
|
// listener address info (on which interface/port was listener bound) without having data races.
|
||||||
// listener address info (on which interface/port was listener binded) without having data races.
|
startupMutex sync.RWMutex
|
||||||
startupMutex sync.RWMutex
|
colorer *color.Color
|
||||||
colorer *color.Color
|
|
||||||
|
|
||||||
// premiddleware are middlewares that are run before routing is done. In case a pre-middleware returns
|
// premiddleware are middlewares that are run before routing is done. In case a pre-middleware returns
|
||||||
// an error the router is not executed and the request will end up in the global error handler.
|
// an error the router is not executed and the request will end up in the global error handler.
|
||||||
premiddleware []MiddlewareFunc
|
premiddleware []MiddlewareFunc
|
||||||
middleware []MiddlewareFunc
|
middleware []MiddlewareFunc
|
||||||
maxParam *int
|
maxParam *int
|
||||||
router *Router
|
router *Router
|
||||||
routers map[string]*Router
|
routers map[string]*Router
|
||||||
pool sync.Pool
|
pool sync.Pool
|
||||||
|
|
||||||
StdLogger *stdLog.Logger
|
StdLogger *stdLog.Logger
|
||||||
Server *http.Server
|
Server *http.Server
|
||||||
TLSServer *http.Server
|
TLSServer *http.Server
|
||||||
Listener net.Listener
|
Listener net.Listener
|
||||||
TLSListener net.Listener
|
TLSListener net.Listener
|
||||||
AutoTLSManager autocert.Manager
|
AutoTLSManager autocert.Manager
|
||||||
DisableHTTP2 bool
|
DisableHTTP2 bool
|
||||||
Debug bool
|
Debug bool
|
||||||
HideBanner bool
|
HideBanner bool
|
||||||
HidePort bool
|
HidePort bool
|
||||||
HTTPErrorHandler HTTPErrorHandler
|
HTTPErrorHandler HTTPErrorHandler
|
||||||
Binder Binder
|
Binder Binder
|
||||||
JSONSerializer JSONSerializer
|
JSONSerializer JSONSerializer
|
||||||
Validator Validator
|
Validator Validator
|
||||||
Renderer Renderer
|
Renderer Renderer
|
||||||
Logger Logger
|
Logger Logger
|
||||||
IPExtractor IPExtractor
|
IPExtractor IPExtractor
|
||||||
ListenerNetwork string
|
ListenerNetwork string
|
||||||
|
|
||||||
// OnAddRouteHandler is called when Echo adds new route to specific host router.
|
// OnAddRouteHandler is called when Echo adds new route to specific host router.
|
||||||
OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc)
|
OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route contains a handler and information for matching against requests.
|
// Route contains a handler and information for matching against requests.
|
||||||
Route struct {
|
type Route struct {
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPError represents an error that occurred while handling a request.
|
// HTTPError represents an error that occurred while handling a request.
|
||||||
HTTPError struct {
|
type HTTPError struct {
|
||||||
Code int `json:"-"`
|
Code int `json:"-"`
|
||||||
Message interface{} `json:"message"`
|
Message interface{} `json:"message"`
|
||||||
Internal error `json:"-"` // Stores the error returned by an external dependency
|
Internal error `json:"-"` // Stores the error returned by an external dependency
|
||||||
}
|
}
|
||||||
|
|
||||||
// MiddlewareFunc defines a function to process middleware.
|
// MiddlewareFunc defines a function to process middleware.
|
||||||
MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
type MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
||||||
|
|
||||||
// HandlerFunc defines a function to serve HTTP requests.
|
// HandlerFunc defines a function to serve HTTP requests.
|
||||||
HandlerFunc func(c Context) error
|
type HandlerFunc func(c Context) error
|
||||||
|
|
||||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||||
HTTPErrorHandler func(err error, c Context)
|
type HTTPErrorHandler func(err error, c Context)
|
||||||
|
|
||||||
// Validator is the interface that wraps the Validate function.
|
// Validator is the interface that wraps the Validate function.
|
||||||
Validator interface {
|
type Validator interface {
|
||||||
Validate(i interface{}) error
|
Validate(i interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.
|
// JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.
|
||||||
JSONSerializer interface {
|
type JSONSerializer interface {
|
||||||
Serialize(c Context, i interface{}, indent string) error
|
Serialize(c Context, i interface{}, indent string) error
|
||||||
Deserialize(c Context, i interface{}) error
|
Deserialize(c Context, i interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderer is the interface that wraps the Render function.
|
// Renderer is the interface that wraps the Render function.
|
||||||
Renderer interface {
|
type Renderer interface {
|
||||||
Render(io.Writer, string, interface{}, Context) error
|
Render(io.Writer, string, interface{}, Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map defines a generic map of type `map[string]interface{}`.
|
// Map defines a generic map of type `map[string]interface{}`.
|
||||||
Map map[string]interface{}
|
type Map map[string]interface{}
|
||||||
|
|
||||||
// Common struct for Echo & Group.
|
// Common struct for Echo & Group.
|
||||||
common struct{}
|
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.
|
||||||
@ -169,7 +170,12 @@ const (
|
|||||||
|
|
||||||
// MIME types
|
// MIME types
|
||||||
const (
|
const (
|
||||||
MIMEApplicationJSON = "application/json"
|
// MIMEApplicationJSON JavaScript Object Notation (JSON) https://www.rfc-editor.org/rfc/rfc8259
|
||||||
|
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
|
||||||
@ -259,7 +265,7 @@ const (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Version of Echo
|
// Version of Echo
|
||||||
Version = "4.11.1"
|
Version = "4.12.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 = `
|
||||||
@ -274,21 +280,19 @@ ____________________________________O/_______
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var methods = [...]string{
|
||||||
methods = [...]string{
|
http.MethodConnect,
|
||||||
http.MethodConnect,
|
http.MethodDelete,
|
||||||
http.MethodDelete,
|
http.MethodGet,
|
||||||
http.MethodGet,
|
http.MethodHead,
|
||||||
http.MethodHead,
|
http.MethodOptions,
|
||||||
http.MethodOptions,
|
http.MethodPatch,
|
||||||
http.MethodPatch,
|
http.MethodPost,
|
||||||
http.MethodPost,
|
PROPFIND,
|
||||||
PROPFIND,
|
http.MethodPut,
|
||||||
http.MethodPut,
|
http.MethodTrace,
|
||||||
http.MethodTrace,
|
REPORT,
|
||||||
REPORT,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
var (
|
var (
|
||||||
@ -341,22 +345,23 @@ var (
|
|||||||
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error handlers
|
// NotFoundHandler is the handler that router uses in case there was no matching route found. Returns an error that results
|
||||||
var (
|
// HTTP 404 status code.
|
||||||
NotFoundHandler = func(c Context) error {
|
var NotFoundHandler = func(c Context) error {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodNotAllowedHandler = func(c Context) error {
|
// MethodNotAllowedHandler is the handler thar router uses in case there was no matching route found but there was
|
||||||
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
// another matching routes for that requested URL. Returns an error that results HTTP 405 Method Not Allowed status code.
|
||||||
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
var MethodNotAllowedHandler = func(c Context) error {
|
||||||
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
||||||
if ok && routerAllowMethods != "" {
|
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
||||||
c.Response().Header().Set(HeaderAllow, routerAllowMethods)
|
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
||||||
}
|
if ok && routerAllowMethods != "" {
|
||||||
return ErrMethodNotAllowed
|
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) {
|
||||||
@ -414,7 +419,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 "commited" the
|
// handler. Then the error that global error handler received will be ignored because we have already "committed" 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) {
|
||||||
|
|
||||||
|
3
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
3
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
25
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
25
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
@ -1,21 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// Group is a set of sub-routes for a specified route. It can be used for inner
|
||||||
// Group is a set of sub-routes for a specified route. It can be used for inner
|
// routes that share a common middleware or functionality that should be separate
|
||||||
// routes that share a common middleware or functionality that should be separate
|
// from the parent echo instance while still inheriting from it.
|
||||||
// from the parent echo instance while still inheriting from it.
|
type Group struct {
|
||||||
Group struct {
|
common
|
||||||
common
|
host string
|
||||||
host string
|
prefix string
|
||||||
prefix string
|
middleware []MiddlewareFunc
|
||||||
middleware []MiddlewareFunc
|
echo *Echo
|
||||||
echo *Echo
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Use implements `Echo#Use()` for sub-routes within the Group.
|
// Use implements `Echo#Use()` for sub-routes within the Group.
|
||||||
func (g *Group) Use(middleware ...MiddlewareFunc) {
|
func (g *Group) Use(middleware ...MiddlewareFunc) {
|
||||||
|
3
vendor/github.com/labstack/echo/v4/group_fs.go
generated
vendored
3
vendor/github.com/labstack/echo/v4/group_fs.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
17
vendor/github.com/labstack/echo/v4/ip.go
generated
vendored
17
vendor/github.com/labstack/echo/v4/ip.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -64,7 +67,7 @@ XFF: "x" "x, a" "x, a, b"
|
|||||||
```
|
```
|
||||||
|
|
||||||
In this case, use **first _untrustable_ IP reading from right**. Never use first one reading from left, as it is
|
In this case, use **first _untrustable_ IP reading from right**. Never use first one reading from left, as it is
|
||||||
configurable by client. Here "trustable" means "you are sure the IP address belongs to your infrastructre".
|
configurable by client. Here "trustable" means "you are sure the IP address belongs to your infrastructure".
|
||||||
In above example, if `b` and `c` are trustable, the IP address of the client is `a` for both cases, never be `x`.
|
In above example, if `b` and `c` are trustable, the IP address of the client is `a` for both cases, never be `x`.
|
||||||
|
|
||||||
In Echo, use `ExtractIPFromXFFHeader(...TrustOption)`.
|
In Echo, use `ExtractIPFromXFFHeader(...TrustOption)`.
|
||||||
@ -225,15 +228,21 @@ func extractIP(req *http.Request) string {
|
|||||||
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
|
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
|
||||||
checker := newIPChecker(options)
|
checker := newIPChecker(options)
|
||||||
return func(req *http.Request) string {
|
return func(req *http.Request) string {
|
||||||
|
directIP := extractIP(req)
|
||||||
realIP := req.Header.Get(HeaderXRealIP)
|
realIP := req.Header.Get(HeaderXRealIP)
|
||||||
if realIP != "" {
|
if realIP == "" {
|
||||||
|
return directIP
|
||||||
|
}
|
||||||
|
|
||||||
|
if checker.trust(net.ParseIP(directIP)) {
|
||||||
realIP = strings.TrimPrefix(realIP, "[")
|
realIP = strings.TrimPrefix(realIP, "[")
|
||||||
realIP = strings.TrimSuffix(realIP, "]")
|
realIP = strings.TrimSuffix(realIP, "]")
|
||||||
if ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
|
if rIP := net.ParseIP(realIP); rIP != nil {
|
||||||
return realIP
|
return realIP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extractIP(req)
|
|
||||||
|
return directIP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
vendor/github.com/labstack/echo/v4/json.go
generated
vendored
3
vendor/github.com/labstack/echo/v4/json.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
70
vendor/github.com/labstack/echo/v4/log.go
generated
vendored
70
vendor/github.com/labstack/echo/v4/log.go
generated
vendored
@ -1,41 +1,41 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/labstack/gommon/log"
|
"github.com/labstack/gommon/log"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// Logger defines the logging interface.
|
||||||
// Logger defines the logging interface.
|
type Logger interface {
|
||||||
Logger interface {
|
Output() io.Writer
|
||||||
Output() io.Writer
|
SetOutput(w io.Writer)
|
||||||
SetOutput(w io.Writer)
|
Prefix() string
|
||||||
Prefix() string
|
SetPrefix(p string)
|
||||||
SetPrefix(p string)
|
Level() log.Lvl
|
||||||
Level() log.Lvl
|
SetLevel(v log.Lvl)
|
||||||
SetLevel(v log.Lvl)
|
SetHeader(h string)
|
||||||
SetHeader(h string)
|
Print(i ...interface{})
|
||||||
Print(i ...interface{})
|
Printf(format string, args ...interface{})
|
||||||
Printf(format string, args ...interface{})
|
Printj(j log.JSON)
|
||||||
Printj(j log.JSON)
|
Debug(i ...interface{})
|
||||||
Debug(i ...interface{})
|
Debugf(format string, args ...interface{})
|
||||||
Debugf(format string, args ...interface{})
|
Debugj(j log.JSON)
|
||||||
Debugj(j log.JSON)
|
Info(i ...interface{})
|
||||||
Info(i ...interface{})
|
Infof(format string, args ...interface{})
|
||||||
Infof(format string, args ...interface{})
|
Infoj(j log.JSON)
|
||||||
Infoj(j log.JSON)
|
Warn(i ...interface{})
|
||||||
Warn(i ...interface{})
|
Warnf(format string, args ...interface{})
|
||||||
Warnf(format string, args ...interface{})
|
Warnj(j log.JSON)
|
||||||
Warnj(j log.JSON)
|
Error(i ...interface{})
|
||||||
Error(i ...interface{})
|
Errorf(format string, args ...interface{})
|
||||||
Errorf(format string, args ...interface{})
|
Errorj(j log.JSON)
|
||||||
Errorj(j log.JSON)
|
Fatal(i ...interface{})
|
||||||
Fatal(i ...interface{})
|
Fatalj(j log.JSON)
|
||||||
Fatalj(j log.JSON)
|
Fatalf(format string, args ...interface{})
|
||||||
Fatalf(format string, args ...interface{})
|
Panic(i ...interface{})
|
||||||
Panic(i ...interface{})
|
Panicj(j log.JSON)
|
||||||
Panicj(j log.JSON)
|
Panicf(format string, args ...interface{})
|
||||||
Panicf(format string, args ...interface{})
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
45
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
45
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,37 +12,35 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// BasicAuthConfig defines the config for BasicAuth middleware.
|
||||||
// BasicAuthConfig defines the config for BasicAuth middleware.
|
type BasicAuthConfig struct {
|
||||||
BasicAuthConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// Validator is a function to validate BasicAuth credentials.
|
// Validator is a function to validate BasicAuth credentials.
|
||||||
// Required.
|
// Required.
|
||||||
Validator BasicAuthValidator
|
Validator BasicAuthValidator
|
||||||
|
|
||||||
// Realm is a string to define realm attribute of BasicAuth.
|
// Realm is a string to define realm attribute of BasicAuth.
|
||||||
// Default value "Restricted".
|
// Default value "Restricted".
|
||||||
Realm string
|
Realm string
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicAuthValidator defines a function to validate BasicAuth credentials.
|
// BasicAuthValidator defines a function to validate BasicAuth credentials.
|
||||||
BasicAuthValidator func(string, string, echo.Context) (bool, error)
|
// The function should return a boolean indicating whether the credentials are valid,
|
||||||
)
|
// and an error if any error occurs during the validation process.
|
||||||
|
type BasicAuthValidator func(string, string, echo.Context) (bool, error)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
basic = "basic"
|
basic = "basic"
|
||||||
defaultRealm = "Restricted"
|
defaultRealm = "Restricted"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// DefaultBasicAuthConfig is the default BasicAuth middleware config.
|
||||||
// DefaultBasicAuthConfig is the default BasicAuth middleware config.
|
var DefaultBasicAuthConfig = BasicAuthConfig{
|
||||||
DefaultBasicAuthConfig = BasicAuthConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
Realm: defaultRealm,
|
||||||
Realm: defaultRealm,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// BasicAuth returns an BasicAuth middleware.
|
// BasicAuth returns an BasicAuth middleware.
|
||||||
//
|
//
|
||||||
|
55
vendor/github.com/labstack/echo/v4/middleware/body_dump.go
generated
vendored
55
vendor/github.com/labstack/echo/v4/middleware/body_dump.go
generated
vendored
@ -1,8 +1,12 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -10,32 +14,28 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// BodyDumpConfig defines the config for BodyDump middleware.
|
||||||
// BodyDumpConfig defines the config for BodyDump middleware.
|
type BodyDumpConfig struct {
|
||||||
BodyDumpConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// Handler receives request and response payload.
|
// Handler receives request and response payload.
|
||||||
// Required.
|
// Required.
|
||||||
Handler BodyDumpHandler
|
Handler BodyDumpHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// BodyDumpHandler receives the request and response payload.
|
// BodyDumpHandler receives the request and response payload.
|
||||||
BodyDumpHandler func(echo.Context, []byte, []byte)
|
type BodyDumpHandler func(echo.Context, []byte, []byte)
|
||||||
|
|
||||||
bodyDumpResponseWriter struct {
|
type bodyDumpResponseWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
// DefaultBodyDumpConfig is the default BodyDump middleware config.
|
||||||
// DefaultBodyDumpConfig is the default BodyDump middleware config.
|
var DefaultBodyDumpConfig = BodyDumpConfig{
|
||||||
DefaultBodyDumpConfig = BodyDumpConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// BodyDump returns a BodyDump middleware.
|
// BodyDump returns a BodyDump middleware.
|
||||||
//
|
//
|
||||||
@ -98,9 +98,16 @@ func (w *bodyDumpResponseWriter) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *bodyDumpResponseWriter) Flush() {
|
func (w *bodyDumpResponseWriter) Flush() {
|
||||||
w.ResponseWriter.(http.Flusher).Flush()
|
err := responseControllerFlush(w.ResponseWriter)
|
||||||
|
if err != nil && errors.Is(err, http.ErrNotSupported) {
|
||||||
|
panic(errors.New("response writer flushing is not supported"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *bodyDumpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
func (w *bodyDumpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
return w.ResponseWriter.(http.Hijacker).Hijack()
|
return responseControllerHijack(w.ResponseWriter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *bodyDumpResponseWriter) Unwrap() http.ResponseWriter {
|
||||||
|
return w.ResponseWriter
|
||||||
}
|
}
|
||||||
|
49
vendor/github.com/labstack/echo/v4/middleware/body_limit.go
generated
vendored
49
vendor/github.com/labstack/echo/v4/middleware/body_limit.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,32 +12,27 @@ import (
|
|||||||
"github.com/labstack/gommon/bytes"
|
"github.com/labstack/gommon/bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// BodyLimitConfig defines the config for BodyLimit middleware.
|
||||||
// BodyLimitConfig defines the config for BodyLimit middleware.
|
type BodyLimitConfig struct {
|
||||||
BodyLimitConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// Maximum allowed size for a request body, it can be specified
|
// Maximum allowed size for a request body, it can be specified
|
||||||
// as `4x` or `4xB`, where x is one of the multiple from K, M, G, T or P.
|
// as `4x` or `4xB`, where x is one of the multiple from K, M, G, T or P.
|
||||||
Limit string `yaml:"limit"`
|
Limit string `yaml:"limit"`
|
||||||
limit int64
|
limit int64
|
||||||
}
|
}
|
||||||
|
|
||||||
limitedReader struct {
|
type limitedReader struct {
|
||||||
BodyLimitConfig
|
BodyLimitConfig
|
||||||
reader io.ReadCloser
|
reader io.ReadCloser
|
||||||
read int64
|
read int64
|
||||||
context echo.Context
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
// DefaultBodyLimitConfig is the default BodyLimit middleware config.
|
||||||
// DefaultBodyLimitConfig is the default BodyLimit middleware config.
|
var DefaultBodyLimitConfig = BodyLimitConfig{
|
||||||
DefaultBodyLimitConfig = BodyLimitConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// BodyLimit returns a BodyLimit middleware.
|
// BodyLimit returns a BodyLimit middleware.
|
||||||
//
|
//
|
||||||
@ -80,7 +78,7 @@ func BodyLimitWithConfig(config BodyLimitConfig) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
// Based on content read
|
// Based on content read
|
||||||
r := pool.Get().(*limitedReader)
|
r := pool.Get().(*limitedReader)
|
||||||
r.Reset(req.Body, c)
|
r.Reset(req.Body)
|
||||||
defer pool.Put(r)
|
defer pool.Put(r)
|
||||||
req.Body = r
|
req.Body = r
|
||||||
|
|
||||||
@ -102,9 +100,8 @@ func (r *limitedReader) Close() error {
|
|||||||
return r.reader.Close()
|
return r.reader.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *limitedReader) Reset(reader io.ReadCloser, context echo.Context) {
|
func (r *limitedReader) Reset(reader io.ReadCloser) {
|
||||||
r.reader = reader
|
r.reader = reader
|
||||||
r.context = context
|
|
||||||
r.read = 0
|
r.read = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
89
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
89
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -13,54 +16,50 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// GzipConfig defines the config for Gzip middleware.
|
||||||
// GzipConfig defines the config for Gzip middleware.
|
type GzipConfig struct {
|
||||||
GzipConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// Gzip compression level.
|
// Gzip compression level.
|
||||||
// Optional. Default value -1.
|
// Optional. Default value -1.
|
||||||
Level int `yaml:"level"`
|
Level int `yaml:"level"`
|
||||||
|
|
||||||
// Length threshold before gzip compression is applied.
|
// Length threshold before gzip compression is applied.
|
||||||
// Optional. Default value 0.
|
// Optional. Default value 0.
|
||||||
//
|
//
|
||||||
// Most of the time you will not need to change the default. Compressing
|
// Most of the time you will not need to change the default. Compressing
|
||||||
// a short response might increase the transmitted data because of the
|
// a short response might increase the transmitted data because of the
|
||||||
// gzip format overhead. Compressing the response will also consume CPU
|
// gzip format overhead. Compressing the response will also consume CPU
|
||||||
// and time on the server and the client (for decompressing). Depending on
|
// and time on the server and the client (for decompressing). Depending on
|
||||||
// your use case such a threshold might be useful.
|
// your use case such a threshold might be useful.
|
||||||
//
|
//
|
||||||
// See also:
|
// See also:
|
||||||
// https://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits
|
// https://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits
|
||||||
MinLength int
|
MinLength int
|
||||||
}
|
}
|
||||||
|
|
||||||
gzipResponseWriter struct {
|
type gzipResponseWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
wroteHeader bool
|
wroteHeader bool
|
||||||
wroteBody bool
|
wroteBody bool
|
||||||
minLength int
|
minLength int
|
||||||
minLengthExceeded bool
|
minLengthExceeded bool
|
||||||
buffer *bytes.Buffer
|
buffer *bytes.Buffer
|
||||||
code int
|
code int
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
gzipScheme = "gzip"
|
gzipScheme = "gzip"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// DefaultGzipConfig is the default Gzip middleware config.
|
||||||
// DefaultGzipConfig is the default Gzip middleware config.
|
var DefaultGzipConfig = GzipConfig{
|
||||||
DefaultGzipConfig = GzipConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
Level: -1,
|
||||||
Level: -1,
|
MinLength: 0,
|
||||||
MinLength: 0,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
||||||
// scheme.
|
// scheme.
|
||||||
@ -191,13 +190,15 @@ func (w *gzipResponseWriter) Flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
w.Writer.(*gzip.Writer).Flush()
|
w.Writer.(*gzip.Writer).Flush()
|
||||||
if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
|
_ = responseControllerFlush(w.ResponseWriter)
|
||||||
flusher.Flush()
|
}
|
||||||
}
|
|
||||||
|
func (w *gzipResponseWriter) Unwrap() http.ResponseWriter {
|
||||||
|
return w.ResponseWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
return w.ResponseWriter.(http.Hijacker).Hijack()
|
return responseControllerHijack(w.ResponseWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
||||||
|
5
vendor/github.com/labstack/echo/v4/middleware/context_timeout.go
generated
vendored
5
vendor/github.com/labstack/echo/v4/middleware/context_timeout.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -13,7 +16,7 @@ type ContextTimeoutConfig struct {
|
|||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
// ErrorHandler is a function when error aries in middeware execution.
|
// ErrorHandler is a function when error aries in middleware execution.
|
||||||
ErrorHandler func(err error, c echo.Context) error
|
ErrorHandler func(err error, c echo.Context) error
|
||||||
|
|
||||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
||||||
|
202
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
202
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,112 +12,109 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// CORSConfig defines the config for CORS middleware.
|
||||||
// CORSConfig defines the config for CORS middleware.
|
type CORSConfig struct {
|
||||||
CORSConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// AllowOrigins determines the value of the Access-Control-Allow-Origin
|
// AllowOrigins determines the value of the Access-Control-Allow-Origin
|
||||||
// response header. This header defines a list of origins that may access the
|
// response header. This header defines a list of origins that may access the
|
||||||
// resource. The wildcard characters '*' and '?' are supported and are
|
// resource. The wildcard characters '*' and '?' are supported and are
|
||||||
// converted to regex fragments '.*' and '.' accordingly.
|
// converted to regex fragments '.*' and '.' accordingly.
|
||||||
//
|
//
|
||||||
// Security: use extreme caution when handling the origin, and carefully
|
// Security: use extreme caution when handling the origin, and carefully
|
||||||
// validate any logic. Remember that attackers may register hostile domain names.
|
// validate any logic. Remember that attackers may register hostile domain names.
|
||||||
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||||
//
|
//
|
||||||
// Optional. Default value []string{"*"}.
|
// Optional. Default value []string{"*"}.
|
||||||
//
|
//
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
||||||
AllowOrigins []string `yaml:"allow_origins"`
|
AllowOrigins []string `yaml:"allow_origins"`
|
||||||
|
|
||||||
// AllowOriginFunc is a custom function to validate the origin. It takes the
|
// AllowOriginFunc is a custom function to validate the origin. It takes the
|
||||||
// origin as an argument and returns true if allowed or false otherwise. If
|
// origin as an argument and returns true if allowed or false otherwise. If
|
||||||
// an error is returned, it is returned by the handler. If this option is
|
// an error is returned, it is returned by the handler. If this option is
|
||||||
// set, AllowOrigins is ignored.
|
// set, AllowOrigins is ignored.
|
||||||
//
|
//
|
||||||
// Security: use extreme caution when handling the origin, and carefully
|
// Security: use extreme caution when handling the origin, and carefully
|
||||||
// validate any logic. Remember that attackers may register hostile domain names.
|
// validate any logic. Remember that attackers may register hostile domain names.
|
||||||
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||||
//
|
//
|
||||||
// Optional.
|
// Optional.
|
||||||
AllowOriginFunc func(origin string) (bool, error) `yaml:"allow_origin_func"`
|
AllowOriginFunc func(origin string) (bool, error) `yaml:"-"`
|
||||||
|
|
||||||
// AllowMethods determines the value of the Access-Control-Allow-Methods
|
// AllowMethods determines the value of the Access-Control-Allow-Methods
|
||||||
// response header. This header specified the list of methods allowed when
|
// response header. This header specified the list of methods allowed when
|
||||||
// accessing the resource. This is used in response to a preflight request.
|
// accessing the resource. This is used in response to a preflight request.
|
||||||
//
|
//
|
||||||
// Optional. Default value DefaultCORSConfig.AllowMethods.
|
// Optional. Default value DefaultCORSConfig.AllowMethods.
|
||||||
// If `allowMethods` is left empty, this middleware will fill for preflight
|
// If `allowMethods` is left empty, this middleware will fill for preflight
|
||||||
// request `Access-Control-Allow-Methods` header value
|
// request `Access-Control-Allow-Methods` header value
|
||||||
// from `Allow` header that echo.Router set into context.
|
// from `Allow` header that echo.Router set into context.
|
||||||
//
|
//
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
|
||||||
AllowMethods []string `yaml:"allow_methods"`
|
AllowMethods []string `yaml:"allow_methods"`
|
||||||
|
|
||||||
// AllowHeaders determines the value of the Access-Control-Allow-Headers
|
// AllowHeaders determines the value of the Access-Control-Allow-Headers
|
||||||
// response header. This header is used in response to a preflight request to
|
// response header. This header is used in response to a preflight request to
|
||||||
// indicate which HTTP headers can be used when making the actual request.
|
// indicate which HTTP headers can be used when making the actual request.
|
||||||
//
|
//
|
||||||
// Optional. Default value []string{}.
|
// Optional. Default value []string{}.
|
||||||
//
|
//
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
|
||||||
AllowHeaders []string `yaml:"allow_headers"`
|
AllowHeaders []string `yaml:"allow_headers"`
|
||||||
|
|
||||||
// AllowCredentials determines the value of the
|
// AllowCredentials determines the value of the
|
||||||
// Access-Control-Allow-Credentials response header. This header indicates
|
// Access-Control-Allow-Credentials response header. This header indicates
|
||||||
// whether or not the response to the request can be exposed when the
|
// whether or not the response to the request can be exposed when the
|
||||||
// credentials mode (Request.credentials) is true. When used as part of a
|
// credentials mode (Request.credentials) is true. When used as part of a
|
||||||
// response to a preflight request, this indicates whether or not the actual
|
// response to a preflight request, this indicates whether or not the actual
|
||||||
// request can be made using credentials. See also
|
// request can be made using credentials. See also
|
||||||
// [MDN: Access-Control-Allow-Credentials].
|
// [MDN: Access-Control-Allow-Credentials].
|
||||||
//
|
//
|
||||||
// Optional. Default value false, in which case the header is not set.
|
// Optional. Default value false, in which case the header is not set.
|
||||||
//
|
//
|
||||||
// Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`.
|
// Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`.
|
||||||
// See "Exploiting CORS misconfigurations for Bitcoins and bounties",
|
// See "Exploiting CORS misconfigurations for Bitcoins and bounties",
|
||||||
// https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
// https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||||
//
|
//
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
|
||||||
AllowCredentials bool `yaml:"allow_credentials"`
|
AllowCredentials bool `yaml:"allow_credentials"`
|
||||||
|
|
||||||
// UnsafeWildcardOriginWithAllowCredentials UNSAFE/INSECURE: allows wildcard '*' origin to be used with AllowCredentials
|
// UnsafeWildcardOriginWithAllowCredentials UNSAFE/INSECURE: allows wildcard '*' origin to be used with AllowCredentials
|
||||||
// flag. In that case we consider any origin allowed and send it back to the client with `Access-Control-Allow-Origin` header.
|
// flag. In that case we consider any origin allowed and send it back to the client with `Access-Control-Allow-Origin` header.
|
||||||
//
|
//
|
||||||
// This is INSECURE and potentially leads to [cross-origin](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)
|
// This is INSECURE and potentially leads to [cross-origin](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)
|
||||||
// attacks. See: https://github.com/labstack/echo/issues/2400 for discussion on the subject.
|
// attacks. See: https://github.com/labstack/echo/issues/2400 for discussion on the subject.
|
||||||
//
|
//
|
||||||
// Optional. Default value is false.
|
// Optional. Default value is false.
|
||||||
UnsafeWildcardOriginWithAllowCredentials bool `yaml:"unsafe_wildcard_origin_with_allow_credentials"`
|
UnsafeWildcardOriginWithAllowCredentials bool `yaml:"unsafe_wildcard_origin_with_allow_credentials"`
|
||||||
|
|
||||||
// ExposeHeaders determines the value of Access-Control-Expose-Headers, which
|
// ExposeHeaders determines the value of Access-Control-Expose-Headers, which
|
||||||
// defines a list of headers that clients are allowed to access.
|
// defines a list of headers that clients are allowed to access.
|
||||||
//
|
//
|
||||||
// Optional. Default value []string{}, in which case the header is not set.
|
// Optional. Default value []string{}, in which case the header is not set.
|
||||||
//
|
//
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header
|
||||||
ExposeHeaders []string `yaml:"expose_headers"`
|
ExposeHeaders []string `yaml:"expose_headers"`
|
||||||
|
|
||||||
// MaxAge determines the value of the Access-Control-Max-Age response header.
|
// MaxAge determines the value of the Access-Control-Max-Age response header.
|
||||||
// This header indicates how long (in seconds) the results of a preflight
|
// This header indicates how long (in seconds) the results of a preflight
|
||||||
// request can be cached.
|
// request can be cached.
|
||||||
//
|
// The header is set only if MaxAge != 0, negative value sends "0" which instructs browsers not to cache that response.
|
||||||
// Optional. Default value 0. The header is set only if MaxAge > 0.
|
//
|
||||||
//
|
// Optional. Default value 0 - meaning header is not sent.
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
//
|
||||||
MaxAge int `yaml:"max_age"`
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
||||||
}
|
MaxAge int `yaml:"max_age"`
|
||||||
)
|
}
|
||||||
|
|
||||||
var (
|
// DefaultCORSConfig is the default CORS middleware config.
|
||||||
// DefaultCORSConfig is the default CORS middleware config.
|
var DefaultCORSConfig = CORSConfig{
|
||||||
DefaultCORSConfig = CORSConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
AllowOrigins: []string{"*"},
|
||||||
AllowOrigins: []string{"*"},
|
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
|
||||||
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
|
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
|
||||||
// See also [MDN: Cross-Origin Resource Sharing (CORS)].
|
// See also [MDN: Cross-Origin Resource Sharing (CORS)].
|
||||||
@ -159,7 +159,11 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
|||||||
allowMethods := strings.Join(config.AllowMethods, ",")
|
allowMethods := strings.Join(config.AllowMethods, ",")
|
||||||
allowHeaders := strings.Join(config.AllowHeaders, ",")
|
allowHeaders := strings.Join(config.AllowHeaders, ",")
|
||||||
exposeHeaders := strings.Join(config.ExposeHeaders, ",")
|
exposeHeaders := strings.Join(config.ExposeHeaders, ",")
|
||||||
maxAge := strconv.Itoa(config.MaxAge)
|
|
||||||
|
maxAge := "0"
|
||||||
|
if config.MaxAge > 0 {
|
||||||
|
maxAge = strconv.Itoa(config.MaxAge)
|
||||||
|
}
|
||||||
|
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
@ -282,7 +286,7 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
|||||||
res.Header().Set(echo.HeaderAccessControlAllowHeaders, h)
|
res.Header().Set(echo.HeaderAccessControlAllowHeaders, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.MaxAge > 0 {
|
if config.MaxAge != 0 {
|
||||||
res.Header().Set(echo.HeaderAccessControlMaxAge, maxAge)
|
res.Header().Set(echo.HeaderAccessControlMaxAge, maxAge)
|
||||||
}
|
}
|
||||||
return c.NoContent(http.StatusNoContent)
|
return c.NoContent(http.StatusNoContent)
|
||||||
|
123
vendor/github.com/labstack/echo/v4/middleware/csrf.go
generated
vendored
123
vendor/github.com/labstack/echo/v4/middleware/csrf.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -6,85 +9,80 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/gommon/random"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// CSRFConfig defines the config for CSRF middleware.
|
||||||
// CSRFConfig defines the config for CSRF middleware.
|
type CSRFConfig struct {
|
||||||
CSRFConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// TokenLength is the length of the generated token.
|
// TokenLength is the length of the generated token.
|
||||||
TokenLength uint8 `yaml:"token_length"`
|
TokenLength uint8 `yaml:"token_length"`
|
||||||
// Optional. Default value 32.
|
// Optional. Default value 32.
|
||||||
|
|
||||||
// TokenLookup is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
|
// TokenLookup is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
|
||||||
// to extract token from the request.
|
// to extract token from the request.
|
||||||
// Optional. Default value "header:X-CSRF-Token".
|
// Optional. Default value "header:X-CSRF-Token".
|
||||||
// Possible values:
|
// Possible values:
|
||||||
// - "header:<name>" or "header:<name>:<cut-prefix>"
|
// - "header:<name>" or "header:<name>:<cut-prefix>"
|
||||||
// - "query:<name>"
|
// - "query:<name>"
|
||||||
// - "form:<name>"
|
// - "form:<name>"
|
||||||
// Multiple sources example:
|
// Multiple sources example:
|
||||||
// - "header:X-CSRF-Token,query:csrf"
|
// - "header:X-CSRF-Token,query:csrf"
|
||||||
TokenLookup string `yaml:"token_lookup"`
|
TokenLookup string `yaml:"token_lookup"`
|
||||||
|
|
||||||
// Context key to store generated CSRF token into context.
|
// Context key to store generated CSRF token into context.
|
||||||
// Optional. Default value "csrf".
|
// Optional. Default value "csrf".
|
||||||
ContextKey string `yaml:"context_key"`
|
ContextKey string `yaml:"context_key"`
|
||||||
|
|
||||||
// Name of the CSRF cookie. This cookie will store CSRF token.
|
// Name of the CSRF cookie. This cookie will store CSRF token.
|
||||||
// Optional. Default value "csrf".
|
// Optional. Default value "csrf".
|
||||||
CookieName string `yaml:"cookie_name"`
|
CookieName string `yaml:"cookie_name"`
|
||||||
|
|
||||||
// Domain of the CSRF cookie.
|
// Domain of the CSRF cookie.
|
||||||
// Optional. Default value none.
|
// Optional. Default value none.
|
||||||
CookieDomain string `yaml:"cookie_domain"`
|
CookieDomain string `yaml:"cookie_domain"`
|
||||||
|
|
||||||
// Path of the CSRF cookie.
|
// Path of the CSRF cookie.
|
||||||
// Optional. Default value none.
|
// Optional. Default value none.
|
||||||
CookiePath string `yaml:"cookie_path"`
|
CookiePath string `yaml:"cookie_path"`
|
||||||
|
|
||||||
// Max age (in seconds) of the CSRF cookie.
|
// Max age (in seconds) of the CSRF cookie.
|
||||||
// Optional. Default value 86400 (24hr).
|
// Optional. Default value 86400 (24hr).
|
||||||
CookieMaxAge int `yaml:"cookie_max_age"`
|
CookieMaxAge int `yaml:"cookie_max_age"`
|
||||||
|
|
||||||
// Indicates if CSRF cookie is secure.
|
// Indicates if CSRF cookie is secure.
|
||||||
// Optional. Default value false.
|
// Optional. Default value false.
|
||||||
CookieSecure bool `yaml:"cookie_secure"`
|
CookieSecure bool `yaml:"cookie_secure"`
|
||||||
|
|
||||||
// Indicates if CSRF cookie is HTTP only.
|
// Indicates if CSRF cookie is HTTP only.
|
||||||
// Optional. Default value false.
|
// Optional. Default value false.
|
||||||
CookieHTTPOnly bool `yaml:"cookie_http_only"`
|
CookieHTTPOnly bool `yaml:"cookie_http_only"`
|
||||||
|
|
||||||
// Indicates SameSite mode of the CSRF cookie.
|
// Indicates SameSite mode of the CSRF cookie.
|
||||||
// Optional. Default value SameSiteDefaultMode.
|
// Optional. Default value SameSiteDefaultMode.
|
||||||
CookieSameSite http.SameSite `yaml:"cookie_same_site"`
|
CookieSameSite http.SameSite `yaml:"cookie_same_site"`
|
||||||
|
|
||||||
// ErrorHandler defines a function which is executed for returning custom errors.
|
// ErrorHandler defines a function which is executed for returning custom errors.
|
||||||
ErrorHandler CSRFErrorHandler
|
ErrorHandler CSRFErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSRFErrorHandler is a function which is executed for creating custom errors.
|
// CSRFErrorHandler is a function which is executed for creating custom errors.
|
||||||
CSRFErrorHandler func(err error, c echo.Context) error
|
type CSRFErrorHandler func(err error, c echo.Context) error
|
||||||
)
|
|
||||||
|
|
||||||
// ErrCSRFInvalid is returned when CSRF check fails
|
// ErrCSRFInvalid is returned when CSRF check fails
|
||||||
var ErrCSRFInvalid = echo.NewHTTPError(http.StatusForbidden, "invalid csrf token")
|
var ErrCSRFInvalid = echo.NewHTTPError(http.StatusForbidden, "invalid csrf token")
|
||||||
|
|
||||||
var (
|
// DefaultCSRFConfig is the default CSRF middleware config.
|
||||||
// DefaultCSRFConfig is the default CSRF middleware config.
|
var DefaultCSRFConfig = CSRFConfig{
|
||||||
DefaultCSRFConfig = CSRFConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
TokenLength: 32,
|
||||||
TokenLength: 32,
|
TokenLookup: "header:" + echo.HeaderXCSRFToken,
|
||||||
TokenLookup: "header:" + echo.HeaderXCSRFToken,
|
ContextKey: "csrf",
|
||||||
ContextKey: "csrf",
|
CookieName: "_csrf",
|
||||||
CookieName: "_csrf",
|
CookieMaxAge: 86400,
|
||||||
CookieMaxAge: 86400,
|
CookieSameSite: http.SameSiteDefaultMode,
|
||||||
CookieSameSite: http.SameSiteDefaultMode,
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// CSRF returns a Cross-Site Request Forgery (CSRF) middleware.
|
// CSRF returns a Cross-Site Request Forgery (CSRF) middleware.
|
||||||
// See: https://en.wikipedia.org/wiki/Cross-site_request_forgery
|
// See: https://en.wikipedia.org/wiki/Cross-site_request_forgery
|
||||||
@ -103,6 +101,7 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
|
|||||||
if config.TokenLength == 0 {
|
if config.TokenLength == 0 {
|
||||||
config.TokenLength = DefaultCSRFConfig.TokenLength
|
config.TokenLength = DefaultCSRFConfig.TokenLength
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.TokenLookup == "" {
|
if config.TokenLookup == "" {
|
||||||
config.TokenLookup = DefaultCSRFConfig.TokenLookup
|
config.TokenLookup = DefaultCSRFConfig.TokenLookup
|
||||||
}
|
}
|
||||||
@ -132,7 +131,7 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
token := ""
|
token := ""
|
||||||
if k, err := c.Cookie(config.CookieName); err != nil {
|
if k, err := c.Cookie(config.CookieName); err != nil {
|
||||||
token = random.String(config.TokenLength) // Generate token
|
token = randomString(config.TokenLength)
|
||||||
} else {
|
} else {
|
||||||
token = k.Value // Reuse token
|
token = k.Value // Reuse token
|
||||||
}
|
}
|
||||||
|
31
vendor/github.com/labstack/echo/v4/middleware/decompress.go
generated
vendored
31
vendor/github.com/labstack/echo/v4/middleware/decompress.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,16 +12,14 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
// DecompressConfig defines the config for Decompress middleware.
|
||||||
// DecompressConfig defines the config for Decompress middleware.
|
type DecompressConfig struct {
|
||||||
DecompressConfig struct {
|
// Skipper defines a function to skip middleware.
|
||||||
// Skipper defines a function to skip middleware.
|
Skipper Skipper
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// GzipDecompressPool defines an interface to provide the sync.Pool used to create/store Gzip readers
|
// GzipDecompressPool defines an interface to provide the sync.Pool used to create/store Gzip readers
|
||||||
GzipDecompressPool Decompressor
|
GzipDecompressPool Decompressor
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// GZIPEncoding content-encoding header if set to "gzip", decompress body contents.
|
// GZIPEncoding content-encoding header if set to "gzip", decompress body contents.
|
||||||
const GZIPEncoding string = "gzip"
|
const GZIPEncoding string = "gzip"
|
||||||
@ -28,13 +29,11 @@ type Decompressor interface {
|
|||||||
gzipDecompressPool() sync.Pool
|
gzipDecompressPool() sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
// DefaultDecompressConfig defines the config for decompress middleware
|
||||||
//DefaultDecompressConfig defines the config for decompress middleware
|
var DefaultDecompressConfig = DecompressConfig{
|
||||||
DefaultDecompressConfig = DecompressConfig{
|
Skipper: DefaultSkipper,
|
||||||
Skipper: DefaultSkipper,
|
GzipDecompressPool: &DefaultGzipDecompressPool{},
|
||||||
GzipDecompressPool: &DefaultGzipDecompressPool{},
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// DefaultGzipDecompressPool is the default implementation of Decompressor interface
|
// DefaultGzipDecompressPool is the default implementation of Decompressor interface
|
||||||
type DefaultGzipDecompressPool struct {
|
type DefaultGzipDecompressPool struct {
|
||||||
|
3
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
3
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user