Compare commits
No commits in common. "master" and "0.3.0" have entirely different histories.
43
go.mod
43
go.mod
@ -1,42 +1,41 @@
|
|||||||
module git.paulbsd.com/paulbsd/pki
|
module git.paulbsd.com/paulbsd/pki
|
||||||
|
|
||||||
go 1.23
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-acme/lego/v4 v4.17.4
|
github.com/go-acme/lego/v4 v4.9.1
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/labstack/echo/v4 v4.12.0
|
github.com/google/go-cmp v0.5.5 // indirect
|
||||||
github.com/lib/pq v1.10.9
|
github.com/labstack/echo/v4 v4.9.1
|
||||||
github.com/miekg/dns v1.1.62 // indirect
|
github.com/lib/pq v1.10.7
|
||||||
|
github.com/miekg/dns v1.1.50 // 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.26.0 // indirect
|
golang.org/x/crypto v0.4.0 // indirect
|
||||||
golang.org/x/net v0.28.0 // indirect
|
golang.org/x/net v0.4.0 // indirect
|
||||||
golang.org/x/sys v0.24.0 // indirect
|
golang.org/x/sys v0.3.0 // indirect
|
||||||
golang.org/x/text v0.17.0 // indirect
|
golang.org/x/text v0.5.0 // indirect
|
||||||
golang.org/x/time v0.6.0 // indirect
|
golang.org/x/time v0.3.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.12 // indirect
|
||||||
xorm.io/xorm v1.3.9
|
xorm.io/xorm v1.3.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
|
github.com/goccy/go-json v0.10.0 // 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.2 // indirect
|
github.com/labstack/gommon v0.4.0 // 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.20 // indirect
|
github.com/mattn/go-isatty v0.0.16 // 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.6.0 // indirect
|
github.com/ovh/go-ovh v1.3.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.20.0 // indirect
|
golang.org/x/mod v0.7.0 // indirect
|
||||||
golang.org/x/oauth2 v0.22.0 // indirect
|
golang.org/x/tools v0.4.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||||
golang.org/x/tools v0.24.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
718
go.sum
718
go.sum
@ -1,34 +1,103 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||||
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
|
github.com/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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||||
|
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||||
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.9.1 h1:n9Z5MQwANeGSQKlVE3bEh9SDvAySK9oVYOKCGCESqQE=
|
||||||
github.com/go-acme/lego/v4 v4.16.1/go.mod h1:AVvwdPned/IWpD/ihHhMsKnveF7HHYAz/CmtXi7OZoE=
|
github.com/go-acme/lego/v4 v4.9.1/go.mod h1:g3JRUyWS3L/VObpp4bCxzJftKyf/Wba8QrSSnoiqjg4=
|
||||||
github.com/go-acme/lego/v4 v4.17.4 h1:h0nePd3ObP6o7kAkndtpTzCw8shOZuWckNYeUQwo36Q=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-acme/lego/v4 v4.17.4/go.mod h1:dU94SvPNqimEeb7EVilGGSnS0nU1O5Exir0pQ4QFL4U=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible 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/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=
|
||||||
@ -37,50 +106,188 @@ 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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.3.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/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
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/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||||
|
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
|
||||||
|
github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
|
||||||
|
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
|
||||||
|
github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE=
|
||||||
|
github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||||
|
github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
|
||||||
|
github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
|
||||||
|
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
|
||||||
|
github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc=
|
||||||
|
github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60=
|
||||||
|
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/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.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
|
||||||
|
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
|
||||||
|
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/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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
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.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||||
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||||
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
|
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||||
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
|
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||||
|
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||||
|
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||||
|
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
|
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
|
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||||
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
@ -91,138 +298,427 @@ 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/ovh/go-ovh v1.5.1 h1:P8O+7H+NQuFK9P/j4sFW5C0fvSS2DnHYGPwdVCp45wI=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
github.com/ovh/go-ovh v1.5.1/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||||
github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI=
|
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||||
|
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/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/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||||
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
|
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
|
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
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.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.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
|
||||||
|
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||||
|
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.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
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.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
||||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
|
||||||
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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
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-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/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-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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.19.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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
|
||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
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.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
|
||||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
|
||||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
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/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.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=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
modernc.org/cc/v3 v3.35.18 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U=
|
||||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||||
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
||||||
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
||||||
xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
|
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
||||||
xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
|
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/ccorpus v1.11.1/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/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/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/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||||
|
modernc.org/opt v0.1.1/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/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||||
|
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||||
|
modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
|
||||||
|
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||||
|
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
|
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
|
||||||
|
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/xorm v1.3.2 h1:uTRRKF2jYzbZ5nsofXVUx6ncMaek+SHjWYtCXyZo1oM=
|
||||||
|
xorm.io/xorm v1.3.2/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
||||||
|
@ -2,13 +2,10 @@ 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"`
|
||||||
Domain string `xorm:"notnull"`
|
Domains 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,13 +60,10 @@ 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 key, value := range options {
|
for k, v := range options {
|
||||||
if value == "" {
|
if v == "" {
|
||||||
utils.Advice(fmt.Sprintf("Provider parameter %s not set", key))
|
utils.Advice(fmt.Sprintf("OVH provider parameter %s not set", k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +72,6 @@ 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,7 +7,6 @@ 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"
|
||||||
@ -18,7 +17,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{}, domain.Domain{}}
|
pki.User{}}
|
||||||
|
|
||||||
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",
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
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,13 +9,12 @@ 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"
|
||||||
)
|
)
|
||||||
@ -30,8 +29,9 @@ 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, domain *string) (Entry cert.Entry, err error) {
|
func (u *User) GetEntry(cfg *config.Config, domains []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,38 +66,12 @@ 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, domainnames *[]string) (certs *certificate.Resource, err error) {
|
func (u *User) RequestNewCert(cfg *config.Config, domains []string) (certificates *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
|
||||||
|
|
||||||
var dom domain.Domain
|
ovhprovider, err := initProvider(cfg)
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -107,7 +81,7 @@ func (u *User) RequestNewCert(cfg *config.Config, domainnames *[]string) (certs
|
|||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.Challenge.SetDNS01Provider(provider)
|
err = client.Challenge.SetDNS01Provider(ovhprovider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
@ -121,15 +95,14 @@ func (u *User) RequestNewCert(cfg *config.Config, domainnames *[]string) (certs
|
|||||||
}
|
}
|
||||||
|
|
||||||
request := certificate.ObtainRequest{
|
request := certificate.ObtainRequest{
|
||||||
Domains: *domainnames,
|
Domains: domains,
|
||||||
Bundle: true,
|
Bundle: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
certs, err = client.Certificate.Obtain(request)
|
certificates, err = client.Certificate.Obtain(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
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"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// initOVHProvider initialize DNS provider configuration
|
// initProvider initialize DNS provider configuration
|
||||||
func initOVHProvider(cfg *config.Config) (ovhprovider *ovh.DNSProvider, err error) {
|
func initProvider(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"]
|
||||||
@ -19,24 +15,6 @@ func initOVHProvider(cfg *config.Config) (ovhprovider *ovh.DNSProvider, err erro
|
|||||||
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,6 +4,7 @@ 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"
|
||||||
@ -29,18 +30,13 @@ 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.POST("/cert", func(c echo.Context) (err error) {
|
e.GET("/domain/:domains", func(c echo.Context) (err error) {
|
||||||
var request = new(EntryRequest)
|
var result EntryResponse
|
||||||
var result = make(map[string]EntryResponse)
|
var domains = strings.Split(c.Param("domains"), ",")
|
||||||
err = c.Bind(&request)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return c.JSON(http.StatusInternalServerError, "error parsing request")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Providing %s to user %s at %s\n", request.Domains, c.Get("username"), c.RealIP())
|
log.Println(fmt.Sprintf("Providing %s to user %s at %s", domains, c.Get("username"), c.RealIP()))
|
||||||
|
|
||||||
result, err = GetCertificate(cfg, c.Get("user").(*pki.User), &request.Domains)
|
result, err = GetCertificate(cfg, c.Get("user").(*pki.User), 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,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/pki/src/cert"
|
"git.paulbsd.com/paulbsd/pki/src/cert"
|
||||||
@ -13,24 +14,18 @@ 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 map[string]EntryResponse, err error) {
|
func GetCertificate(cfg *config.Config, user *pki.User, domains []string) (result 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)
|
|
||||||
|
|
||||||
firstdomain := (*domains)[0]
|
entry, err := user.GetEntry(cfg, domains)
|
||||||
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.Printf("Error fetching new certificate %s\n", err)
|
log.Println(fmt.Sprintf("Error fetching new certificate %s", err))
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
NotBefore, NotAfter, err := GetDates(certs.Certificate)
|
NotBefore, NotAfter, err := GetDates(certs.Certificate)
|
||||||
@ -38,36 +33,33 @@ func GetCertificate(cfg *config.Config, user *pki.User, domains *[]string) (resu
|
|||||||
log.Println("Error where parsing dates")
|
log.Println("Error where parsing dates")
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
entry := cert.Entry{Domain: certs.Domain,
|
entry := cert.Entry{Domains: strings.Join(domains, ","),
|
||||||
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[firstdomain] = convertEntryToResponse(entry)
|
result = convertEntryToResponse(entry)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
result[firstdomain] = convertEntryToResponse(entry)
|
result = 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) {
|
||||||
for _, domain := range *domains {
|
domainRegex, err := regexp.Compile(`^[a-z0-9\*]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}$`)
|
||||||
err = CheckDomain(&domain)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckDomain check if requested domain are valid
|
for _, d := range domains {
|
||||||
func CheckDomain(domain *string) (err error) {
|
res := domainRegex.Match([]byte(d))
|
||||||
res := domainRegex.Match([]byte(*domain))
|
|
||||||
if !res {
|
if !res {
|
||||||
return fmt.Errorf("Domain %s has not a valid syntax %s, please verify", *domain, err)
|
return fmt.Errorf(fmt.Sprintf("Domain %s has not a valid syntax %s, please verify", d, err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -88,7 +80,9 @@ 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) {
|
||||||
out.Domains = append(out.Domains, in.Domain)
|
timeformatstring := "2006-01-02 15:04:05"
|
||||||
|
|
||||||
|
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)
|
||||||
@ -97,14 +91,9 @@ 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"`
|
||||||
|
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] [![Coverage Status][coveralls image]][coveralls]
|
# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![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,6 +21,8 @@ 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,9 +71,6 @@ 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
|
||||||
@ -84,7 +81,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
|
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
|
||||||
func NewExponentialBackOff(opts ...ExponentialBackOffOpts) *ExponentialBackOff {
|
func NewExponentialBackOff() *ExponentialBackOff {
|
||||||
b := &ExponentialBackOff{
|
b := &ExponentialBackOff{
|
||||||
InitialInterval: DefaultInitialInterval,
|
InitialInterval: DefaultInitialInterval,
|
||||||
RandomizationFactor: DefaultRandomizationFactor,
|
RandomizationFactor: DefaultRandomizationFactor,
|
||||||
@ -94,62 +91,10 @@ func NewExponentialBackOff(opts ...ExponentialBackOffOpts) *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 location != "" {
|
if len(location) > 0 {
|
||||||
a.core.jws.SetKid(location)
|
a.core.jws.SetKid(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/acme/api/api.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/acme/api/api.go
generated
vendored
@ -117,7 +117,7 @@ func (a *Core) signedPost(uri string, content []byte, response interface{}) (*ht
|
|||||||
return nil, fmt.Errorf("failed to post JWS message: failed to sign content: %w", err)
|
return nil, fmt.Errorf("failed to post JWS message: failed to sign content: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
signedBody := bytes.NewBufferString(signedContent.FullSerialize())
|
signedBody := bytes.NewBuffer([]byte(signedContent.FullSerialize()))
|
||||||
|
|
||||||
resp, err := a.doer.Post(uri, signedBody, "application/jose+json", response)
|
resp, err := a.doer.Post(uri, signedBody, "application/jose+json", response)
|
||||||
|
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/acme/api/internal/nonces/nonce_manager.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/acme/api/internal/nonces/nonce_manager.go
generated
vendored
@ -63,7 +63,7 @@ func (n *Manager) getNonce() (string, error) {
|
|||||||
return GetFromResponse(resp)
|
return GetFromResponse(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFromResponse Extracts a nonce from an HTTP response.
|
// GetFromResponse Extracts a nonce from a HTTP response.
|
||||||
func GetFromResponse(resp *http.Response) (string, error) {
|
func GetFromResponse(resp *http.Response) (string, error) {
|
||||||
if resp == nil {
|
if resp == nil {
|
||||||
return "", errors.New("nil response")
|
return "", errors.New("nil response")
|
||||||
|
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/v4"
|
jose "gopkg.in/square/go-jose.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// JWS Represents a JWS.
|
// JWS Represents a JWS.
|
||||||
|
4
vendor/github.com/go-acme/lego/v4/acme/api/internal/sender/sender.go
generated
vendored
4
vendor/github.com/go-acme/lego/v4/acme/api/internal/sender/sender.go
generated
vendored
@ -133,10 +133,6 @@ func checkError(req *http.Request, resp *http.Response) error {
|
|||||||
errorDetails.Method = req.Method
|
errorDetails.Method = req.Method
|
||||||
errorDetails.URL = req.URL.String()
|
errorDetails.URL = req.URL.String()
|
||||||
|
|
||||||
if errorDetails.HTTPStatus == 0 {
|
|
||||||
errorDetails.HTTPStatus = resp.StatusCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for errors we handle specifically
|
// Check for errors we handle specifically
|
||||||
if errorDetails.HTTPStatus == http.StatusBadRequest && errorDetails.Type == acme.BadNonceErr {
|
if errorDetails.HTTPStatus == http.StatusBadRequest && errorDetails.Type == acme.BadNonceErr {
|
||||||
return &acme.NonceError{ProblemDetails: errorDetails}
|
return &acme.NonceError{ProblemDetails: errorDetails}
|
||||||
|
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.17.4"
|
ourUserAgent = "xenolf-acme/4.9.1"
|
||||||
|
|
||||||
// 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
|
||||||
|
39
vendor/github.com/go-acme/lego/v4/acme/api/order.go
generated
vendored
39
vendor/github.com/go-acme/lego/v4/acme/api/order.go
generated
vendored
@ -3,58 +3,21 @@ package api
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme"
|
"github.com/go-acme/lego/v4/acme"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OrderOptions used to create an order (optional).
|
|
||||||
type OrderOptions struct {
|
|
||||||
NotBefore 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
|
||||||
|
|
||||||
// New Creates a new order.
|
// New Creates a new order.
|
||||||
func (o *OrderService) New(domains []string) (acme.ExtendedOrder, error) {
|
func (o *OrderService) New(domains []string) (acme.ExtendedOrder, error) {
|
||||||
return o.NewWithOptions(domains, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithOptions Creates a new order.
|
|
||||||
func (o *OrderService) NewWithOptions(domains []string, opts *OrderOptions) (acme.ExtendedOrder, error) {
|
|
||||||
var identifiers []acme.Identifier
|
var identifiers []acme.Identifier
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
ident := acme.Identifier{Value: domain, Type: "dns"}
|
identifiers = append(identifiers, acme.Identifier{Type: "dns", Value: domain})
|
||||||
|
|
||||||
if net.ParseIP(domain) != nil {
|
|
||||||
ident.Type = "ip"
|
|
||||||
}
|
|
||||||
|
|
||||||
identifiers = append(identifiers, ident)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
orderReq := acme.Order{Identifiers: identifiers}
|
orderReq := acme.Order{Identifiers: identifiers}
|
||||||
|
|
||||||
if opts != nil {
|
|
||||||
if !opts.NotAfter.IsZero() {
|
|
||||||
orderReq.NotAfter = opts.NotAfter.Format(time.RFC3339)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !opts.NotBefore.IsZero() {
|
|
||||||
orderReq.NotBefore = opts.NotBefore.Format(time.RFC3339)
|
|
||||||
}
|
|
||||||
|
|
||||||
if o.core.GetDirectory().RenewalInfo != "" {
|
|
||||||
orderReq.Replaces = opts.ReplacesCertID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var order acme.Order
|
var order acme.Order
|
||||||
resp, err := o.core.post(o.core.GetDirectory().NewOrderURL, orderReq, &order)
|
resp, err := o.core.post(o.core.GetDirectory().NewOrderURL, orderReq, &order)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
28
vendor/github.com/go-acme/lego/v4/acme/api/renewal.go
generated
vendored
28
vendor/github.com/go-acme/lego/v4/acme/api/renewal.go
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrNoARI is returned when the server does not advertise a renewal info endpoint.
|
|
||||||
var ErrNoARI = errors.New("renewalInfo[get/post]: server does not advertise a renewal info endpoint")
|
|
||||||
|
|
||||||
// GetRenewalInfo GETs renewal information for a certificate from the renewalInfo endpoint.
|
|
||||||
// This is used to determine if a certificate needs to be renewed.
|
|
||||||
//
|
|
||||||
// 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) GetRenewalInfo(certID string) (*http.Response, error) {
|
|
||||||
if c.core.GetDirectory().RenewalInfo == "" {
|
|
||||||
return nil, ErrNoARI
|
|
||||||
}
|
|
||||||
|
|
||||||
if certID == "" {
|
|
||||||
return nil, errors.New("renewalInfo[get]: 'certID' cannot be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.core.HTTPClient.Get(c.core.GetDirectory().RenewalInfo + "/" + certID)
|
|
||||||
}
|
|
43
vendor/github.com/go-acme/lego/v4/acme/commons.go
generated
vendored
43
vendor/github.com/go-acme/lego/v4/acme/commons.go
generated
vendored
@ -38,7 +38,6 @@ const (
|
|||||||
|
|
||||||
// Directory the ACME directory object.
|
// Directory the ACME directory object.
|
||||||
// - https://www.rfc-editor.org/rfc/rfc8555.html#section-7.1.1
|
// - https://www.rfc-editor.org/rfc/rfc8555.html#section-7.1.1
|
||||||
// - https://datatracker.ietf.org/doc/draft-ietf-acme-ari/
|
|
||||||
type Directory struct {
|
type Directory struct {
|
||||||
NewNonceURL string `json:"newNonce"`
|
NewNonceURL string `json:"newNonce"`
|
||||||
NewAccountURL string `json:"newAccount"`
|
NewAccountURL string `json:"newAccount"`
|
||||||
@ -47,7 +46,6 @@ type Directory struct {
|
|||||||
RevokeCertURL string `json:"revokeCert"`
|
RevokeCertURL string `json:"revokeCert"`
|
||||||
KeyChangeURL string `json:"keyChange"`
|
KeyChangeURL string `json:"keyChange"`
|
||||||
Meta Meta `json:"meta"`
|
Meta Meta `json:"meta"`
|
||||||
RenewalInfo string `json:"renewalInfo"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meta the ACME meta object (related to Directory).
|
// Meta the ACME meta object (related to Directory).
|
||||||
@ -76,7 +74,7 @@ type Meta struct {
|
|||||||
ExternalAccountRequired bool `json:"externalAccountRequired"`
|
ExternalAccountRequired bool `json:"externalAccountRequired"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtendedAccount an extended Account.
|
// ExtendedAccount a extended Account.
|
||||||
type ExtendedAccount struct {
|
type ExtendedAccount struct {
|
||||||
Account
|
Account
|
||||||
// Contains the value of the response header `Location`
|
// Contains the value of the response header `Location`
|
||||||
@ -181,12 +179,6 @@ 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.
|
||||||
@ -314,36 +306,3 @@ type RawCertificate struct {
|
|||||||
Cert []byte
|
Cert []byte
|
||||||
Issuer []byte
|
Issuer []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window is a window of time.
|
|
||||||
type Window struct {
|
|
||||||
Start time.Time `json:"start"`
|
|
||||||
End time.Time `json:"end"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenewalInfoResponse is the response to GET requests made the renewalInfo endpoint.
|
|
||||||
// - (4.1. Getting Renewal Information) https://datatracker.ietf.org/doc/draft-ietf-acme-ari/
|
|
||||||
type RenewalInfoResponse struct {
|
|
||||||
// SuggestedWindow contains two fields, start and end,
|
|
||||||
// whose values are timestamps which bound the window of time in which the CA recommends renewing the certificate.
|
|
||||||
SuggestedWindow Window `json:"suggestedWindow"`
|
|
||||||
// ExplanationURL is an optional URL pointing to a page which may explain why the suggested renewal window is what it is.
|
|
||||||
// For example, it may be a page explaining the CA's dynamic load-balancing strategy,
|
|
||||||
// or a page documenting which certificates are affected by a mass revocation event.
|
|
||||||
// Callers SHOULD provide this URL to their operator, if present.
|
|
||||||
ExplanationURL string `json:"explanationURL"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenewalInfoUpdateRequest is the JWS payload for POST requests made to the renewalInfo endpoint.
|
|
||||||
// - (4.2. RenewalInfo Objects) https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-4.2
|
|
||||||
type RenewalInfoUpdateRequest struct {
|
|
||||||
// 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"`
|
|
||||||
// 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,
|
|
||||||
// for instance because it has been renewed and the new certificate is in use, or because it is no longer in use.
|
|
||||||
// Clients SHOULD NOT send a request where this value is false.
|
|
||||||
Replaced bool `json:"replaced"`
|
|
||||||
}
|
|
||||||
|
73
vendor/github.com/go-acme/lego/v4/certcrypto/crypto.go
generated
vendored
73
vendor/github.com/go-acme/lego/v4/certcrypto/crypto.go
generated
vendored
@ -14,8 +14,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -27,7 +25,6 @@ const (
|
|||||||
EC256 = KeyType("P256")
|
EC256 = KeyType("P256")
|
||||||
EC384 = KeyType("P384")
|
EC384 = KeyType("P384")
|
||||||
RSA2048 = KeyType("2048")
|
RSA2048 = KeyType("2048")
|
||||||
RSA3072 = KeyType("3072")
|
|
||||||
RSA4096 = KeyType("4096")
|
RSA4096 = KeyType("4096")
|
||||||
RSA8192 = KeyType("8192")
|
RSA8192 = KeyType("8192")
|
||||||
)
|
)
|
||||||
@ -85,11 +82,11 @@ func ParsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
|
|||||||
// ParsePEMPrivateKey parses a private key from key, which is a PEM block.
|
// ParsePEMPrivateKey parses a private key from key, which is a PEM block.
|
||||||
// Borrowed from Go standard library, to handle various private key and PEM block types.
|
// Borrowed from Go standard library, to handle various private key and PEM block types.
|
||||||
// https://github.com/golang/go/blob/693748e9fa385f1e2c3b91ca9acbb6c0ad2d133d/src/crypto/tls/tls.go#L291-L308
|
// https://github.com/golang/go/blob/693748e9fa385f1e2c3b91ca9acbb6c0ad2d133d/src/crypto/tls/tls.go#L291-L308
|
||||||
// https://github.com/golang/go/blob/693748e9fa385f1e2c3b91ca9acbb6c0ad2d133d/src/crypto/tls/tls.go#L238
|
// https://github.com/golang/go/blob/693748e9fa385f1e2c3b91ca9acbb6c0ad2d133d/src/crypto/tls/tls.go#L238)
|
||||||
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, errors.New("invalid PEM block")
|
return nil, fmt.Errorf("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") {
|
||||||
@ -124,8 +121,6 @@ func GeneratePrivateKey(keyType KeyType) (crypto.PrivateKey, error) {
|
|||||||
return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||||
case RSA2048:
|
case RSA2048:
|
||||||
return rsa.GenerateKey(rand.Reader, 2048)
|
return rsa.GenerateKey(rand.Reader, 2048)
|
||||||
case RSA3072:
|
|
||||||
return rsa.GenerateKey(rand.Reader, 3072)
|
|
||||||
case RSA4096:
|
case RSA4096:
|
||||||
return rsa.GenerateKey(rand.Reader, 4096)
|
return rsa.GenerateKey(rand.Reader, 4096)
|
||||||
case RSA8192:
|
case RSA8192:
|
||||||
@ -136,20 +131,9 @@ func GeneratePrivateKey(keyType KeyType) (crypto.PrivateKey, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GenerateCSR(privateKey crypto.PrivateKey, domain string, san []string, mustStaple bool) ([]byte, error) {
|
func GenerateCSR(privateKey crypto.PrivateKey, domain string, san []string, mustStaple bool) ([]byte, error) {
|
||||||
var dnsNames []string
|
|
||||||
var ipAddresses []net.IP
|
|
||||||
for _, altname := range san {
|
|
||||||
if ip := net.ParseIP(altname); ip != nil {
|
|
||||||
ipAddresses = append(ipAddresses, ip)
|
|
||||||
} else {
|
|
||||||
dnsNames = append(dnsNames, altname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template := x509.CertificateRequest{
|
template := x509.CertificateRequest{
|
||||||
Subject: pkix.Name{CommonName: domain},
|
Subject: pkix.Name{CommonName: domain},
|
||||||
DNSNames: dnsNames,
|
DNSNames: san,
|
||||||
IPAddresses: ipAddresses,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if mustStaple {
|
if mustStaple {
|
||||||
@ -217,26 +201,6 @@ 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 != "" {
|
||||||
@ -251,13 +215,6 @@ func ExtractDomains(cert *x509.Certificate) []string {
|
|||||||
domains = append(domains, sanDomain)
|
domains = append(domains, sanDomain)
|
||||||
}
|
}
|
||||||
|
|
||||||
commonNameIP := net.ParseIP(cert.Subject.CommonName)
|
|
||||||
for _, sanIP := range cert.IPAddresses {
|
|
||||||
if !commonNameIP.Equal(sanIP) {
|
|
||||||
domains = append(domains, sanIP.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return domains
|
return domains
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +226,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 slices.Contains(domains, sanName) {
|
if containsSAN(domains, sanName) {
|
||||||
// Duplicate; skip this name
|
// Duplicate; skip this name
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -278,14 +235,16 @@ func ExtractDomainsCSR(csr *x509.CertificateRequest) []string {
|
|||||||
domains = append(domains, sanName)
|
domains = append(domains, sanName)
|
||||||
}
|
}
|
||||||
|
|
||||||
cnip := net.ParseIP(csr.Subject.CommonName)
|
return domains
|
||||||
for _, sanIP := range csr.IPAddresses {
|
|
||||||
if !cnip.Equal(sanIP) {
|
|
||||||
domains = append(domains, sanIP.String())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -318,15 +277,9 @@ func generateDerCert(privateKey *rsa.PrivateKey, expiration time.Time, domain st
|
|||||||
|
|
||||||
KeyUsage: x509.KeyUsageKeyEncipherment,
|
KeyUsage: x509.KeyUsageKeyEncipherment,
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
|
DNSNames: []string{domain},
|
||||||
ExtraExtensions: extensions,
|
ExtraExtensions: extensions,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handling SAN filling as type suspected
|
|
||||||
if ip := net.ParseIP(domain); ip != nil {
|
|
||||||
template.IPAddresses = []net.IP{ip}
|
|
||||||
} else {
|
|
||||||
template.DNSNames = []string{domain}
|
|
||||||
}
|
|
||||||
|
|
||||||
return x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
|
return x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/go-acme/lego/v4/certificate/authorization.go
generated
vendored
15
vendor/github.com/go-acme/lego/v4/certificate/authorization.go
generated
vendored
@ -12,7 +12,6 @@ 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
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,14 +35,13 @@ func (c *Certifier) getAuthorizations(order acme.ExtendedOrder) ([]acme.Authoriz
|
|||||||
}
|
}
|
||||||
|
|
||||||
var responses []acme.Authorization
|
var responses []acme.Authorization
|
||||||
|
failures := make(obtainError)
|
||||||
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)
|
||||||
case err := <-errc:
|
case err := <-errc:
|
||||||
failures.Add(err.Domain, err.Error)
|
failures[err.Domain] = err.Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +52,12 @@ func (c *Certifier) getAuthorizations(order acme.ExtendedOrder) ([]acme.Authoriz
|
|||||||
close(resc)
|
close(resc)
|
||||||
close(errc)
|
close(errc)
|
||||||
|
|
||||||
return responses, failures.Join()
|
// be careful to not return an empty failures map;
|
||||||
|
// even if empty, they become non-nil error values
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return responses, failures
|
||||||
|
}
|
||||||
|
return responses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder, force bool) {
|
func (c *Certifier) deactivateAuthorizations(order acme.ExtendedOrder, force bool) {
|
||||||
|
141
vendor/github.com/go-acme/lego/v4/certificate/certificates.go
generated
vendored
141
vendor/github.com/go-acme/lego/v4/certificate/certificates.go
generated
vendored
@ -55,18 +55,11 @@ type Resource struct {
|
|||||||
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
||||||
type ObtainRequest struct {
|
type ObtainRequest struct {
|
||||||
Domains []string
|
Domains []string
|
||||||
|
Bundle bool
|
||||||
PrivateKey crypto.PrivateKey
|
PrivateKey crypto.PrivateKey
|
||||||
MustStaple bool
|
MustStaple bool
|
||||||
|
|
||||||
NotBefore time.Time
|
|
||||||
NotAfter time.Time
|
|
||||||
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.
|
||||||
@ -77,16 +70,9 @@ type ObtainRequest struct {
|
|||||||
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
// See https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2.
|
||||||
type ObtainForCSRRequest struct {
|
type ObtainForCSRRequest struct {
|
||||||
CSR *x509.CertificateRequest
|
CSR *x509.CertificateRequest
|
||||||
|
|
||||||
NotBefore time.Time
|
|
||||||
NotAfter time.Time
|
|
||||||
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 {
|
||||||
@ -131,13 +117,7 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
|||||||
log.Infof("[%s] acme: Obtaining SAN certificate", strings.Join(domains, ", "))
|
log.Infof("[%s] acme: Obtaining SAN certificate", strings.Join(domains, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
orderOpts := &api.OrderOptions{
|
order, err := c.core.Orders.New(domains)
|
||||||
NotBefore: request.NotBefore,
|
|
||||||
NotAfter: request.NotAfter,
|
|
||||||
ReplacesCertID: request.ReplacesCertID,
|
|
||||||
}
|
|
||||||
|
|
||||||
order, err := c.core.Orders.NewWithOptions(domains, orderOpts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -158,11 +138,11 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
|||||||
|
|
||||||
log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
|
log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
|
||||||
|
|
||||||
failures := newObtainError()
|
failures := make(obtainError)
|
||||||
cert, err := c.getForOrder(domains, order, request.Bundle, request.PrivateKey, request.MustStaple, request.PreferredChain)
|
cert, err := c.getForOrder(domains, order, request.Bundle, request.PrivateKey, request.MustStaple, request.PreferredChain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, auth := range authz {
|
for _, auth := range authz {
|
||||||
failures.Add(challenge.GetTargetedDomain(auth), err)
|
failures[challenge.GetTargetedDomain(auth)] = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +150,12 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
|
|||||||
c.deactivateAuthorizations(order, true)
|
c.deactivateAuthorizations(order, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert, failures.Join()
|
// Do not return an empty failures map, because
|
||||||
|
// it would still be a non-nil error value
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return cert, failures
|
||||||
|
}
|
||||||
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObtainForCSR tries to obtain a certificate matching the CSR passed into it.
|
// ObtainForCSR tries to obtain a certificate matching the CSR passed into it.
|
||||||
@ -197,13 +182,7 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
|||||||
log.Infof("[%s] acme: Obtaining SAN certificate given a CSR", strings.Join(domains, ", "))
|
log.Infof("[%s] acme: Obtaining SAN certificate given a CSR", strings.Join(domains, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
orderOpts := &api.OrderOptions{
|
order, err := c.core.Orders.New(domains)
|
||||||
NotBefore: request.NotBefore,
|
|
||||||
NotAfter: request.NotAfter,
|
|
||||||
ReplacesCertID: request.ReplacesCertID,
|
|
||||||
}
|
|
||||||
|
|
||||||
order, err := c.core.Orders.NewWithOptions(domains, orderOpts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -224,11 +203,11 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
|||||||
|
|
||||||
log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
|
log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
|
||||||
|
|
||||||
failures := newObtainError()
|
failures := make(obtainError)
|
||||||
cert, err := c.getForCSR(domains, order, request.Bundle, request.CSR.Raw, nil, request.PreferredChain)
|
cert, err := c.getForCSR(domains, order, request.Bundle, request.CSR.Raw, nil, request.PreferredChain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, auth := range authz {
|
for _, auth := range authz {
|
||||||
failures.Add(challenge.GetTargetedDomain(auth), err)
|
failures[challenge.GetTargetedDomain(auth)] = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +220,12 @@ func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error)
|
|||||||
cert.CSR = certcrypto.PEMEncode(request.CSR)
|
cert.CSR = certcrypto.PEMEncode(request.CSR)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert, failures.Join()
|
// Do not return an empty failures map,
|
||||||
|
// because it would still be a non-nil error value
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return cert, failures
|
||||||
|
}
|
||||||
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bundle bool, privateKey crypto.PrivateKey, mustStaple bool, preferredChain string) (*Resource, error) {
|
func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bundle bool, privateKey crypto.PrivateKey, mustStaple bool, preferredChain string) (*Resource, error) {
|
||||||
@ -253,10 +237,8 @@ func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bund
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commonName := ""
|
// Determine certificate name(s) based on the authorization resources
|
||||||
if len(domains[0]) <= 64 {
|
commonName := domains[0]
|
||||||
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
|
||||||
@ -264,12 +246,7 @@ 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)
|
||||||
@ -291,8 +268,9 @@ func (c *Certifier) getForCSR(domains []string, order acme.ExtendedOrder, bundle
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commonName := domains[0]
|
||||||
certRes := &Resource{
|
certRes := &Resource{
|
||||||
Domain: domains[0],
|
Domain: commonName,
|
||||||
CertURL: respOrder.Certificate,
|
CertURL: respOrder.Certificate,
|
||||||
PrivateKey: privateKeyPem,
|
PrivateKey: privateKeyPem,
|
||||||
}
|
}
|
||||||
@ -410,18 +388,6 @@ func (c *Certifier) RevokeWithReason(cert []byte, reason *uint) error {
|
|||||||
return c.core.Certificates.Revoke(revokeMsg)
|
return c.core.Certificates.Revoke(revokeMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenewOptions options used by Certifier.RenewWithOptions.
|
|
||||||
type RenewOptions struct {
|
|
||||||
NotBefore time.Time
|
|
||||||
NotAfter time.Time
|
|
||||||
// If true, the []byte contains both the issuer certificate and your issued certificate as a bundle.
|
|
||||||
Bundle bool
|
|
||||||
PreferredChain string
|
|
||||||
AlwaysDeactivateAuthorizations bool
|
|
||||||
// Not supported for CSR request.
|
|
||||||
MustStaple bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Renew takes a Resource and tries to renew the certificate.
|
// Renew takes a Resource and tries to renew the certificate.
|
||||||
//
|
//
|
||||||
// If the renewal process succeeds, the new certificate will be returned in a new CertResource.
|
// If the renewal process succeeds, the new certificate will be returned in a new CertResource.
|
||||||
@ -432,26 +398,7 @@ type RenewOptions struct {
|
|||||||
// If bundle is true, the []byte contains both the issuer certificate and your issued certificate as a bundle.
|
// If bundle is true, the []byte contains both the issuer certificate and your issued certificate as a bundle.
|
||||||
//
|
//
|
||||||
// For private key reuse the PrivateKey property of the passed in Resource should be non-nil.
|
// For private key reuse the PrivateKey property of the passed in Resource should be non-nil.
|
||||||
// Deprecated: use RenewWithOptions instead.
|
|
||||||
func (c *Certifier) Renew(certRes Resource, bundle, mustStaple bool, preferredChain string) (*Resource, error) {
|
func (c *Certifier) Renew(certRes Resource, bundle, mustStaple bool, preferredChain string) (*Resource, error) {
|
||||||
return c.RenewWithOptions(certRes, &RenewOptions{
|
|
||||||
Bundle: bundle,
|
|
||||||
PreferredChain: preferredChain,
|
|
||||||
MustStaple: mustStaple,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenewWithOptions takes a Resource and tries to renew the certificate.
|
|
||||||
//
|
|
||||||
// If the renewal process succeeds, the new certificate will be returned in a new CertResource.
|
|
||||||
// Please be aware that this function will return a new certificate in ANY case that is not an error.
|
|
||||||
// If the server does not provide us with a new cert on a GET request to the CertURL
|
|
||||||
// this function will start a new-cert flow where a new certificate gets generated.
|
|
||||||
//
|
|
||||||
// If bundle is true, the []byte contains both the issuer certificate and your issued certificate as a bundle.
|
|
||||||
//
|
|
||||||
// For private key reuse the PrivateKey property of the passed in Resource should be non-nil.
|
|
||||||
func (c *Certifier) RenewWithOptions(certRes Resource, options *RenewOptions) (*Resource, error) {
|
|
||||||
// Input certificate is PEM encoded.
|
// Input certificate is PEM encoded.
|
||||||
// Decode it here as we may need the decoded cert later on in the renewal process.
|
// Decode it here as we may need the decoded cert later on in the renewal process.
|
||||||
// The input may be a bundle or a single certificate.
|
// The input may be a bundle or a single certificate.
|
||||||
@ -478,17 +425,11 @@ func (c *Certifier) RenewWithOptions(certRes Resource, options *RenewOptions) (*
|
|||||||
return nil, errP
|
return nil, errP
|
||||||
}
|
}
|
||||||
|
|
||||||
request := ObtainForCSRRequest{CSR: csr}
|
return c.ObtainForCSR(ObtainForCSRRequest{
|
||||||
|
CSR: csr,
|
||||||
if options != nil {
|
Bundle: bundle,
|
||||||
request.NotBefore = options.NotBefore
|
PreferredChain: preferredChain,
|
||||||
request.NotAfter = options.NotAfter
|
})
|
||||||
request.Bundle = options.Bundle
|
|
||||||
request.PreferredChain = options.PreferredChain
|
|
||||||
request.AlwaysDeactivateAuthorizations = options.AlwaysDeactivateAuthorizations
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.ObtainForCSR(request)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var privateKey crypto.PrivateKey
|
var privateKey crypto.PrivateKey
|
||||||
@ -499,21 +440,14 @@ func (c *Certifier) RenewWithOptions(certRes Resource, options *RenewOptions) (*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request := ObtainRequest{
|
query := ObtainRequest{
|
||||||
Domains: certcrypto.ExtractDomains(x509Cert),
|
Domains: certcrypto.ExtractDomains(x509Cert),
|
||||||
|
Bundle: bundle,
|
||||||
PrivateKey: privateKey,
|
PrivateKey: privateKey,
|
||||||
|
MustStaple: mustStaple,
|
||||||
|
PreferredChain: preferredChain,
|
||||||
}
|
}
|
||||||
|
return c.Obtain(query)
|
||||||
if options != nil {
|
|
||||||
request.MustStaple = options.MustStaple
|
|
||||||
request.NotBefore = options.NotBefore
|
|
||||||
request.NotAfter = options.NotAfter
|
|
||||||
request.Bundle = options.Bundle
|
|
||||||
request.PreferredChain = options.PreferredChain
|
|
||||||
request.AlwaysDeactivateAuthorizations = options.AlwaysDeactivateAuthorizations
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Obtain(request)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOCSP takes a PEM encoded cert or cert bundle returning the raw OCSP response,
|
// GetOCSP takes a PEM encoded cert or cert bundle returning the raw OCSP response,
|
||||||
@ -614,13 +548,8 @@ 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: domain,
|
Domain: x509Certs[0].Subject.CommonName,
|
||||||
Certificate: cert,
|
Certificate: cert,
|
||||||
IssuerCertificate: issuer,
|
IssuerCertificate: issuer,
|
||||||
CertURL: url,
|
CertURL: url,
|
||||||
|
36
vendor/github.com/go-acme/lego/v4/certificate/errors.go
generated
vendored
36
vendor/github.com/go-acme/lego/v4/certificate/errors.go
generated
vendored
@ -1,37 +1,27 @@
|
|||||||
package certificate
|
package certificate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type obtainError struct {
|
// obtainError is returned when there are specific errors available per domain.
|
||||||
data map[string]error
|
type obtainError map[string]error
|
||||||
}
|
|
||||||
|
|
||||||
func newObtainError() *obtainError {
|
func (e obtainError) Error() string {
|
||||||
return &obtainError{data: make(map[string]error)}
|
buffer := bytes.NewBufferString("error: one or more domains had a problem:\n")
|
||||||
}
|
|
||||||
|
|
||||||
func (e *obtainError) Add(domain string, err error) {
|
var domains []string
|
||||||
e.data[domain] = err
|
for domain := range e {
|
||||||
|
domains = append(domains, domain)
|
||||||
}
|
}
|
||||||
|
sort.Strings(domains)
|
||||||
|
|
||||||
func (e *obtainError) Join() error {
|
for _, domain := range domains {
|
||||||
if e == nil {
|
buffer.WriteString(fmt.Sprintf("[%s] %s\n", domain, e[domain]))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return buffer.String()
|
||||||
if len(e.data) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
for d, e := range e.data {
|
|
||||||
err = errors.Join(err, fmt.Errorf("%s: %w", d, e))
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("error: one or more domains had a problem:\n%w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type domainError struct {
|
type domainError struct {
|
||||||
|
129
vendor/github.com/go-acme/lego/v4/certificate/renewal.go
generated
vendored
129
vendor/github.com/go-acme/lego/v4/certificate/renewal.go
generated
vendored
@ -1,129 +0,0 @@
|
|||||||
package certificate
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/asn1"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RenewalInfoRequest contains the necessary renewal information.
|
|
||||||
type RenewalInfoRequest struct {
|
|
||||||
Cert *x509.Certificate
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenewalInfoResponse is a wrapper around acme.RenewalInfoResponse that provides a method for determining when to renew a certificate.
|
|
||||||
type RenewalInfoResponse struct {
|
|
||||||
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.
|
|
||||||
// It returns a pointer to a time.Time value indicating when the renewal should be attempted or nil if deferred until the next normal wake time.
|
|
||||||
// This method implements the RECOMMENDED algorithm described in draft-ietf-acme-ari.
|
|
||||||
//
|
|
||||||
// - (4.1-11. Getting Renewal Information) https://datatracker.ietf.org/doc/draft-ietf-acme-ari/
|
|
||||||
func (r *RenewalInfoResponse) ShouldRenewAt(now time.Time, willingToSleep time.Duration) *time.Time {
|
|
||||||
// Explicitly convert all times to UTC.
|
|
||||||
now = now.UTC()
|
|
||||||
start := r.SuggestedWindow.Start.UTC()
|
|
||||||
end := r.SuggestedWindow.End.UTC()
|
|
||||||
|
|
||||||
// Select a uniform random time within the suggested window.
|
|
||||||
window := end.Sub(start)
|
|
||||||
randomDuration := time.Duration(rand.Int63n(int64(window)))
|
|
||||||
rt := start.Add(randomDuration)
|
|
||||||
|
|
||||||
// If the selected time is in the past, attempt renewal immediately.
|
|
||||||
if rt.Before(now) {
|
|
||||||
return &now
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if the client can schedule itself to attempt renewal at exactly the selected time, do so.
|
|
||||||
willingToSleepUntil := now.Add(willingToSleep)
|
|
||||||
if willingToSleepUntil.After(rt) || willingToSleepUntil.Equal(rt) {
|
|
||||||
return &rt
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Otherwise, if the selected time is before the next time that the client would wake up normally, attempt renewal immediately.
|
|
||||||
|
|
||||||
// Otherwise, sleep until the next normal wake time, re-check ARI, and return to Step 1.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRenewalInfo sends a request to the ACME server's renewalInfo endpoint to obtain a suggested renewal window.
|
|
||||||
// The caller MUST provide the certificate and issuer certificate for the certificate they wish to renew.
|
|
||||||
// The caller should attempt to renew the certificate at the time indicated by the ShouldRenewAt method of the returned RenewalInfoResponse object.
|
|
||||||
//
|
|
||||||
// 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) GetRenewalInfo(req RenewalInfoRequest) (*RenewalInfoResponse, error) {
|
|
||||||
certID, err := MakeARICertID(req.Cert)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error making certID: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.core.Certificates.GetRenewalInfo(certID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var info RenewalInfoResponse
|
|
||||||
err = json.NewDecoder(resp.Body).Decode(&info)
|
|
||||||
if err != nil {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeARICertID constructs a certificate identifier as described in draft-ietf-acme-ari-03, section 4.1.
|
|
||||||
func MakeARICertID(leaf *x509.Certificate) (string, error) {
|
|
||||||
if leaf == nil {
|
|
||||||
return "", errors.New("leaf certificate is nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal the Serial Number into DER.
|
|
||||||
der, err := asn1.Marshal(leaf.SerialNumber)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the DER encoded bytes are sufficient (at least 3 bytes: tag,
|
|
||||||
// length, and value).
|
|
||||||
if len(der) < 3 {
|
|
||||||
return "", errors.New("invalid DER encoding of serial number")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract only the integer bytes from the DER encoded Serial Number
|
|
||||||
// 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
|
|
||||||
}
|
|
8
vendor/github.com/go-acme/lego/v4/challenge/dns01/cname.go
generated
vendored
8
vendor/github.com/go-acme/lego/v4/challenge/dns01/cname.go
generated
vendored
@ -1,16 +1,12 @@
|
|||||||
package dns01
|
package dns01
|
||||||
|
|
||||||
import (
|
import "github.com/miekg/dns"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update FQDN with CNAME if any.
|
// Update FQDN with CNAME if any.
|
||||||
func updateDomainWithCName(r *dns.Msg, fqdn string) string {
|
func updateDomainWithCName(r *dns.Msg, fqdn string) string {
|
||||||
for _, rr := range r.Answer {
|
for _, rr := range r.Answer {
|
||||||
if cn, ok := rr.(*dns.CNAME); ok {
|
if cn, ok := rr.(*dns.CNAME); ok {
|
||||||
if strings.EqualFold(cn.Hdr.Name, fqdn) {
|
if cn.Hdr.Name == fqdn {
|
||||||
return cn.Target
|
return cn.Target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge.go
generated
vendored
43
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge.go
generated
vendored
@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme"
|
"github.com/go-acme/lego/v4/acme"
|
||||||
@ -115,7 +114,7 @@ func (c *Challenge) Solve(authz acme.Authorization) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := GetChallengeInfo(authz.Identifier.Value, keyAuth)
|
fqdn, value := GetRecord(authz.Identifier.Value, keyAuth)
|
||||||
|
|
||||||
var timeout, interval time.Duration
|
var timeout, interval time.Duration
|
||||||
switch provider := c.provider.(type) {
|
switch provider := c.provider.(type) {
|
||||||
@ -125,12 +124,12 @@ func (c *Challenge) Solve(authz acme.Authorization) error {
|
|||||||
timeout, interval = DefaultPropagationTimeout, DefaultPollingInterval
|
timeout, interval = DefaultPropagationTimeout, DefaultPollingInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("[%s] acme: Checking DNS record propagation. [nameservers=%s]", domain, strings.Join(recursiveNameservers, ","))
|
log.Infof("[%s] acme: Checking DNS record propagation using %+v", domain, recursiveNameservers)
|
||||||
|
|
||||||
time.Sleep(interval)
|
time.Sleep(interval)
|
||||||
|
|
||||||
err = wait.For("propagation", timeout, interval, func() (bool, error) {
|
err = wait.For("propagation", timeout, interval, func() (bool, error) {
|
||||||
stop, errP := c.preCheck.call(domain, info.EffectiveFQDN, info.Value)
|
stop, errP := c.preCheck.call(domain, fqdn, value)
|
||||||
if !stop || errP != nil {
|
if !stop || errP != nil {
|
||||||
log.Infof("[%s] acme: Waiting for DNS record propagation.", domain)
|
log.Infof("[%s] acme: Waiting for DNS record propagation.", domain)
|
||||||
}
|
}
|
||||||
@ -173,49 +172,25 @@ type sequential interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRecord returns a DNS record which will fulfill the `dns-01` challenge.
|
// GetRecord returns a DNS record which will fulfill the `dns-01` challenge.
|
||||||
// Deprecated: use GetChallengeInfo instead.
|
|
||||||
func GetRecord(domain, keyAuth string) (fqdn, value string) {
|
func GetRecord(domain, keyAuth string) (fqdn, value string) {
|
||||||
info := GetChallengeInfo(domain, keyAuth)
|
|
||||||
|
|
||||||
return info.EffectiveFQDN, info.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChallengeInfo contains the information use to create the TXT record.
|
|
||||||
type ChallengeInfo struct {
|
|
||||||
// FQDN is the full-qualified challenge domain (i.e. `_acme-challenge.[domain].`)
|
|
||||||
FQDN string
|
|
||||||
|
|
||||||
// EffectiveFQDN contains the resulting FQDN after the CNAMEs resolutions.
|
|
||||||
EffectiveFQDN string
|
|
||||||
|
|
||||||
// Value contains the value for the TXT record.
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChallengeInfo returns information used to create a DNS record which will fulfill the `dns-01` challenge.
|
|
||||||
func GetChallengeInfo(domain, keyAuth string) ChallengeInfo {
|
|
||||||
keyAuthShaBytes := sha256.Sum256([]byte(keyAuth))
|
keyAuthShaBytes := sha256.Sum256([]byte(keyAuth))
|
||||||
// base64URL encoding without padding
|
// base64URL encoding without padding
|
||||||
value := base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
|
value = base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
|
||||||
|
|
||||||
ok, _ := strconv.ParseBool(os.Getenv("LEGO_DISABLE_CNAME_SUPPORT"))
|
fqdn = getChallengeFqdn(domain)
|
||||||
|
|
||||||
return ChallengeInfo{
|
return
|
||||||
Value: value,
|
|
||||||
FQDN: getChallengeFQDN(domain, false),
|
|
||||||
EffectiveFQDN: getChallengeFQDN(domain, !ok),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getChallengeFQDN(domain string, followCNAME bool) string {
|
func getChallengeFqdn(domain string) string {
|
||||||
fqdn := fmt.Sprintf("_acme-challenge.%s.", domain)
|
fqdn := fmt.Sprintf("_acme-challenge.%s.", domain)
|
||||||
|
|
||||||
if !followCNAME {
|
if ok, _ := strconv.ParseBool(os.Getenv("LEGO_DISABLE_CNAME_SUPPORT")); ok {
|
||||||
return fqdn
|
return fqdn
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursion counter so it doesn't spin out of control
|
// recursion counter so it doesn't spin out of control
|
||||||
for range 50 {
|
for limit := 0; limit < 50; limit++ {
|
||||||
// Keep following CNAMEs
|
// Keep following CNAMEs
|
||||||
r, err := dnsQuery(fqdn, dns.TypeCNAME, recursiveNameservers, true)
|
r, err := dnsQuery(fqdn, dns.TypeCNAME, recursiveNameservers, true)
|
||||||
|
|
||||||
|
21
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge_manual.go
generated
vendored
21
vendor/github.com/go-acme/lego/v4/challenge/dns01/dns_challenge_manual.go
generated
vendored
@ -21,36 +21,33 @@ func NewDNSProviderManual() (*DNSProviderManual, error) {
|
|||||||
|
|
||||||
// Present prints instructions for manually creating the TXT record.
|
// Present prints instructions for manually creating the TXT record.
|
||||||
func (*DNSProviderManual) Present(domain, token, keyAuth string) error {
|
func (*DNSProviderManual) Present(domain, token, keyAuth string) error {
|
||||||
info := GetChallengeInfo(domain, keyAuth)
|
fqdn, value := GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := FindZoneByFqdn(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("manual: could not find zone: %w", err)
|
return 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)
|
||||||
fmt.Printf(dnsTemplate+"\n", info.EffectiveFQDN, DefaultTTL, info.Value)
|
fmt.Printf(dnsTemplate+"\n", fqdn, DefaultTTL, value)
|
||||||
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 nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanUp prints instructions for manually removing the TXT record.
|
// CleanUp prints instructions for manually removing the TXT record.
|
||||||
func (*DNSProviderManual) CleanUp(domain, token, keyAuth string) error {
|
func (*DNSProviderManual) CleanUp(domain, token, keyAuth string) error {
|
||||||
info := GetChallengeInfo(domain, keyAuth)
|
fqdn, _ := GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := FindZoneByFqdn(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("manual: could not find zone: %w", err)
|
return 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)
|
||||||
fmt.Printf(dnsTemplate+"\n", info.EffectiveFQDN, DefaultTTL, "...")
|
fmt.Printf(dnsTemplate+"\n", fqdn, DefaultTTL, "...")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
24
vendor/github.com/go-acme/lego/v4/challenge/dns01/domain.go
generated
vendored
24
vendor/github.com/go-acme/lego/v4/challenge/dns01/domain.go
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
package dns01
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ExtractSubDomain extracts the subdomain part from a domain and a zone.
|
|
||||||
func ExtractSubDomain(domain, zone string) (string, error) {
|
|
||||||
canonDomain := dns.Fqdn(domain)
|
|
||||||
canonZone := dns.Fqdn(zone)
|
|
||||||
|
|
||||||
if canonDomain == canonZone {
|
|
||||||
return "", fmt.Errorf("no subdomain because the domain and the zone are identical: %s", canonDomain)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !dns.IsSubDomain(canonZone, canonDomain) {
|
|
||||||
return "", fmt.Errorf("%s is not a subdomain of %s", canonDomain, canonZone)
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.TrimSuffix(canonDomain, "."+canonZone), nil
|
|
||||||
}
|
|
150
vendor/github.com/go-acme/lego/v4/challenge/dns01/nameserver.go
generated
vendored
150
vendor/github.com/go-acme/lego/v4/challenge/dns01/nameserver.go
generated
vendored
@ -4,9 +4,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"slices"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -99,12 +96,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 find zone: %w", err)
|
return nil, fmt.Errorf("could not determine the 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, fmt.Errorf("NS call failed: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rr := range r.Answer {
|
for _, rr := range r.Answer {
|
||||||
@ -116,8 +113,7 @@ 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
|
||||||
@ -131,7 +127,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 "", fmt.Errorf("[fqdn=%s] %w", fqdn, err)
|
return "", err
|
||||||
}
|
}
|
||||||
return soa.primaryNs, nil
|
return soa.primaryNs, nil
|
||||||
}
|
}
|
||||||
@ -147,7 +143,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 "", fmt.Errorf("[fqdn=%s] %w", fqdn, err)
|
return "", err
|
||||||
}
|
}
|
||||||
return soa.zone, nil
|
return soa.zone, nil
|
||||||
}
|
}
|
||||||
@ -172,35 +168,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 r *dns.Msg
|
var in *dns.Msg
|
||||||
|
|
||||||
labelIndexes := dns.Split(fqdn)
|
labelIndexes := dns.Split(fqdn)
|
||||||
for _, index := range labelIndexes {
|
for _, index := range labelIndexes {
|
||||||
domain := fqdn[index:]
|
domain := fqdn[index:]
|
||||||
|
|
||||||
r, err = dnsQuery(domain, dns.TypeSOA, nameservers, true)
|
in, err = dnsQuery(domain, dns.TypeSOA, nameservers, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if r == nil {
|
if in == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r.Rcode {
|
switch in.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(r.Answer) == 0 {
|
if len(in.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(r) {
|
if dnsMsgContainsCNAME(in) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ans := range r.Answer {
|
for _, ans := range in.Answer {
|
||||||
if soa, ok := ans.(*dns.SOA); ok {
|
if soa, ok := ans.(*dns.SOA); ok {
|
||||||
return newSoaCacheEntry(soa), nil
|
return newSoaCacheEntry(soa), nil
|
||||||
}
|
}
|
||||||
@ -209,46 +205,36 @@ 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, &DNSError{Message: fmt.Sprintf("unexpected response for '%s'", domain), MsgOut: r}
|
return nil, fmt.Errorf("unexpected response code '%s' for %s", dns.RcodeToString[in.Rcode], domain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, &DNSError{Message: fmt.Sprintf("could not find the start of authority for '%s'", fqdn), MsgOut: r, Err: err}
|
return nil, fmt.Errorf("could not find the start of authority for %s%s", fqdn, formatDNSError(in, 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 {
|
||||||
return slices.ContainsFunc(msg.Answer, func(rr dns.RR) bool {
|
for _, ans := range msg.Answer {
|
||||||
_, ok := rr.(*dns.CNAME)
|
if _, ok := ans.(*dns.CNAME); ok {
|
||||||
return ok
|
return true
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
|
||||||
if len(nameservers) == 0 {
|
var in *dns.Msg
|
||||||
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 {
|
||||||
r, err = sendDNSQuery(m, ns)
|
in, err = sendDNSQuery(m, ns)
|
||||||
if err == nil && len(r.Answer) > 0 {
|
if err == nil && len(in.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 {
|
||||||
@ -264,84 +250,32 @@ 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 {
|
|
||||||
tcp := &dns.Client{Net: "tcp", Timeout: dnsTimeout}
|
|
||||||
r, _, err := tcp.Exchange(m, ns)
|
|
||||||
if err != nil {
|
|
||||||
return r, &DNSError{Message: "DNS call error", MsgIn: m, NS: ns, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
udp := &dns.Client{Net: "udp", Timeout: dnsTimeout}
|
udp := &dns.Client{Net: "udp", Timeout: dnsTimeout}
|
||||||
r, _, err := udp.Exchange(m, ns)
|
in, _, err := udp.Exchange(m, ns)
|
||||||
|
|
||||||
if r != nil && r.Truncated {
|
if in != nil && in.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
|
||||||
r, _, err = tcp.Exchange(m, ns)
|
in, _, 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 {
|
||||||
return r, &DNSError{Message: "DNS call error", MsgIn: m, NS: ns, Err: err}
|
parts = append(parts, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
if len(parts) > 0 {
|
||||||
|
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, ";")
|
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/challenge/resolver/errors.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/challenge/resolver/errors.go
generated
vendored
@ -19,7 +19,7 @@ func (e obtainError) Error() string {
|
|||||||
sort.Strings(domains)
|
sort.Strings(domains)
|
||||||
|
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
_, _ = fmt.Fprintf(buffer, "[%s] %s\n", domain, e[domain])
|
buffer.WriteString(fmt.Sprintf("[%s] %s\n", domain, e[domain]))
|
||||||
}
|
}
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/challenge/resolver/prober.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/challenge/resolver/prober.go
generated
vendored
@ -128,7 +128,7 @@ func sequentialSolve(authSolvers []*selectedAuthSolver, failures obtainError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parallelSolve(authSolvers []*selectedAuthSolver, failures obtainError) {
|
func parallelSolve(authSolvers []*selectedAuthSolver, failures obtainError) {
|
||||||
// For all valid preSolvers, first submit the challenges, so they have max time to propagate
|
// For all valid preSolvers, first submit the challenges so they have max time to propagate
|
||||||
for _, authSolver := range authSolvers {
|
for _, authSolver := range authSolvers {
|
||||||
authz := authSolver.authz
|
authz := authSolver.authz
|
||||||
if solvr, ok := authSolver.solver.(preSolver); ok {
|
if solvr, ok := authSolver.solver.(preSolver); ok {
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/challenge/resolver/solver_manager.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/challenge/resolver/solver_manager.go
generated
vendored
@ -53,7 +53,7 @@ func (c *SolverManager) SetDNS01Provider(p challenge.Provider, opts ...dns01.Cha
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes a challenge type from the available solvers.
|
// Remove Remove a challenge type from the available solvers.
|
||||||
func (c *SolverManager) Remove(chlgType challenge.Type) {
|
func (c *SolverManager) Remove(chlgType challenge.Type) {
|
||||||
delete(c.solvers, chlgType)
|
delete(c.solvers, chlgType)
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/challenge/tlsalpn01/tls_alpn_challenge_server.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/challenge/tlsalpn01/tls_alpn_challenge_server.go
generated
vendored
@ -40,7 +40,7 @@ func (s *ProviderServer) GetAddress() string {
|
|||||||
return net.JoinHostPort(s.iface, s.port)
|
return net.JoinHostPort(s.iface, s.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Present generates a certificate with an SHA-256 digest of the keyAuth provided
|
// Present generates a certificate with a SHA-256 digest of the keyAuth provided
|
||||||
// as the acmeValidation-v1 extension value to conform to the ACME-TLS-ALPN spec.
|
// as the acmeValidation-v1 extension value to conform to the ACME-TLS-ALPN spec.
|
||||||
func (s *ProviderServer) Present(domain, token, keyAuth string) error {
|
func (s *ProviderServer) Present(domain, token, keyAuth string) error {
|
||||||
if s.port == "" {
|
if s.port == "" {
|
||||||
|
2
vendor/github.com/go-acme/lego/v4/lego/client_config.go
generated
vendored
2
vendor/github.com/go-acme/lego/v4/lego/client_config.go
generated
vendored
@ -29,7 +29,7 @@ const (
|
|||||||
|
|
||||||
// caServerNameEnvVar is the environment variable name that can be used to
|
// caServerNameEnvVar is the environment variable name that can be used to
|
||||||
// specify the CA server name that can be used to
|
// specify the CA server name that can be used to
|
||||||
// authenticate an ACME server with an HTTPS certificate not issued by a CA in
|
// authenticate an ACME server with a HTTPS certificate not issued by a CA in
|
||||||
// the system-wide trusted root list.
|
// the system-wide trusted root list.
|
||||||
caServerNameEnvVar = "LEGO_CA_SERVER_NAME"
|
caServerNameEnvVar = "LEGO_CA_SERVER_NAME"
|
||||||
|
|
||||||
|
89
vendor/github.com/go-acme/lego/v4/platform/config/env/env.go
generated
vendored
89
vendor/github.com/go-acme/lego/v4/platform/config/env/env.go
generated
vendored
@ -78,26 +78,15 @@ 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 value != "" {
|
if len(value) > 0 {
|
||||||
return value, main
|
return value, main
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
value := GetOrFile(name)
|
value := GetOrFile(name)
|
||||||
if value != "" {
|
if len(value) > 0 {
|
||||||
return value, main
|
return value, main
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,32 +94,43 @@ 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 envvar 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 an time.Duration (second).
|
||||||
|
// Returns the default if the envvar 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 envvar cannot be find.
|
||||||
func GetOrDefaultString(envVar string, defaultValue string) string {
|
func GetOrDefaultString(envVar, defaultValue string) string {
|
||||||
return getOrDefault(envVar, defaultValue, ParseString)
|
v := GetOrFile(envVar)
|
||||||
|
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 envvar cannot be coopered to a boolean, or is not found.
|
// Returns the default if the envvar cannot be coopered to a boolean, or is not found.
|
||||||
func GetOrDefaultBool(envVar string, defaultValue bool) bool {
|
func GetOrDefaultBool(envVar string, defaultValue bool) bool {
|
||||||
return getOrDefault(envVar, defaultValue, strconv.ParseBool)
|
v, err := strconv.ParseBool(GetOrFile(envVar))
|
||||||
}
|
|
||||||
|
|
||||||
// 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,26 +161,3 @@ 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
|
|
||||||
}
|
|
||||||
|
5
vendor/github.com/go-acme/lego/v4/platform/wait/wait.go
generated
vendored
5
vendor/github.com/go-acme/lego/v4/platform/wait/wait.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package wait
|
package wait
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -17,9 +18,9 @@ func For(msg string, timeout, interval time.Duration, f func() (bool, error)) er
|
|||||||
select {
|
select {
|
||||||
case <-timeUp:
|
case <-timeUp:
|
||||||
if lastErr == nil {
|
if lastErr == nil {
|
||||||
return fmt.Errorf("%s: time limit exceeded", msg)
|
return errors.New("time limit exceeded")
|
||||||
}
|
}
|
||||||
return fmt.Errorf("%s: time limit exceeded: last error: %w", msg, lastErr)
|
return fmt.Errorf("time limit exceeded: last error: %w", lastErr)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
vendor/github.com/go-acme/lego/v4/providers/dns/internal/errutils/client.go
generated
vendored
133
vendor/github.com/go-acme/lego/v4/providers/dns/internal/errutils/client.go
generated
vendored
@ -1,133 +0,0 @@
|
|||||||
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))
|
|
||||||
}
|
|
165
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.go
generated
vendored
165
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.go
generated
vendored
@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -15,13 +16,15 @@ 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"
|
||||||
@ -29,19 +32,6 @@ 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"`
|
||||||
@ -52,32 +42,18 @@ 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
|
ApplicationKey string
|
||||||
ApplicationSecret string
|
ApplicationSecret string
|
||||||
ConsumerKey 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{
|
||||||
@ -102,11 +78,17 @@ 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) {
|
||||||
config, err := createConfigFromEnvVars()
|
values, err := env.Get(EnvEndpoint, EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +98,16 @@ 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.OAuth2Config != nil && config.hasAppKeyAuth() {
|
if config.APIEndpoint == "" || config.ApplicationKey == "" || config.ApplicationSecret == "" || config.ConsumerKey == "" {
|
||||||
return nil, errors.New("ovh: can't use both authentication systems (ApplicationKey and OAuth2)")
|
return nil, errors.New("ovh: credentials missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := newClient(config)
|
client, err := ovh.NewClient(
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
@ -136,23 +123,19 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
|||||||
|
|
||||||
// Present creates a TXT record to fulfill the dns-01 challenge.
|
// Present creates a TXT record to fulfill the dns-01 challenge.
|
||||||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
info := dns01.GetChallengeInfo(domain, keyAuth)
|
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
// Parse domain name
|
// Parse domain name
|
||||||
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := dns01.FindZoneByFqdn(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ovh: could not find zone for domain %q: %w", domain, err)
|
return fmt.Errorf("ovh: could not determine zone for domain %q: %w", fqdn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authZone = dns01.UnFqdn(authZone)
|
authZone = dns01.UnFqdn(authZone)
|
||||||
|
subDomain := extractRecordName(fqdn, authZone)
|
||||||
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ovh: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
reqURL := fmt.Sprintf("/domain/zone/%s/record", authZone)
|
reqURL := fmt.Sprintf("/domain/zone/%s/record", authZone)
|
||||||
reqData := Record{FieldType: "TXT", SubDomain: subDomain, Target: info.Value, TTL: d.config.TTL}
|
reqData := Record{FieldType: "TXT", SubDomain: subDomain, Target: value, TTL: d.config.TTL}
|
||||||
|
|
||||||
// Create TXT record
|
// Create TXT record
|
||||||
var respData Record
|
var respData Record
|
||||||
@ -177,19 +160,19 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||||||
|
|
||||||
// CleanUp removes the TXT record matching the specified parameters.
|
// CleanUp removes the TXT record matching the specified parameters.
|
||||||
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
info := dns01.GetChallengeInfo(domain, keyAuth)
|
fqdn, _ := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
// get the record's unique ID from when we created it
|
// get the record's unique ID from when we created it
|
||||||
d.recordIDsMu.Lock()
|
d.recordIDsMu.Lock()
|
||||||
recordID, ok := d.recordIDs[token]
|
recordID, ok := d.recordIDs[token]
|
||||||
d.recordIDsMu.Unlock()
|
d.recordIDsMu.Unlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("ovh: unknown record ID for '%s'", info.EffectiveFQDN)
|
return fmt.Errorf("ovh: unknown record ID for '%s'", fqdn)
|
||||||
}
|
}
|
||||||
|
|
||||||
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
authZone, err := dns01.FindZoneByFqdn(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ovh: could not find zone for domain %q: %w", domain, err)
|
return fmt.Errorf("ovh: could not determine zone for domain %q: %w", fqdn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authZone = dns01.UnFqdn(authZone)
|
authZone = dns01.UnFqdn(authZone)
|
||||||
@ -222,94 +205,10 @@ 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) {
|
func extractRecordName(fqdn, zone string) string {
|
||||||
firstAppKeyEnvVar := findFirstValuedEnvVar(EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey)
|
name := dns01.UnFqdn(fqdn)
|
||||||
firstOAuth2EnvVar := findFirstValuedEnvVar(EnvClientID, EnvClientSecret)
|
if idx := strings.Index(name, "."+zone); idx != -1 {
|
||||||
|
return name[:idx]
|
||||||
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 ""
|
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
|
|
||||||
}
|
|
||||||
|
35
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.toml
generated
vendored
35
vendor/github.com/go-acme/lego/v4/providers/dns/ovh/ovh.toml
generated
vendored
@ -5,20 +5,11 @@ 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 = '''
|
||||||
@ -26,7 +17,7 @@ Additional = '''
|
|||||||
|
|
||||||
Application key and secret can be created by following the [OVH guide](https://docs.ovh.com/gb/en/customer/first-steps-with-ovh-api/).
|
Application key and secret can be created by following the [OVH guide](https://docs.ovh.com/gb/en/customer/first-steps-with-ovh-api/).
|
||||||
|
|
||||||
When requesting the consumer key, the following configuration can be used to define access rights:
|
When requesting the consumer key, the following configuration can be use to define access rights:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -42,32 +33,14 @@ 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 (Application Key authentication)"
|
OVH_APPLICATION_KEY = "Application key"
|
||||||
OVH_APPLICATION_SECRET = "Application secret (Application Key authentication)"
|
OVH_APPLICATION_SECRET = "Application secret"
|
||||||
OVH_CONSUMER_KEY = "Consumer key (Application Key authentication)"
|
OVH_CONSUMER_KEY = "Consumer key"
|
||||||
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
228
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/internal/client.go
generated
vendored
@ -1,228 +0,0 @@
|
|||||||
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
48
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/internal/types.go
generated
vendored
@ -1,48 +0,0 @@
|
|||||||
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
228
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/pdns.go
generated
vendored
@ -1,228 +0,0 @@
|
|||||||
// 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
37
vendor/github.com/go-acme/lego/v4/providers/dns/pdns/pdns.toml
generated
vendored
@ -1,37 +0,0 @@
|
|||||||
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,8 +9,6 @@ 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.
|
||||||
@ -54,7 +52,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)
|
||||||
@ -78,7 +76,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)
|
||||||
@ -130,7 +128,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
|
||||||
|
2
vendor/github.com/go-jose/go-jose/v4/.gitignore
generated
vendored
2
vendor/github.com/go-jose/go-jose/v4/.gitignore
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
jose-util/jose-util
|
|
||||||
jose-util.t.err
|
|
53
vendor/github.com/go-jose/go-jose/v4/.golangci.yml
generated
vendored
53
vendor/github.com/go-jose/go-jose/v4/.golangci.yml
generated
vendored
@ -1,53 +0,0 @@
|
|||||||
# https://github.com/golangci/golangci-lint
|
|
||||||
|
|
||||||
run:
|
|
||||||
skip-files:
|
|
||||||
- doc_test.go
|
|
||||||
modules-download-mode: readonly
|
|
||||||
|
|
||||||
linters:
|
|
||||||
enable-all: true
|
|
||||||
disable:
|
|
||||||
- gochecknoglobals
|
|
||||||
- goconst
|
|
||||||
- lll
|
|
||||||
- maligned
|
|
||||||
- nakedret
|
|
||||||
- scopelint
|
|
||||||
- unparam
|
|
||||||
- funlen # added in 1.18 (requires go-jose changes before it can be enabled)
|
|
||||||
|
|
||||||
linters-settings:
|
|
||||||
gocyclo:
|
|
||||||
min-complexity: 35
|
|
||||||
|
|
||||||
issues:
|
|
||||||
exclude-rules:
|
|
||||||
- text: "don't use ALL_CAPS in Go names"
|
|
||||||
linters:
|
|
||||||
- golint
|
|
||||||
- text: "hardcoded credentials"
|
|
||||||
linters:
|
|
||||||
- gosec
|
|
||||||
- text: "weak cryptographic primitive"
|
|
||||||
linters:
|
|
||||||
- gosec
|
|
||||||
- path: json/
|
|
||||||
linters:
|
|
||||||
- dupl
|
|
||||||
- errcheck
|
|
||||||
- gocritic
|
|
||||||
- gocyclo
|
|
||||||
- golint
|
|
||||||
- govet
|
|
||||||
- ineffassign
|
|
||||||
- staticcheck
|
|
||||||
- structcheck
|
|
||||||
- stylecheck
|
|
||||||
- unused
|
|
||||||
- path: _test\.go
|
|
||||||
linters:
|
|
||||||
- scopelint
|
|
||||||
- path: jwk.go
|
|
||||||
linters:
|
|
||||||
- gocyclo
|
|
33
vendor/github.com/go-jose/go-jose/v4/.travis.yml
generated
vendored
33
vendor/github.com/go-jose/go-jose/v4/.travis.yml
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
allow_failures:
|
|
||||||
- go: tip
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "1.13.x"
|
|
||||||
- "1.14.x"
|
|
||||||
- tip
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export PATH=$HOME/.local/bin:$PATH
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge
|
|
||||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0
|
|
||||||
- pip install cram --user
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test -v -covermode=count -coverprofile=profile.cov .
|
|
||||||
- go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner
|
|
||||||
- go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher
|
|
||||||
- go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt
|
|
||||||
- go test -v ./json # no coverage for forked encoding/json package
|
|
||||||
- golangci-lint run
|
|
||||||
- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util
|
|
||||||
- cd ..
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- gocovmerge *.cov */*.cov > merged.coverprofile
|
|
||||||
- goveralls -coverprofile merged.coverprofile -service=travis-ci
|
|
96
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
generated
vendored
96
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
generated
vendored
@ -1,96 +0,0 @@
|
|||||||
# 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
|
|
13
vendor/github.com/go-jose/go-jose/v4/SECURITY.md
generated
vendored
13
vendor/github.com/go-jose/go-jose/v4/SECURITY.md
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
# 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.
|
|
3
vendor/github.com/goccy/go-json/.golangci.yml
generated
vendored
3
vendor/github.com/goccy/go-json/.golangci.yml
generated
vendored
@ -56,9 +56,6 @@ linters:
|
|||||||
- cyclop
|
- cyclop
|
||||||
- containedctx
|
- containedctx
|
||||||
- revive
|
- revive
|
||||||
- nosnakecase
|
|
||||||
- exhaustruct
|
|
||||||
- depguard
|
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
|
32
vendor/github.com/goccy/go-json/CHANGELOG.md
generated
vendored
32
vendor/github.com/goccy/go-json/CHANGELOG.md
generated
vendored
@ -1,35 +1,3 @@
|
|||||||
# v0.10.2 - 2023/03/20
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
* Support DebugDOT option for debugging encoder ( #440 )
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix combination of embedding structure and omitempty option ( #442 )
|
|
||||||
|
|
||||||
# v0.10.1 - 2023/03/13
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix checkptr error for array decoder ( #415 )
|
|
||||||
* Fix added buffer size check when decoding key ( #430 )
|
|
||||||
* Fix handling of anonymous fields other than struct ( #431 )
|
|
||||||
* Fix to not optimize when lower conversion can't handle byte-by-byte ( #432 )
|
|
||||||
* Fix a problem that MarshalIndent does not work when UnorderedMap is specified ( #435 )
|
|
||||||
* Fix mapDecoder.DecodeStream() for empty objects containing whitespace ( #425 )
|
|
||||||
* Fix an issue that could not set the correct NextField for fields in the embedded structure ( #438 )
|
|
||||||
|
|
||||||
# v0.10.0 - 2022/11/29
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
* Support JSON Path ( #250 )
|
|
||||||
|
|
||||||
### Fix bugs
|
|
||||||
|
|
||||||
* Fix marshaler for map's key ( #409 )
|
|
||||||
|
|
||||||
# v0.9.11 - 2022/08/18
|
# v0.9.11 - 2022/08/18
|
||||||
|
|
||||||
### Fix bugs
|
### Fix bugs
|
||||||
|
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.54.2; \
|
GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0; \
|
||||||
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...) //nolint: contextcheck
|
err := e.encodeWithOption(rctx, v, optFuncs...)
|
||||||
|
|
||||||
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) //nolint: contextcheck
|
buf, err := encode(rctx, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
encoder.ReleaseRuntimeContext(rctx)
|
encoder.ReleaseRuntimeContext(rctx)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
4
vendor/github.com/goccy/go-json/internal/decoder/array.go
generated
vendored
4
vendor/github.com/goccy/go-json/internal/decoder/array.go
generated
vendored
@ -19,9 +19,7 @@ type arrayDecoder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
|
func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
|
||||||
// workaround to avoid checkptr errors. cannot use `*(*unsafe.Pointer)(unsafe_New(elemType))` directly.
|
zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType))
|
||||||
zeroValuePtr := unsafe_New(elemType)
|
|
||||||
zeroValue := **(**unsafe.Pointer)(unsafe.Pointer(&zeroValuePtr))
|
|
||||||
return &arrayDecoder{
|
return &arrayDecoder{
|
||||||
valueDecoder: dec,
|
valueDecoder: dec,
|
||||||
elemType: elemType,
|
elemType: elemType,
|
||||||
|
2
vendor/github.com/goccy/go-json/internal/decoder/map.go
generated
vendored
2
vendor/github.com/goccy/go-json/internal/decoder/map.go
generated
vendored
@ -88,7 +88,7 @@ func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
|
|||||||
mapValue = makemap(d.mapType, 0)
|
mapValue = makemap(d.mapType, 0)
|
||||||
}
|
}
|
||||||
s.cursor++
|
s.cursor++
|
||||||
if s.skipWhiteSpace() == '}' {
|
if s.equalChar('}') {
|
||||||
*(*unsafe.Pointer)(p) = mapValue
|
*(*unsafe.Pointer)(p) = mapValue
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return nil
|
return nil
|
||||||
|
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,7 +85,6 @@ 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
|
||||||
|
54
vendor/github.com/goccy/go-json/internal/decoder/struct.go
generated
vendored
54
vendor/github.com/goccy/go-json/internal/decoder/struct.go
generated
vendored
@ -51,14 +51,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toASCIILower(s string) string {
|
|
||||||
b := []byte(s)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = largeToSmallTable[b[i]]
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder {
|
func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder {
|
||||||
return &structDecoder{
|
return &structDecoder{
|
||||||
fieldMap: fieldMap,
|
fieldMap: fieldMap,
|
||||||
@ -99,10 +91,6 @@ func (d *structDecoder) tryOptimize() {
|
|||||||
for k, v := range d.fieldMap {
|
for k, v := range d.fieldMap {
|
||||||
key := strings.ToLower(k)
|
key := strings.ToLower(k)
|
||||||
if key != k {
|
if key != k {
|
||||||
if key != toASCIILower(k) {
|
|
||||||
d.isTriedOptimize = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// already exists same key (e.g. Hello and HELLO has same lower case key
|
// already exists same key (e.g. Hello and HELLO has same lower case key
|
||||||
if _, exists := conflicted[key]; exists {
|
if _, exists := conflicted[key]; exists {
|
||||||
d.isTriedOptimize = true
|
d.isTriedOptimize = true
|
||||||
@ -170,53 +158,49 @@ func (d *structDecoder) tryOptimize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decode from '\uXXXX'
|
// decode from '\uXXXX'
|
||||||
func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64, error) {
|
func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64) {
|
||||||
const defaultOffset = 4
|
const defaultOffset = 4
|
||||||
const surrogateOffset = 6
|
const surrogateOffset = 6
|
||||||
|
|
||||||
if cursor+defaultOffset >= int64(len(buf)) {
|
|
||||||
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
r := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
||||||
if utf16.IsSurrogate(r) {
|
if utf16.IsSurrogate(r) {
|
||||||
cursor += defaultOffset
|
cursor += defaultOffset
|
||||||
if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
|
if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
|
||||||
return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1, nil
|
return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1
|
||||||
}
|
}
|
||||||
cursor += 2
|
cursor += 2
|
||||||
r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
|
||||||
if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
|
if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
|
||||||
return []byte(string(r)), cursor + defaultOffset - 1, nil
|
return []byte(string(r)), cursor + defaultOffset - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []byte(string(r)), cursor + defaultOffset - 1, nil
|
return []byte(string(r)), cursor + defaultOffset - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error) {
|
func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64) {
|
||||||
c := buf[cursor]
|
c := buf[cursor]
|
||||||
cursor++
|
cursor++
|
||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
return []byte{'"'}, cursor, nil
|
return []byte{'"'}, cursor
|
||||||
case '\\':
|
case '\\':
|
||||||
return []byte{'\\'}, cursor, nil
|
return []byte{'\\'}, cursor
|
||||||
case '/':
|
case '/':
|
||||||
return []byte{'/'}, cursor, nil
|
return []byte{'/'}, cursor
|
||||||
case 'b':
|
case 'b':
|
||||||
return []byte{'\b'}, cursor, nil
|
return []byte{'\b'}, cursor
|
||||||
case 'f':
|
case 'f':
|
||||||
return []byte{'\f'}, cursor, nil
|
return []byte{'\f'}, cursor
|
||||||
case 'n':
|
case 'n':
|
||||||
return []byte{'\n'}, cursor, nil
|
return []byte{'\n'}, cursor
|
||||||
case 'r':
|
case 'r':
|
||||||
return []byte{'\r'}, cursor, nil
|
return []byte{'\r'}, cursor
|
||||||
case 't':
|
case 't':
|
||||||
return []byte{'\t'}, cursor, nil
|
return []byte{'\t'}, cursor
|
||||||
case 'u':
|
case 'u':
|
||||||
return decodeKeyCharByUnicodeRune(buf, cursor)
|
return decodeKeyCharByUnicodeRune(buf, cursor)
|
||||||
}
|
}
|
||||||
return nil, cursor, nil
|
return nil, cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
||||||
@ -258,10 +242,7 @@ func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64,
|
|||||||
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
||||||
case '\\':
|
case '\\':
|
||||||
cursor++
|
cursor++
|
||||||
chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
|
chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
|
||||||
for _, c := range chars {
|
for _, c := range chars {
|
||||||
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
||||||
if curBit == 0 {
|
if curBit == 0 {
|
||||||
@ -324,10 +305,7 @@ func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64,
|
|||||||
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
|
||||||
case '\\':
|
case '\\':
|
||||||
cursor++
|
cursor++
|
||||||
chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
|
chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
|
||||||
for _, c := range chars {
|
for _, c := range chars {
|
||||||
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
|
||||||
if curBit == 0 {
|
if curBit == 0 {
|
||||||
|
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) { //nolint: nonamedreturns
|
func unquoteBytes(s []byte) (t []byte, ok bool) {
|
||||||
length := len(s)
|
length := len(s)
|
||||||
if length < 2 || s[0] != '"' || s[length-1] != '"' {
|
if length < 2 || s[0] != '"' || s[length-1] != '"' {
|
||||||
return
|
return
|
||||||
|
20
vendor/github.com/goccy/go-json/internal/encoder/code.go
generated
vendored
20
vendor/github.com/goccy/go-json/internal/encoder/code.go
generated
vendored
@ -397,10 +397,7 @@ func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *
|
|||||||
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
||||||
// firstField is special StructHead operation for anonymous structure.
|
// firstField is special StructHead operation for anonymous structure.
|
||||||
// So, StructHead's next operation is truly struct head operation.
|
// So, StructHead's next operation is truly struct head operation.
|
||||||
for firstField.Op == OpStructHead || firstField.Op == OpStructField {
|
lastField := firstField.Next
|
||||||
firstField = firstField.Next
|
|
||||||
}
|
|
||||||
lastField := firstField
|
|
||||||
for lastField.NextField != nil {
|
for lastField.NextField != nil {
|
||||||
lastField = lastField.NextField
|
lastField = lastField.NextField
|
||||||
}
|
}
|
||||||
@ -440,6 +437,11 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
|||||||
}
|
}
|
||||||
if isEndField {
|
if isEndField {
|
||||||
endField := fieldCodes.Last()
|
endField := fieldCodes.Last()
|
||||||
|
if isEmbeddedStruct(field) {
|
||||||
|
firstField.End = endField
|
||||||
|
lastField := c.lastAnonymousFieldCode(firstField)
|
||||||
|
lastField.NextField = endField
|
||||||
|
}
|
||||||
if len(codes) > 0 {
|
if len(codes) > 0 {
|
||||||
codes.First().End = endField
|
codes.First().End = endField
|
||||||
} else {
|
} else {
|
||||||
@ -696,15 +698,7 @@ func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) O
|
|||||||
Indent: ctx.indent,
|
Indent: ctx.indent,
|
||||||
}
|
}
|
||||||
codes.Last().Next = end
|
codes.Last().Next = end
|
||||||
code := codes.First()
|
codes.First().NextField = end
|
||||||
for code.Op == OpStructField || code.Op == OpStructHead {
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
for code.NextField != nil {
|
|
||||||
code = code.NextField
|
|
||||||
}
|
|
||||||
code.NextField = end
|
|
||||||
|
|
||||||
codes = codes.Add(end)
|
codes = codes.Add(end)
|
||||||
ctx.incOpcodeIndex()
|
ctx.incOpcodeIndex()
|
||||||
return codes
|
return codes
|
||||||
|
2
vendor/github.com/goccy/go-json/internal/encoder/compact.go
generated
vendored
2
vendor/github.com/goccy/go-json/internal/encoder/compact.go
generated
vendored
@ -213,8 +213,8 @@ func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, e
|
|||||||
dst = append(dst, src[start:cursor]...)
|
dst = append(dst, src[start:cursor]...)
|
||||||
dst = append(dst, `\u202`...)
|
dst = append(dst, `\u202`...)
|
||||||
dst = append(dst, hex[src[cursor+2]&0xF])
|
dst = append(dst, hex[src[cursor+2]&0xF])
|
||||||
start = cursor + 3
|
|
||||||
cursor += 2
|
cursor += 2
|
||||||
|
start = cursor + 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch c {
|
switch c {
|
||||||
|
11
vendor/github.com/goccy/go-json/internal/encoder/compiler.go
generated
vendored
11
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.implementsMarshalJSONType(typ) || c.implementsMarshalJSONType(runtime.PtrTo(typ)):
|
case c.isPtrMarshalJSONType(typ):
|
||||||
return c.marshalJSONCode(typ)
|
return c.marshalJSONCode(typ)
|
||||||
case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType):
|
case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType):
|
||||||
return c.marshalTextCode(typ)
|
return c.marshalTextCode(typ)
|
||||||
@ -617,13 +617,6 @@ func (c *Compiler) structCode(typ *runtime.Type, isPtr bool) (*StructCode, error
|
|||||||
return code, nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toElemType(t *runtime.Type) *runtime.Type {
|
|
||||||
for t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) {
|
func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) {
|
||||||
field := tag.Field
|
field := tag.Field
|
||||||
fieldType := runtime.Type2RType(field.Type)
|
fieldType := runtime.Type2RType(field.Type)
|
||||||
@ -633,7 +626,7 @@ func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTa
|
|||||||
key: tag.Key,
|
key: tag.Key,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
offset: field.Offset,
|
offset: field.Offset,
|
||||||
isAnonymous: field.Anonymous && !tag.IsTaggedKey && toElemType(fieldType).Kind() == reflect.Struct,
|
isAnonymous: field.Anonymous && !tag.IsTaggedKey,
|
||||||
isTaggedKey: tag.IsTaggedKey,
|
isTaggedKey: tag.IsTaggedKey,
|
||||||
isNilableType: c.isNilableType(fieldType),
|
isNilableType: c.isNilableType(fieldType),
|
||||||
isNilCheck: true,
|
isNilCheck: true,
|
||||||
|
24
vendor/github.com/goccy/go-json/internal/encoder/int.go
generated
vendored
24
vendor/github.com/goccy/go-json/internal/encoder/int.go
generated
vendored
@ -1,27 +1,3 @@
|
|||||||
// This files's processing codes are inspired by https://github.com/segmentio/encoding.
|
|
||||||
// The license notation is as follows.
|
|
||||||
//
|
|
||||||
// # MIT License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2019 Segment.io, Inc.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
83
vendor/github.com/goccy/go-json/internal/encoder/opcode.go
generated
vendored
83
vendor/github.com/goccy/go-json/internal/encoder/opcode.go
generated
vendored
@ -1,9 +1,7 @@
|
|||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -557,87 +555,6 @@ func (c *Opcode) Dump() string {
|
|||||||
return strings.Join(codes, "\n")
|
return strings.Join(codes, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Opcode) DumpDOT() string {
|
|
||||||
type edge struct {
|
|
||||||
from, to *Opcode
|
|
||||||
label string
|
|
||||||
weight int
|
|
||||||
}
|
|
||||||
var edges []edge
|
|
||||||
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(b, "digraph \"%p\" {\n", c.Type)
|
|
||||||
fmt.Fprintln(b, "mclimit=1.5;\nrankdir=TD;\nordering=out;\nnode[shape=box];")
|
|
||||||
for code := c; !code.IsEnd(); {
|
|
||||||
label := code.Op.String()
|
|
||||||
fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, label)
|
|
||||||
if p := code.Next; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p,
|
|
||||||
label: "Next",
|
|
||||||
weight: 10,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if p := code.NextField; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p,
|
|
||||||
label: "NextField",
|
|
||||||
weight: 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if p := code.End; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p,
|
|
||||||
label: "End",
|
|
||||||
weight: 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if p := code.Jmp; p != nil {
|
|
||||||
edges = append(edges, edge{
|
|
||||||
from: code,
|
|
||||||
to: p.Code,
|
|
||||||
label: "Jmp",
|
|
||||||
weight: 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
switch code.Op.CodeType() {
|
|
||||||
case CodeSliceHead:
|
|
||||||
code = code.Next
|
|
||||||
case CodeMapHead:
|
|
||||||
code = code.Next
|
|
||||||
case CodeArrayElem, CodeSliceElem:
|
|
||||||
code = code.End
|
|
||||||
case CodeMapKey:
|
|
||||||
code = code.End
|
|
||||||
case CodeMapValue:
|
|
||||||
code = code.Next
|
|
||||||
case CodeMapEnd:
|
|
||||||
code = code.Next
|
|
||||||
case CodeStructField:
|
|
||||||
code = code.Next
|
|
||||||
case CodeStructEnd:
|
|
||||||
code = code.Next
|
|
||||||
default:
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
if code.IsEnd() {
|
|
||||||
fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, code.Op.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Slice(edges, func(i, j int) bool {
|
|
||||||
return edges[i].to.DisplayIdx < edges[j].to.DisplayIdx
|
|
||||||
})
|
|
||||||
for _, e := range edges {
|
|
||||||
fmt.Fprintf(b, "\"%p\" -> \"%p\" [label=%q][weight=%d];\n", e.from, e.to, e.label, e.weight)
|
|
||||||
}
|
|
||||||
fmt.Fprint(b, "}")
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
|
func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
|
||||||
idx := opcodeOffset(ctx.ptrIndex)
|
idx := opcodeOffset(ctx.ptrIndex)
|
||||||
ctx.incPtrIndex()
|
ctx.incPtrIndex()
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/encoder/option.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/encoder/option.go
generated
vendored
@ -23,7 +23,6 @@ type Option struct {
|
|||||||
ColorScheme *ColorScheme
|
ColorScheme *ColorScheme
|
||||||
Context context.Context
|
Context context.Context
|
||||||
DebugOut io.Writer
|
DebugOut io.Writer
|
||||||
DebugDOTOut io.WriteCloser
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EncodeFormat struct {
|
type EncodeFormat struct {
|
||||||
|
24
vendor/github.com/goccy/go-json/internal/encoder/string.go
generated
vendored
24
vendor/github.com/goccy/go-json/internal/encoder/string.go
generated
vendored
@ -1,27 +1,3 @@
|
|||||||
// This files's string processing codes are inspired by https://github.com/segmentio/encoding.
|
|
||||||
// The license notation is as follows.
|
|
||||||
//
|
|
||||||
// # MIT License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2019 Segment.io, Inc.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
package encoder
|
package encoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
6
vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go
generated
vendored
6
vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go
generated
vendored
@ -2,7 +2,6 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/goccy/go-json/internal/encoder"
|
"github.com/goccy/go-json/internal/encoder"
|
||||||
)
|
)
|
||||||
@ -15,11 +14,6 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet)
|
|||||||
} else {
|
} else {
|
||||||
code = codeSet.NoescapeKeyCode
|
code = codeSet.NoescapeKeyCode
|
||||||
}
|
}
|
||||||
if wc := ctx.Option.DebugDOTOut; wc != nil {
|
|
||||||
_, _ = io.WriteString(wc, code.DumpDOT())
|
|
||||||
wc.Close()
|
|
||||||
ctx.Option.DebugDOTOut = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
w := ctx.Option.DebugOut
|
w := ctx.Option.DebugOut
|
||||||
|
7
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go
generated
vendored
7
vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go
generated
vendored
@ -189,7 +189,7 @@ func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
||||||
return append(b[:len(b)-2], ':', ' ')
|
return append(b, ':', ' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
||||||
@ -229,9 +229,8 @@ func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
|
|
||||||
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
||||||
last := len(b) - 1
|
last := len(b) - 1
|
||||||
// replace comma to newline
|
b[last] = '\n'
|
||||||
b[last-1] = '\n'
|
b = appendIndent(ctx, b, code.Indent-1)
|
||||||
b = appendIndent(ctx, b[:last], code.Indent)
|
|
||||||
return append(b, '}', ',', '\n')
|
return append(b, '}', ',', '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go
generated
vendored
7
vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go
generated
vendored
@ -133,7 +133,7 @@ func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
|
||||||
return append(b[:len(b)-2], ':', ' ')
|
return append(b, ':', ' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
|
||||||
@ -173,9 +173,8 @@ func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
|
|||||||
|
|
||||||
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
|
||||||
last := len(b) - 1
|
last := len(b) - 1
|
||||||
// replace comma to newline
|
b[last] = '\n'
|
||||||
b[last-1] = '\n'
|
b = appendIndent(ctx, b, code.Indent-1)
|
||||||
b = appendIndent(ctx, b[:last], code.Indent)
|
|
||||||
return append(b, '}', ',', '\n')
|
return append(b, '}', ',', '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
vendor/github.com/goccy/go-json/internal/runtime/rtype.go
generated
vendored
1
vendor/github.com/goccy/go-json/internal/runtime/rtype.go
generated
vendored
@ -252,6 +252,7 @@ func IfaceIndir(*Type) bool
|
|||||||
//go:noescape
|
//go:noescape
|
||||||
func RType2Type(t *Type) reflect.Type
|
func RType2Type(t *Type) reflect.Type
|
||||||
|
|
||||||
|
//go:nolint structcheck
|
||||||
type emptyInterface struct {
|
type emptyInterface struct {
|
||||||
_ *Type
|
_ *Type
|
||||||
ptr unsafe.Pointer
|
ptr unsafe.Pointer
|
||||||
|
5
vendor/github.com/goccy/go-json/json.go
generated
vendored
5
vendor/github.com/goccy/go-json/json.go
generated
vendored
@ -166,6 +166,7 @@ type UnmarshalerContext interface {
|
|||||||
// JSON cannot represent cyclic data structures and Marshal does not
|
// JSON cannot represent cyclic data structures and Marshal does not
|
||||||
// handle them. Passing cyclic structures to Marshal will result in
|
// handle them. Passing cyclic structures to Marshal will result in
|
||||||
// an infinite recursion.
|
// an infinite recursion.
|
||||||
|
//
|
||||||
func Marshal(v interface{}) ([]byte, error) {
|
func Marshal(v interface{}) ([]byte, error) {
|
||||||
return MarshalWithOption(v)
|
return MarshalWithOption(v)
|
||||||
}
|
}
|
||||||
@ -263,13 +264,14 @@ func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...E
|
|||||||
//
|
//
|
||||||
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
||||||
// by setting that Go value to nil. Because null is often used in JSON to mean
|
// by setting that Go value to nil. Because null is often used in JSON to mean
|
||||||
// “not present,” unmarshaling a JSON null into any other Go type has no effect
|
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
|
||||||
// on the value and produces no error.
|
// on the value and produces no error.
|
||||||
//
|
//
|
||||||
// When unmarshaling quoted strings, invalid UTF-8 or
|
// When unmarshaling quoted strings, invalid UTF-8 or
|
||||||
// invalid UTF-16 surrogate pairs are not treated as an error.
|
// invalid UTF-16 surrogate pairs are not treated as an error.
|
||||||
// Instead, they are replaced by the Unicode replacement
|
// Instead, they are replaced by the Unicode replacement
|
||||||
// character U+FFFD.
|
// character U+FFFD.
|
||||||
|
//
|
||||||
func Unmarshal(data []byte, v interface{}) error {
|
func Unmarshal(data []byte, v interface{}) error {
|
||||||
return unmarshal(data, v)
|
return unmarshal(data, v)
|
||||||
}
|
}
|
||||||
@ -297,6 +299,7 @@ func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc)
|
|||||||
// Number, for JSON numbers
|
// Number, for JSON numbers
|
||||||
// string, for JSON string literals
|
// string, for JSON string literals
|
||||||
// nil, for JSON null
|
// nil, for JSON null
|
||||||
|
//
|
||||||
type Token = json.Token
|
type Token = json.Token
|
||||||
|
|
||||||
// A Number represents a JSON number literal.
|
// A Number represents a JSON number literal.
|
||||||
|
7
vendor/github.com/goccy/go-json/option.go
generated
vendored
7
vendor/github.com/goccy/go-json/option.go
generated
vendored
@ -48,13 +48,6 @@ func DebugWith(w io.Writer) EncodeOptionFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugDOT sets the destination to write opcodes graph.
|
|
||||||
func DebugDOT(w io.WriteCloser) EncodeOptionFunc {
|
|
||||||
return func(opt *EncodeOption) {
|
|
||||||
opt.DebugDOTOut = w
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Colorize add an identifier for coloring to the string of the encoded result.
|
// Colorize add an identifier for coloring to the string of the encoded result.
|
||||||
func Colorize(scheme *ColorScheme) EncodeOptionFunc {
|
func Colorize(scheme *ColorScheme) EncodeOptionFunc {
|
||||||
return func(opt *EncodeOption) {
|
return func(opt *EncodeOption) {
|
||||||
|
21
vendor/github.com/labstack/echo/v4/.travis.yml
generated
vendored
Normal file
21
vendor/github.com/labstack/echo/v4/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
arch:
|
||||||
|
- amd64
|
||||||
|
- ppc64le
|
||||||
|
|
||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.14.x
|
||||||
|
- 1.15.x
|
||||||
|
- tip
|
||||||
|
env:
|
||||||
|
- GO111MODULE=on
|
||||||
|
install:
|
||||||
|
- go get -v golang.org/x/lint/golint
|
||||||
|
script:
|
||||||
|
- golint -set_exit_status ./...
|
||||||
|
- go test -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
169
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
169
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,174 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v4.12.0 - 2024-04-15
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Update golang.org/x/net dep because of [GO-2024-2687](https://pkg.go.dev/vuln/GO-2024-2687) by @aldas in https://github.com/labstack/echo/pull/2625
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* binder: make binding to Map work better with string destinations by @aldas in https://github.com/labstack/echo/pull/2554
|
|
||||||
* README.md: add Encore as sponsor by @marcuskohlberg in https://github.com/labstack/echo/pull/2579
|
|
||||||
* Reorder paragraphs in README.md by @aldas in https://github.com/labstack/echo/pull/2581
|
|
||||||
* CI: upgrade actions/checkout to v4 by @aldas in https://github.com/labstack/echo/pull/2584
|
|
||||||
* Remove default charset from 'application/json' Content-Type header by @doortts in https://github.com/labstack/echo/pull/2568
|
|
||||||
* CI: Use Go 1.22 by @aldas in https://github.com/labstack/echo/pull/2588
|
|
||||||
* binder: allow binding to a nil map by @georgmu in https://github.com/labstack/echo/pull/2574
|
|
||||||
* Add Skipper Unit Test In BasicBasicAuthConfig and Add More Detail Explanation regarding BasicAuthValidator by @RyoKusnadi in https://github.com/labstack/echo/pull/2461
|
|
||||||
* fix some typos by @teslaedison in https://github.com/labstack/echo/pull/2603
|
|
||||||
* fix: some typos by @pomadev in https://github.com/labstack/echo/pull/2596
|
|
||||||
* Allow ResponseWriters to unwrap writers when flushing/hijacking by @aldas in https://github.com/labstack/echo/pull/2595
|
|
||||||
* Add SPDX licence comments to files. by @aldas in https://github.com/labstack/echo/pull/2604
|
|
||||||
* Upgrade deps by @aldas in https://github.com/labstack/echo/pull/2605
|
|
||||||
* Change type definition blocks to single declarations. This helps copy… by @aldas in https://github.com/labstack/echo/pull/2606
|
|
||||||
* Fix Real IP logic by @cl-bvl in https://github.com/labstack/echo/pull/2550
|
|
||||||
* Default binder can use `UnmarshalParams(params []string) error` inter… by @aldas in https://github.com/labstack/echo/pull/2607
|
|
||||||
* Default binder can bind pointer to slice as struct field. For example `*[]string` by @aldas in https://github.com/labstack/echo/pull/2608
|
|
||||||
* Remove maxparam dependence from Context by @aldas in https://github.com/labstack/echo/pull/2611
|
|
||||||
* When route is registered with empty path it is normalized to `/`. by @aldas in https://github.com/labstack/echo/pull/2616
|
|
||||||
* proxy middleware should use httputil.ReverseProxy for SSE requests by @aldas in https://github.com/labstack/echo/pull/2624
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.4 - 2023-12-20
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Upgrade golang.org/x/crypto to v0.17.0 to fix vulnerability [issue](https://pkg.go.dev/vuln/GO-2023-2402) [#2562](https://github.com/labstack/echo/pull/2562)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Update deps and mark Go version to 1.18 as this is what golang.org/x/* use [#2563](https://github.com/labstack/echo/pull/2563)
|
|
||||||
* Request logger: add example for Slog https://pkg.go.dev/log/slog [#2543](https://github.com/labstack/echo/pull/2543)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.3 - 2023-11-07
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* 'c.Attachment' and 'c.Inline' should escape filename in 'Content-Disposition' header to avoid 'Reflect File Download' vulnerability. [#2541](https://github.com/labstack/echo/pull/2541)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Tests: refactor context tests to be separate functions [#2540](https://github.com/labstack/echo/pull/2540)
|
|
||||||
* Proxy middleware: reuse echo request context [#2537](https://github.com/labstack/echo/pull/2537)
|
|
||||||
* Mark unmarshallable yaml struct tags as ignored [#2536](https://github.com/labstack/echo/pull/2536)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.2 - 2023-10-11
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Bump golang.org/x/net to prevent CVE-2023-39325 / CVE-2023-44487 HTTP/2 Rapid Reset Attack [#2527](https://github.com/labstack/echo/pull/2527)
|
|
||||||
* fix(sec): randomString bias introduced by #2490 [#2492](https://github.com/labstack/echo/pull/2492)
|
|
||||||
* CSRF/RequestID mw: switch math/random usage to crypto/random [#2490](https://github.com/labstack/echo/pull/2490)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Delete unused context in body_limit.go [#2483](https://github.com/labstack/echo/pull/2483)
|
|
||||||
* Use Go 1.21 in CI [#2505](https://github.com/labstack/echo/pull/2505)
|
|
||||||
* Fix some typos [#2511](https://github.com/labstack/echo/pull/2511)
|
|
||||||
* Allow CORS middleware to send Access-Control-Max-Age: 0 [#2518](https://github.com/labstack/echo/pull/2518)
|
|
||||||
* Bump dependancies [#2522](https://github.com/labstack/echo/pull/2522)
|
|
||||||
|
|
||||||
## v4.11.1 - 2023-07-16
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fix `Gzip` middleware not sending response code for no content responses (404, 301/302 redirects etc) [#2481](https://github.com/labstack/echo/pull/2481)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.11.0 - 2023-07-14
|
|
||||||
|
|
||||||
|
|
||||||
**Fixes**
|
|
||||||
|
|
||||||
* Fixes the proxy middleware concurrency issue of calling the Next() proxy target on Round Robin Balancer [#2409](https://github.com/labstack/echo/pull/2409)
|
|
||||||
* Fix `group.RouteNotFound` not working when group has attached middlewares [#2411](https://github.com/labstack/echo/pull/2411)
|
|
||||||
* Fix global error handler return error message when message is an error [#2456](https://github.com/labstack/echo/pull/2456)
|
|
||||||
* Do not use global timeNow variables [#2477](https://github.com/labstack/echo/pull/2477)
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Added a optional config variable to disable centralized error handler in recovery middleware [#2410](https://github.com/labstack/echo/pull/2410)
|
|
||||||
* refactor: use `strings.ReplaceAll` directly [#2424](https://github.com/labstack/echo/pull/2424)
|
|
||||||
* Add support for Go1.20 `http.rwUnwrapper` to Response struct [#2425](https://github.com/labstack/echo/pull/2425)
|
|
||||||
* Check whether is nil before invoking centralized error handling [#2429](https://github.com/labstack/echo/pull/2429)
|
|
||||||
* Proper colon support in `echo.Reverse` method [#2416](https://github.com/labstack/echo/pull/2416)
|
|
||||||
* Fix misuses of a vs an in documentation comments [#2436](https://github.com/labstack/echo/pull/2436)
|
|
||||||
* Add link to slog.Handler library for Echo logging into README.md [#2444](https://github.com/labstack/echo/pull/2444)
|
|
||||||
* In proxy middleware Support retries of failed proxy requests [#2414](https://github.com/labstack/echo/pull/2414)
|
|
||||||
* gofmt fixes to comments [#2452](https://github.com/labstack/echo/pull/2452)
|
|
||||||
* gzip response only if it exceeds a minimal length [#2267](https://github.com/labstack/echo/pull/2267)
|
|
||||||
* Upgrade packages [#2475](https://github.com/labstack/echo/pull/2475)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.10.2 - 2023-02-22
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* `filepath.Clean` behaviour has changed in Go 1.20 - adapt to it [#2406](https://github.com/labstack/echo/pull/2406)
|
|
||||||
* Add `middleware.CORSConfig.UnsafeWildcardOriginWithAllowCredentials` to make UNSAFE usages of wildcard origin + allow cretentials less likely [#2405](https://github.com/labstack/echo/pull/2405)
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Add more HTTP error values [#2277](https://github.com/labstack/echo/pull/2277)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.10.1 - 2023-02-19
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* Upgrade deps due to the latest golang.org/x/net vulnerability [#2402](https://github.com/labstack/echo/pull/2402)
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Add new JWT repository to the README [#2377](https://github.com/labstack/echo/pull/2377)
|
|
||||||
* Return an empty string for ctx.path if there is no registered path [#2385](https://github.com/labstack/echo/pull/2385)
|
|
||||||
* Add context timeout middleware [#2380](https://github.com/labstack/echo/pull/2380)
|
|
||||||
* Update link to jaegertracing [#2394](https://github.com/labstack/echo/pull/2394)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.10.0 - 2022-12-27
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
* We are deprecating JWT middleware in this repository. Please use https://github.com/labstack/echo-jwt instead.
|
|
||||||
|
|
||||||
JWT middleware is moved to separate repository to allow us to bump/upgrade version of JWT implementation (`github.com/golang-jwt/jwt`) we are using
|
|
||||||
which we can not do in Echo core because this would break backwards compatibility guarantees we try to maintain.
|
|
||||||
|
|
||||||
* This minor version bumps minimum Go version to 1.17 (from 1.16) due `golang.org/x/` packages we depend on. There are
|
|
||||||
several vulnerabilities fixed in these libraries.
|
|
||||||
|
|
||||||
Echo still tries to support last 4 Go versions but there are occasions we can not guarantee this promise.
|
|
||||||
|
|
||||||
|
|
||||||
**Enhancements**
|
|
||||||
|
|
||||||
* Bump x/text to 0.3.8 [#2305](https://github.com/labstack/echo/pull/2305)
|
|
||||||
* Bump dependencies and add notes about Go releases we support [#2336](https://github.com/labstack/echo/pull/2336)
|
|
||||||
* Add helper interface for ProxyBalancer interface [#2316](https://github.com/labstack/echo/pull/2316)
|
|
||||||
* Expose `middleware.CreateExtractors` function so we can use it from echo-contrib repository [#2338](https://github.com/labstack/echo/pull/2338)
|
|
||||||
* Refactor func(Context) error to HandlerFunc [#2315](https://github.com/labstack/echo/pull/2315)
|
|
||||||
* Improve function comments [#2329](https://github.com/labstack/echo/pull/2329)
|
|
||||||
* Add new method HTTPError.WithInternal [#2340](https://github.com/labstack/echo/pull/2340)
|
|
||||||
* Replace io/ioutil package usages [#2342](https://github.com/labstack/echo/pull/2342)
|
|
||||||
* Add staticcheck to CI flow [#2343](https://github.com/labstack/echo/pull/2343)
|
|
||||||
* Replace relative path determination from proprietary to std [#2345](https://github.com/labstack/echo/pull/2345)
|
|
||||||
* Remove square brackets from ipv6 addresses in XFF (X-Forwarded-For header) [#2182](https://github.com/labstack/echo/pull/2182)
|
|
||||||
* Add testcases for some BodyLimit middleware configuration options [#2350](https://github.com/labstack/echo/pull/2350)
|
|
||||||
* Additional configuration options for RequestLogger and Logger middleware [#2341](https://github.com/labstack/echo/pull/2341)
|
|
||||||
* Add route to request log [#2162](https://github.com/labstack/echo/pull/2162)
|
|
||||||
* GitHub Workflows security hardening [#2358](https://github.com/labstack/echo/pull/2358)
|
|
||||||
* Add govulncheck to CI and bump dependencies [#2362](https://github.com/labstack/echo/pull/2362)
|
|
||||||
* Fix rate limiter docs [#2366](https://github.com/labstack/echo/pull/2366)
|
|
||||||
* Refactor how `e.Routes()` work and introduce `e.OnAddRouteHandler` callback [#2337](https://github.com/labstack/echo/pull/2337)
|
|
||||||
|
|
||||||
|
|
||||||
## v4.9.1 - 2022-10-12
|
## v4.9.1 - 2022-10-12
|
||||||
|
|
||||||
**Fixes**
|
**Fixes**
|
||||||
|
6
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
6
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
@ -10,10 +10,8 @@ check: lint vet race ## Check project
|
|||||||
|
|
||||||
init:
|
init:
|
||||||
@go install golang.org/x/lint/golint@latest
|
@go install golang.org/x/lint/golint@latest
|
||||||
@go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
||||||
|
|
||||||
lint: ## Lint the files
|
lint: ## Lint the files
|
||||||
@staticcheck ${PKG_LIST}
|
|
||||||
@golint -set_exit_status ${PKG_LIST}
|
@golint -set_exit_status ${PKG_LIST}
|
||||||
|
|
||||||
vet: ## Vet the files
|
vet: ## Vet the files
|
||||||
@ -31,6 +29,6 @@ benchmark: ## Run benchmarks
|
|||||||
help: ## Display this help screen
|
help: ## Display this help screen
|
||||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
goversion ?= "1.19"
|
goversion ?= "1.16"
|
||||||
test_version: ## Run tests inside Docker with given version (defaults to 1.19 oldest supported). Example: make test_version goversion=1.19
|
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.16
|
||||||
@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"
|
||||||
|
55
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
55
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
@ -3,24 +3,26 @@
|
|||||||
[![Sourcegraph](https://sourcegraph.com/github.com/labstack/echo/-/badge.svg?style=flat-square)](https://sourcegraph.com/github.com/labstack/echo?badge)
|
[![Sourcegraph](https://sourcegraph.com/github.com/labstack/echo/-/badge.svg?style=flat-square)](https://sourcegraph.com/github.com/labstack/echo?badge)
|
||||||
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/labstack/echo/v4)
|
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/labstack/echo/v4)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/labstack/echo?style=flat-square)](https://goreportcard.com/report/github.com/labstack/echo)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/labstack/echo?style=flat-square)](https://goreportcard.com/report/github.com/labstack/echo)
|
||||||
[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/labstack/echo/echo.yml?style=flat-square)](https://github.com/labstack/echo/actions)
|
[![Build Status](http://img.shields.io/travis/labstack/echo.svg?style=flat-square)](https://travis-ci.org/labstack/echo)
|
||||||
[![Codecov](https://img.shields.io/codecov/c/github/labstack/echo.svg?style=flat-square)](https://codecov.io/gh/labstack/echo)
|
[![Codecov](https://img.shields.io/codecov/c/github/labstack/echo.svg?style=flat-square)](https://codecov.io/gh/labstack/echo)
|
||||||
[![Forum](https://img.shields.io/badge/community-forum-00afd1.svg?style=flat-square)](https://github.com/labstack/echo/discussions)
|
[![Forum](https://img.shields.io/badge/community-forum-00afd1.svg?style=flat-square)](https://github.com/labstack/echo/discussions)
|
||||||
[![Twitter](https://img.shields.io/badge/twitter-@labstack-55acee.svg?style=flat-square)](https://twitter.com/labstack)
|
[![Twitter](https://img.shields.io/badge/twitter-@labstack-55acee.svg?style=flat-square)](https://twitter.com/labstack)
|
||||||
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/labstack/echo/master/LICENSE)
|
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/labstack/echo/master/LICENSE)
|
||||||
|
|
||||||
## Echo
|
## Supported Go versions
|
||||||
|
|
||||||
High performance, extensible, minimalist Go web framework.
|
Latest version of Echo supports last four Go major [releases](https://go.dev/doc/devel/release) and might work with older versions.
|
||||||
|
|
||||||
* [Official website](https://echo.labstack.com)
|
As of version 4.0.0, Echo is available as a [Go module](https://github.com/golang/go/wiki/Modules).
|
||||||
* [Quick start](https://echo.labstack.com/docs/quick-start)
|
Therefore a Go version capable of understanding /vN suffixed imports is required:
|
||||||
* [Middlewares](https://echo.labstack.com/docs/category/middleware)
|
|
||||||
|
|
||||||
Help and questions: [Github Discussions](https://github.com/labstack/echo/discussions)
|
|
||||||
|
|
||||||
|
|
||||||
### Feature Overview
|
Any of these versions will allow you to import Echo as `github.com/labstack/echo/v4` which is the recommended
|
||||||
|
way of using Echo going forward.
|
||||||
|
|
||||||
|
For older versions, please use the latest v3 tag.
|
||||||
|
|
||||||
|
## Feature Overview
|
||||||
|
|
||||||
- Optimized HTTP router which smartly prioritize routes
|
- Optimized HTTP router which smartly prioritize routes
|
||||||
- Build robust and scalable RESTful APIs
|
- Build robust and scalable RESTful APIs
|
||||||
@ -36,18 +38,6 @@ Help and questions: [Github Discussions](https://github.com/labstack/echo/discus
|
|||||||
- Automatic TLS via Let’s Encrypt
|
- Automatic TLS via Let’s Encrypt
|
||||||
- HTTP/2 support
|
- HTTP/2 support
|
||||||
|
|
||||||
## Sponsors
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<a href="https://encore.dev" style="display: inline-flex; align-items: center; gap: 10px">
|
|
||||||
<img src="https://user-images.githubusercontent.com/78424526/214602214-52e0483a-b5fc-4d4c-b03e-0b7b23e012df.svg" height="28px" alt="encore icon"></img>
|
|
||||||
<b>Encore – the platform for building Go-based cloud backends</b>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
Click [here](https://github.com/sponsors/labstack) for more information on sponsorship.
|
|
||||||
|
|
||||||
## Benchmarks
|
## Benchmarks
|
||||||
|
|
||||||
Date: 2020/11/11<br>
|
Date: 2020/11/11<br>
|
||||||
@ -67,7 +57,6 @@ The benchmarks above were run on an Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
|
|||||||
// go get github.com/labstack/echo/{version}
|
// go get github.com/labstack/echo/{version}
|
||||||
go get github.com/labstack/echo/v4
|
go get github.com/labstack/echo/v4
|
||||||
```
|
```
|
||||||
Latest version of Echo supports last four Go major [releases](https://go.dev/doc/devel/release) and might work with older versions.
|
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
@ -101,33 +90,25 @@ func hello(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Official middleware repositories
|
# Third-party middlewares
|
||||||
|
|
||||||
Following list of middleware is maintained by Echo team.
|
|
||||||
|
|
||||||
| Repository | Description |
|
| Repository | Description |
|
||||||
|------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [github.com/labstack/echo-jwt](https://github.com/labstack/echo-jwt) | [JWT](https://github.com/golang-jwt/jwt) middleware |
|
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
||||||
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](https://github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
|
||||||
|
|
||||||
# Third-party middleware repositories
|
|
||||||
|
|
||||||
Be careful when adding 3rd party middleware. Echo teams does not have time or manpower to guarantee safety and quality
|
|
||||||
of middlewares in this list.
|
|
||||||
|
|
||||||
| Repository | Description |
|
|
||||||
|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
||||||
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
||||||
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
||||||
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
||||||
| [github.com/samber/slog-echo](https://github.com/samber/slog-echo) | Go [slog](https://pkg.go.dev/golang.org/x/exp/slog) logging library wrapper for Echo logger interface. |
|
|
||||||
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
||||||
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo. |
|
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo. |
|
||||||
| [github.com/go-woo/protoc-gen-echo](https://github.com/go-woo/protoc-gen-echo) | ProtoBuf generate Echo server side code |
|
| [github.com/go-woo/protoc-gen-echo](https://github.com/go-woo/protoc-gen-echo) | ProtoBuf generate Echo server side code |
|
||||||
|
|
||||||
Please send a PR to add your own library here.
|
Please send a PR to add your own library here.
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
|
- [Forum](https://github.com/labstack/echo/discussions)
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
**Use issues for everything**
|
**Use issues for everything**
|
||||||
|
124
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
124
vendor/github.com/labstack/echo/v4/bind.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -14,28 +11,23 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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.
|
||||||
type DefaultBinder struct{}
|
DefaultBinder struct{}
|
||||||
|
|
||||||
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
|
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
|
||||||
// Types that don't implement this, but do implement encoding.TextUnmarshaler
|
// Types that don't implement this, but do implement encoding.TextUnmarshaler
|
||||||
// will use that interface instead.
|
// will use that interface instead.
|
||||||
type BindUnmarshaler interface {
|
BindUnmarshaler interface {
|
||||||
// UnmarshalParam decodes and assigns a value from an form or query param.
|
// UnmarshalParam decodes and assigns a value from an form or query param.
|
||||||
UnmarshalParam(param string) error
|
UnmarshalParam(param string) error
|
||||||
}
|
}
|
||||||
|
)
|
||||||
// bindMultipleUnmarshaler is used by binder to unmarshal multiple values from request at once to
|
|
||||||
// type implementing this interface. For example request could have multiple query fields `?a=1&a=2&b=test` in that case
|
|
||||||
// for `a` following slice `["1", "2"] will be passed to unmarshaller.
|
|
||||||
type bindMultipleUnmarshaler interface {
|
|
||||||
UnmarshalParams(params []string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// BindPathParams binds path params to bindable object
|
// BindPathParams binds path params to bindable object
|
||||||
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
|
||||||
@ -139,29 +131,10 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
typ := reflect.TypeOf(destination).Elem()
|
typ := reflect.TypeOf(destination).Elem()
|
||||||
val := reflect.ValueOf(destination).Elem()
|
val := reflect.ValueOf(destination).Elem()
|
||||||
|
|
||||||
// Support binding to limited Map destinations:
|
// Map
|
||||||
// - map[string][]string,
|
if typ.Kind() == reflect.Map {
|
||||||
// - map[string]string <-- (binds first value from data slice)
|
|
||||||
// - map[string]interface{}
|
|
||||||
// You are better off binding to struct but there are user who want this map feature. Source of data for these cases are:
|
|
||||||
// params,query,header,form as these sources produce string values, most of the time slice of strings, actually.
|
|
||||||
if typ.Kind() == reflect.Map && typ.Key().Kind() == reflect.String {
|
|
||||||
k := typ.Elem().Kind()
|
|
||||||
isElemInterface := k == reflect.Interface
|
|
||||||
isElemString := k == reflect.String
|
|
||||||
isElemSliceOfStrings := k == reflect.Slice && typ.Elem().Elem().Kind() == reflect.String
|
|
||||||
if !(isElemSliceOfStrings || isElemString || isElemInterface) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if val.IsNil() {
|
|
||||||
val.Set(reflect.MakeMap(typ))
|
|
||||||
}
|
|
||||||
for k, v := range data {
|
for k, v := range data {
|
||||||
if isElemString {
|
|
||||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
|
||||||
} else {
|
|
||||||
val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -188,14 +161,14 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
}
|
}
|
||||||
structFieldKind := structField.Kind()
|
structFieldKind := structField.Kind()
|
||||||
inputFieldName := typeField.Tag.Get(tag)
|
inputFieldName := typeField.Tag.Get(tag)
|
||||||
if typeField.Anonymous && structFieldKind == reflect.Struct && inputFieldName != "" {
|
if typeField.Anonymous && structField.Kind() == reflect.Struct && inputFieldName != "" {
|
||||||
// if anonymous struct with query/param/form tags, report an error
|
// if anonymous struct with query/param/form tags, report an error
|
||||||
return errors.New("query/param/form tags are not allowed with anonymous struct field")
|
return errors.New("query/param/form tags are not allowed with anonymous struct field")
|
||||||
}
|
}
|
||||||
|
|
||||||
if inputFieldName == "" {
|
if inputFieldName == "" {
|
||||||
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
||||||
// structs that implement BindUnmarshaler are bound only when they have explicit tag
|
// structs that implement BindUnmarshaler are binded only when they have explicit tag
|
||||||
if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
|
if _, ok := structField.Addr().Interface().(BindUnmarshaler); !ok && structFieldKind == reflect.Struct {
|
||||||
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
|
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -224,46 +197,27 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: algorithm here is not particularly sophisticated. It probably does not work with absurd types like `**[]*int`
|
// Call this first, in case we're dealing with an alias to an array type
|
||||||
// but it is smart enough to handle niche cases like `*int`,`*[]string`,`[]*int` .
|
if ok, err := unmarshalField(typeField.Type.Kind(), inputValue[0], structField); ok {
|
||||||
|
|
||||||
// try unmarshalling first, in case we're dealing with an alias to an array type
|
|
||||||
if ok, err := unmarshalInputsToField(typeField.Type.Kind(), inputValue, structField); ok {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok, err := unmarshalInputToField(typeField.Type.Kind(), inputValue[0], structField); ok {
|
|
||||||
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()
|
|
||||||
numElems := len(inputValue)
|
numElems := len(inputValue)
|
||||||
|
if structFieldKind == reflect.Slice && numElems > 0 {
|
||||||
|
sliceOf := structField.Type().Elem().Kind()
|
||||||
slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
|
slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
|
||||||
for j := 0; j < numElems; j++ {
|
for j := 0; j < numElems; j++ {
|
||||||
if err := setWithProperType(sliceOf, inputValue[j], slice.Index(j)); err != nil {
|
if err := setWithProperType(sliceOf, inputValue[j], slice.Index(j)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
structField.Set(slice)
|
val.Field(i).Set(slice)
|
||||||
continue
|
} else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
if err := setWithProperType(structFieldKind, inputValue[0], structField); err != nil {
|
|
||||||
return err
|
return err
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -271,7 +225,7 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
|
|
||||||
func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error {
|
func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error {
|
||||||
// But also call it here, in case we're dealing with an array of BindUnmarshalers
|
// But also call it here, in case we're dealing with an array of BindUnmarshalers
|
||||||
if ok, err := unmarshalInputToField(valueKind, val, structField); ok {
|
if ok, err := unmarshalField(valueKind, val, structField); ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,41 +266,35 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalInputsToField(valueKind reflect.Kind, values []string, field reflect.Value) (bool, error) {
|
func unmarshalField(valueKind reflect.Kind, val string, field reflect.Value) (bool, error) {
|
||||||
if valueKind == reflect.Ptr {
|
switch valueKind {
|
||||||
if field.IsNil() {
|
case reflect.Ptr:
|
||||||
field.Set(reflect.New(field.Type().Elem()))
|
return unmarshalFieldPtr(val, field)
|
||||||
|
default:
|
||||||
|
return unmarshalFieldNonPtr(val, field)
|
||||||
}
|
}
|
||||||
field = field.Elem()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unmarshalFieldNonPtr(value string, field reflect.Value) (bool, error) {
|
||||||
fieldIValue := field.Addr().Interface()
|
fieldIValue := field.Addr().Interface()
|
||||||
unmarshaler, ok := fieldIValue.(bindMultipleUnmarshaler)
|
if unmarshaler, ok := fieldIValue.(BindUnmarshaler); ok {
|
||||||
if !ok {
|
return true, unmarshaler.UnmarshalParam(value)
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
return true, unmarshaler.UnmarshalParams(values)
|
if unmarshaler, ok := fieldIValue.(encoding.TextUnmarshaler); ok {
|
||||||
}
|
return true, unmarshaler.UnmarshalText([]byte(value))
|
||||||
|
|
||||||
func unmarshalInputToField(valueKind reflect.Kind, val string, field reflect.Value) (bool, error) {
|
|
||||||
if valueKind == reflect.Ptr {
|
|
||||||
if field.IsNil() {
|
|
||||||
field.Set(reflect.New(field.Type().Elem()))
|
|
||||||
}
|
|
||||||
field = field.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldIValue := field.Addr().Interface()
|
|
||||||
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"
|
||||||
|
21
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
21
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -1239,7 +1236,7 @@ func (b *ValueBinder) durations(sourceParam string, values []string, dest *[]tim
|
|||||||
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, time.Second)
|
return b.unixTime(sourceParam, dest, false, time.Second)
|
||||||
}
|
}
|
||||||
@ -1250,7 +1247,7 @@ func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder
|
|||||||
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, time.Second)
|
return b.unixTime(sourceParam, dest, true, time.Second)
|
||||||
}
|
}
|
||||||
@ -1260,7 +1257,7 @@ func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBi
|
|||||||
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) UnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, time.Millisecond)
|
return b.unixTime(sourceParam, dest, false, time.Millisecond)
|
||||||
}
|
}
|
||||||
@ -1271,7 +1268,7 @@ func (b *ValueBinder) UnixTimeMilli(sourceParam string, dest *time.Time) *ValueB
|
|||||||
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
func (b *ValueBinder) MustUnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, time.Millisecond)
|
return b.unixTime(sourceParam, dest, true, time.Millisecond)
|
||||||
}
|
}
|
||||||
@ -1283,8 +1280,8 @@ func (b *ValueBinder) MustUnixTimeMilli(sourceParam string, dest *time.Time) *Va
|
|||||||
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
// - Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||||
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, false, time.Nanosecond)
|
return b.unixTime(sourceParam, dest, false, time.Nanosecond)
|
||||||
}
|
}
|
||||||
@ -1297,8 +1294,8 @@ func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBi
|
|||||||
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
// Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00
|
||||||
//
|
//
|
||||||
// Note:
|
// Note:
|
||||||
// - time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||||
// - Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||||
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||||
return b.unixTime(sourceParam, dest, true, time.Nanosecond)
|
return b.unixTime(sourceParam, dest, true, time.Nanosecond)
|
||||||
}
|
}
|
||||||
@ -1326,7 +1323,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.UnixMilli(n)
|
*dest = time.Unix(n/1e3, (n%1e3)*1e6) // TODO: time.UnixMilli(n) exists since Go1.17 switch to that when min version allows
|
||||||
case time.Nanosecond:
|
case time.Nanosecond:
|
||||||
*dest = time.Unix(0, n)
|
*dest = time.Unix(0, n)
|
||||||
}
|
}
|
||||||
|
74
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
74
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -16,9 +13,10 @@ 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
|
||||||
|
|
||||||
@ -102,8 +100,8 @@ type Context interface {
|
|||||||
// Set saves data in the context.
|
// Set saves data in the context.
|
||||||
Set(key string, val interface{})
|
Set(key string, val interface{})
|
||||||
|
|
||||||
// Bind binds path params, query params and the request body into provided type `i`. The default binder
|
// Bind binds the request body into provided type `i`. The default binder
|
||||||
// binds body based on Content-Type header.
|
// does it based on Content-Type header.
|
||||||
Bind(i interface{}) error
|
Bind(i interface{}) error
|
||||||
|
|
||||||
// Validate validates provided `i`. It is usually called after `Context#Bind()`.
|
// Validate validates provided `i`. It is usually called after `Context#Bind()`.
|
||||||
@ -171,11 +169,7 @@ type Context interface {
|
|||||||
// Redirect redirects the request to a provided URL with status code.
|
// Redirect redirects the request to a provided URL with status code.
|
||||||
Redirect(code int, url string) error
|
Redirect(code int, url string) error
|
||||||
|
|
||||||
// Error invokes the registered global HTTP error handler. Generally used by middleware.
|
// Error invokes the registered HTTP error handler. Generally used by middleware.
|
||||||
// A side-effect of calling global error handler is that now Response has been committed (sent to the client) and
|
|
||||||
// middlewares up in chain can not change Response status code or Response body anymore.
|
|
||||||
//
|
|
||||||
// Avoid using this method in handlers as no middleware will be able to effectively handle errors after that.
|
|
||||||
Error(err error)
|
Error(err error)
|
||||||
|
|
||||||
// Handler returns the matched handler by router.
|
// Handler returns the matched handler by router.
|
||||||
@ -199,33 +193,20 @@ type Context interface {
|
|||||||
Reset(r *http.Request, w http.ResponseWriter)
|
Reset(r *http.Request, w http.ResponseWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
type context struct {
|
context struct {
|
||||||
request *http.Request
|
request *http.Request
|
||||||
response *Response
|
response *Response
|
||||||
|
path string
|
||||||
|
pnames []string
|
||||||
|
pvalues []string
|
||||||
query url.Values
|
query url.Values
|
||||||
|
handler HandlerFunc
|
||||||
|
store Map
|
||||||
echo *Echo
|
echo *Echo
|
||||||
logger Logger
|
logger Logger
|
||||||
|
|
||||||
store Map
|
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
||||||
// following fields are set by Router
|
|
||||||
|
|
||||||
// path is route path that Router matched. It is empty string where there is no route match.
|
|
||||||
// Route registered with RouteNotFound is considered as a match and path therefore is not empty.
|
|
||||||
path string
|
|
||||||
|
|
||||||
// pnames length is tied to param count for the matched route
|
|
||||||
pnames []string
|
|
||||||
|
|
||||||
// Usually echo.Echo is sizing pvalues but there could be user created middlewares that decide to
|
|
||||||
// overwrite parameter by calling SetParamNames + SetParamValues.
|
|
||||||
// When echo.Echo allocated that slice it length/capacity is tied to echo.Echo.maxParam value.
|
|
||||||
//
|
|
||||||
// It is important that pvalues size is always equal or bigger to pnames length.
|
|
||||||
pvalues []string
|
|
||||||
handler HandlerFunc
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
|
// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
|
||||||
@ -301,16 +282,11 @@ func (c *context) RealIP() string {
|
|||||||
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
|
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
|
||||||
i := strings.IndexAny(ip, ",")
|
i := strings.IndexAny(ip, ",")
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
xffip := strings.TrimSpace(ip[:i])
|
return strings.TrimSpace(ip[:i])
|
||||||
xffip = strings.TrimPrefix(xffip, "[")
|
|
||||||
xffip = strings.TrimSuffix(xffip, "]")
|
|
||||||
return xffip
|
|
||||||
}
|
}
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
|
if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
|
||||||
ip = strings.TrimPrefix(ip, "[")
|
|
||||||
ip = strings.TrimSuffix(ip, "]")
|
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
ra, _, _ := net.SplitHostPort(c.request.RemoteAddr)
|
ra, _, _ := net.SplitHostPort(c.request.RemoteAddr)
|
||||||
@ -344,9 +320,13 @@ func (c *context) SetParamNames(names ...string) {
|
|||||||
c.pnames = names
|
c.pnames = names
|
||||||
|
|
||||||
l := len(names)
|
l := len(names)
|
||||||
|
if *c.echo.maxParam < l {
|
||||||
|
*c.echo.maxParam = l
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.pvalues) < l {
|
if len(c.pvalues) < l {
|
||||||
// Keeping the old pvalues just for backward compatibility, but it sounds that doesn't make sense to keep them,
|
// Keeping the old pvalues just for backward compatibility, but it sounds that doesn't make sense to keep them,
|
||||||
// probably those values will be overridden in a Context#SetParamValues
|
// probably those values will be overriden in a Context#SetParamValues
|
||||||
newPvalues := make([]string, l)
|
newPvalues := make([]string, l)
|
||||||
copy(newPvalues, c.pvalues)
|
copy(newPvalues, c.pvalues)
|
||||||
c.pvalues = newPvalues
|
c.pvalues = newPvalues
|
||||||
@ -358,11 +338,11 @@ func (c *context) ParamValues() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) SetParamValues(values ...string) {
|
func (c *context) SetParamValues(values ...string) {
|
||||||
// NOTE: Don't just set c.pvalues = values, because it has to have length c.echo.maxParam (or bigger) at all times
|
// NOTE: Don't just set c.pvalues = values, because it has to have length c.echo.maxParam at all times
|
||||||
// It will brake the Router#Find code
|
// It will brake the Router#Find code
|
||||||
limit := len(values)
|
limit := len(values)
|
||||||
if limit > len(c.pvalues) {
|
if limit > *c.echo.maxParam {
|
||||||
c.pvalues = make([]string, limit)
|
limit = *c.echo.maxParam
|
||||||
}
|
}
|
||||||
for i := 0; i < limit; i++ {
|
for i := 0; i < limit; i++ {
|
||||||
c.pvalues[i] = values[i]
|
c.pvalues[i] = values[i]
|
||||||
@ -500,7 +480,7 @@ func (c *context) jsonPBlob(code int, callback string, i interface{}) (err error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) json(code int, i interface{}, indent string) error {
|
func (c *context) json(code int, i interface{}, indent string) error {
|
||||||
c.writeContentType(MIMEApplicationJSON)
|
c.writeContentType(MIMEApplicationJSONCharsetUTF8)
|
||||||
c.response.Status = code
|
c.response.Status = code
|
||||||
return c.echo.JSONSerializer.Serialize(c, i, indent)
|
return c.echo.JSONSerializer.Serialize(c, i, indent)
|
||||||
}
|
}
|
||||||
@ -518,7 +498,7 @@ func (c *context) JSONPretty(code int, i interface{}, indent string) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) JSONBlob(code int, b []byte) (err error) {
|
func (c *context) JSONBlob(code int, b []byte) (err error) {
|
||||||
return c.Blob(code, MIMEApplicationJSON, b)
|
return c.Blob(code, MIMEApplicationJSONCharsetUTF8, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
||||||
@ -595,10 +575,8 @@ func (c *context) Inline(file, name string) error {
|
|||||||
return c.contentDisposition(file, name, "inline")
|
return c.contentDisposition(file, name, "inline")
|
||||||
}
|
}
|
||||||
|
|
||||||
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
|
|
||||||
|
|
||||||
func (c *context) contentDisposition(file, name, dispositionType string) error {
|
func (c *context) contentDisposition(file, name, dispositionType string) error {
|
||||||
c.response.Header().Set(HeaderContentDisposition, fmt.Sprintf(`%s; filename="%s"`, dispositionType, quoteEscaper.Replace(name)))
|
c.response.Header().Set(HeaderContentDisposition, fmt.Sprintf("%s; filename=%q", dispositionType, name))
|
||||||
return c.File(file)
|
return c.File(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,8 +631,8 @@ func (c *context) Reset(r *http.Request, w http.ResponseWriter) {
|
|||||||
c.path = ""
|
c.path = ""
|
||||||
c.pnames = nil
|
c.pnames = nil
|
||||||
c.logger = nil
|
c.logger = nil
|
||||||
// NOTE: Don't reset because it has to have length c.echo.maxParam (or bigger) at all times
|
// NOTE: Don't reset because it has to have length c.echo.maxParam at all times
|
||||||
for i := 0; i < len(c.pvalues); i++ {
|
for i := 0; i < *c.echo.maxParam; i++ {
|
||||||
c.pvalues[i] = ""
|
c.pvalues[i] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
201
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
201
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
@ -40,16 +37,16 @@ Learn more at https://echo.labstack.com
|
|||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
stdContext "context"
|
stdContext "context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
stdLog "log"
|
stdLog "log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
@ -63,29 +60,22 @@ 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.
|
||||||
//
|
Echo struct {
|
||||||
// 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.
|
|
||||||
// Adding new routes after the server has been started is also not safe!
|
|
||||||
type 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
|
||||||
|
StdLogger *stdLog.Logger
|
||||||
colorer *color.Color
|
colorer *color.Color
|
||||||
|
|
||||||
// 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.
|
|
||||||
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
|
|
||||||
Server *http.Server
|
Server *http.Server
|
||||||
TLSServer *http.Server
|
TLSServer *http.Server
|
||||||
Listener net.Listener
|
Listener net.Listener
|
||||||
@ -103,55 +93,53 @@ type Echo struct {
|
|||||||
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 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.
|
||||||
type Route struct {
|
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.
|
||||||
type HTTPError struct {
|
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.
|
||||||
type MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
MiddlewareFunc func(next HandlerFunc) HandlerFunc
|
||||||
|
|
||||||
// HandlerFunc defines a function to serve HTTP requests.
|
// HandlerFunc defines a function to serve HTTP requests.
|
||||||
type HandlerFunc func(c Context) error
|
HandlerFunc func(c Context) error
|
||||||
|
|
||||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||||
type HTTPErrorHandler func(err error, c Context)
|
HTTPErrorHandler func(error, Context)
|
||||||
|
|
||||||
// Validator is the interface that wraps the Validate function.
|
// Validator is the interface that wraps the Validate function.
|
||||||
type Validator interface {
|
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.
|
||||||
type JSONSerializer interface {
|
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.
|
||||||
type Renderer interface {
|
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{}`.
|
||||||
type Map map[string]interface{}
|
Map map[string]interface{}
|
||||||
|
|
||||||
// Common struct for Echo & Group.
|
// Common struct for Echo & Group.
|
||||||
type common struct{}
|
common struct{}
|
||||||
|
)
|
||||||
|
|
||||||
// HTTP methods
|
// HTTP methods
|
||||||
// NOTE: Deprecated, please use the stdlib constants directly instead.
|
// NOTE: Deprecated, please use the stdlib constants directly instead.
|
||||||
@ -170,12 +158,7 @@ const (
|
|||||||
|
|
||||||
// MIME types
|
// MIME types
|
||||||
const (
|
const (
|
||||||
// MIMEApplicationJSON JavaScript Object Notation (JSON) https://www.rfc-editor.org/rfc/rfc8259
|
|
||||||
MIMEApplicationJSON = "application/json"
|
MIMEApplicationJSON = "application/json"
|
||||||
// Deprecated: Please use MIMEApplicationJSON instead. JSON should be encoded using UTF-8 by default.
|
|
||||||
// No "charset" parameter is defined for this registration.
|
|
||||||
// Adding one really has no effect on compliant recipients.
|
|
||||||
// See RFC 8259, section 8.1. https://datatracker.ietf.org/doc/html/rfc8259#section-8.1
|
|
||||||
MIMEApplicationJSONCharsetUTF8 = MIMEApplicationJSON + "; " + charsetUTF8
|
MIMEApplicationJSONCharsetUTF8 = MIMEApplicationJSON + "; " + charsetUTF8
|
||||||
MIMEApplicationJavaScript = "application/javascript"
|
MIMEApplicationJavaScript = "application/javascript"
|
||||||
MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
|
MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
|
||||||
@ -265,7 +248,7 @@ const (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Version of Echo
|
// Version of Echo
|
||||||
Version = "4.12.0"
|
Version = "4.9.0"
|
||||||
website = "https://echo.labstack.com"
|
website = "https://echo.labstack.com"
|
||||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||||
banner = `
|
banner = `
|
||||||
@ -280,7 +263,8 @@ ____________________________________O/_______
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
var methods = [...]string{
|
var (
|
||||||
|
methods = [...]string{
|
||||||
http.MethodConnect,
|
http.MethodConnect,
|
||||||
http.MethodDelete,
|
http.MethodDelete,
|
||||||
http.MethodGet,
|
http.MethodGet,
|
||||||
@ -293,50 +277,22 @@ var methods = [...]string{
|
|||||||
http.MethodTrace,
|
http.MethodTrace,
|
||||||
REPORT,
|
REPORT,
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
var (
|
var (
|
||||||
ErrBadRequest = NewHTTPError(http.StatusBadRequest) // HTTP 400 Bad Request
|
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType)
|
||||||
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized) // HTTP 401 Unauthorized
|
ErrNotFound = NewHTTPError(http.StatusNotFound)
|
||||||
ErrPaymentRequired = NewHTTPError(http.StatusPaymentRequired) // HTTP 402 Payment Required
|
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized)
|
||||||
ErrForbidden = NewHTTPError(http.StatusForbidden) // HTTP 403 Forbidden
|
ErrForbidden = NewHTTPError(http.StatusForbidden)
|
||||||
ErrNotFound = NewHTTPError(http.StatusNotFound) // HTTP 404 Not Found
|
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed)
|
||||||
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed) // HTTP 405 Method Not Allowed
|
ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge)
|
||||||
ErrNotAcceptable = NewHTTPError(http.StatusNotAcceptable) // HTTP 406 Not Acceptable
|
ErrTooManyRequests = NewHTTPError(http.StatusTooManyRequests)
|
||||||
ErrProxyAuthRequired = NewHTTPError(http.StatusProxyAuthRequired) // HTTP 407 Proxy AuthRequired
|
ErrBadRequest = NewHTTPError(http.StatusBadRequest)
|
||||||
ErrRequestTimeout = NewHTTPError(http.StatusRequestTimeout) // HTTP 408 Request Timeout
|
ErrBadGateway = NewHTTPError(http.StatusBadGateway)
|
||||||
ErrConflict = NewHTTPError(http.StatusConflict) // HTTP 409 Conflict
|
ErrInternalServerError = NewHTTPError(http.StatusInternalServerError)
|
||||||
ErrGone = NewHTTPError(http.StatusGone) // HTTP 410 Gone
|
ErrRequestTimeout = NewHTTPError(http.StatusRequestTimeout)
|
||||||
ErrLengthRequired = NewHTTPError(http.StatusLengthRequired) // HTTP 411 Length Required
|
ErrServiceUnavailable = NewHTTPError(http.StatusServiceUnavailable)
|
||||||
ErrPreconditionFailed = NewHTTPError(http.StatusPreconditionFailed) // HTTP 412 Precondition Failed
|
|
||||||
ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge) // HTTP 413 Payload Too Large
|
|
||||||
ErrRequestURITooLong = NewHTTPError(http.StatusRequestURITooLong) // HTTP 414 URI Too Long
|
|
||||||
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType) // HTTP 415 Unsupported Media Type
|
|
||||||
ErrRequestedRangeNotSatisfiable = NewHTTPError(http.StatusRequestedRangeNotSatisfiable) // HTTP 416 Range Not Satisfiable
|
|
||||||
ErrExpectationFailed = NewHTTPError(http.StatusExpectationFailed) // HTTP 417 Expectation Failed
|
|
||||||
ErrTeapot = NewHTTPError(http.StatusTeapot) // HTTP 418 I'm a teapot
|
|
||||||
ErrMisdirectedRequest = NewHTTPError(http.StatusMisdirectedRequest) // HTTP 421 Misdirected Request
|
|
||||||
ErrUnprocessableEntity = NewHTTPError(http.StatusUnprocessableEntity) // HTTP 422 Unprocessable Entity
|
|
||||||
ErrLocked = NewHTTPError(http.StatusLocked) // HTTP 423 Locked
|
|
||||||
ErrFailedDependency = NewHTTPError(http.StatusFailedDependency) // HTTP 424 Failed Dependency
|
|
||||||
ErrTooEarly = NewHTTPError(http.StatusTooEarly) // HTTP 425 Too Early
|
|
||||||
ErrUpgradeRequired = NewHTTPError(http.StatusUpgradeRequired) // HTTP 426 Upgrade Required
|
|
||||||
ErrPreconditionRequired = NewHTTPError(http.StatusPreconditionRequired) // HTTP 428 Precondition Required
|
|
||||||
ErrTooManyRequests = NewHTTPError(http.StatusTooManyRequests) // HTTP 429 Too Many Requests
|
|
||||||
ErrRequestHeaderFieldsTooLarge = NewHTTPError(http.StatusRequestHeaderFieldsTooLarge) // HTTP 431 Request Header Fields Too Large
|
|
||||||
ErrUnavailableForLegalReasons = NewHTTPError(http.StatusUnavailableForLegalReasons) // HTTP 451 Unavailable For Legal Reasons
|
|
||||||
ErrInternalServerError = NewHTTPError(http.StatusInternalServerError) // HTTP 500 Internal Server Error
|
|
||||||
ErrNotImplemented = NewHTTPError(http.StatusNotImplemented) // HTTP 501 Not Implemented
|
|
||||||
ErrBadGateway = NewHTTPError(http.StatusBadGateway) // HTTP 502 Bad Gateway
|
|
||||||
ErrServiceUnavailable = NewHTTPError(http.StatusServiceUnavailable) // HTTP 503 Service Unavailable
|
|
||||||
ErrGatewayTimeout = NewHTTPError(http.StatusGatewayTimeout) // HTTP 504 Gateway Timeout
|
|
||||||
ErrHTTPVersionNotSupported = NewHTTPError(http.StatusHTTPVersionNotSupported) // HTTP 505 HTTP Version Not Supported
|
|
||||||
ErrVariantAlsoNegotiates = NewHTTPError(http.StatusVariantAlsoNegotiates) // HTTP 506 Variant Also Negotiates
|
|
||||||
ErrInsufficientStorage = NewHTTPError(http.StatusInsufficientStorage) // HTTP 507 Insufficient Storage
|
|
||||||
ErrLoopDetected = NewHTTPError(http.StatusLoopDetected) // HTTP 508 Loop Detected
|
|
||||||
ErrNotExtended = NewHTTPError(http.StatusNotExtended) // HTTP 510 Not Extended
|
|
||||||
ErrNetworkAuthenticationRequired = NewHTTPError(http.StatusNetworkAuthenticationRequired) // HTTP 511 Network Authentication Required
|
|
||||||
|
|
||||||
ErrValidatorNotRegistered = errors.New("validator not registered")
|
ErrValidatorNotRegistered = errors.New("validator not registered")
|
||||||
ErrRendererNotRegistered = errors.New("renderer not registered")
|
ErrRendererNotRegistered = errors.New("renderer not registered")
|
||||||
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
||||||
@ -345,15 +301,13 @@ var (
|
|||||||
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
ErrInvalidListenerNetwork = errors.New("invalid listener network")
|
||||||
)
|
)
|
||||||
|
|
||||||
// NotFoundHandler is the handler that router uses in case there was no matching route found. Returns an error that results
|
// Error handlers
|
||||||
// HTTP 404 status code.
|
var (
|
||||||
var NotFoundHandler = func(c Context) error {
|
NotFoundHandler = func(c Context) error {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodNotAllowedHandler is the handler thar router uses in case there was no matching route found but there was
|
MethodNotAllowedHandler = func(c Context) error {
|
||||||
// another matching routes for that requested URL. Returns an error that results HTTP 405 Method Not Allowed status code.
|
|
||||||
var MethodNotAllowedHandler = func(c Context) error {
|
|
||||||
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
|
||||||
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
|
||||||
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
|
||||||
@ -362,6 +316,7 @@ var MethodNotAllowedHandler = func(c Context) error {
|
|||||||
}
|
}
|
||||||
return ErrMethodNotAllowed
|
return ErrMethodNotAllowed
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// New creates an instance of Echo.
|
// New creates an instance of Echo.
|
||||||
func New() (e *Echo) {
|
func New() (e *Echo) {
|
||||||
@ -419,7 +374,7 @@ func (e *Echo) Routers() map[string]*Router {
|
|||||||
//
|
//
|
||||||
// NOTE: In case errors happens in middleware call-chain that is returning from handler (which did not return an error).
|
// NOTE: In case errors happens in middleware call-chain that is returning from handler (which did not return an error).
|
||||||
// When handler has already sent response (ala c.JSON()) and there is error in middleware that is returning from
|
// When handler has already sent response (ala c.JSON()) and there is error in middleware that is returning from
|
||||||
// handler. Then the error that global error handler received will be ignored because we have already "committed" the
|
// handler. Then the error that global error handler received will be ignored because we have already "commited" the
|
||||||
// response and status code header has been sent to the client.
|
// response and status code header has been sent to the client.
|
||||||
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
||||||
|
|
||||||
@ -444,18 +399,12 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
|
|||||||
// Issue #1426
|
// Issue #1426
|
||||||
code := he.Code
|
code := he.Code
|
||||||
message := he.Message
|
message := he.Message
|
||||||
|
if m, ok := he.Message.(string); ok {
|
||||||
switch m := he.Message.(type) {
|
|
||||||
case string:
|
|
||||||
if e.Debug {
|
if e.Debug {
|
||||||
message = Map{"message": m, "error": err.Error()}
|
message = Map{"message": m, "error": err.Error()}
|
||||||
} else {
|
} else {
|
||||||
message = Map{"message": m}
|
message = Map{"message": m}
|
||||||
}
|
}
|
||||||
case json.Marshaler:
|
|
||||||
// do nothing - this type knows how to format itself to JSON
|
|
||||||
case error:
|
|
||||||
message = Map{"message": m.Error()}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send response
|
// Send response
|
||||||
@ -578,20 +527,21 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
|
|||||||
return e.file(path, file, e.GET, m...)
|
return e.file(path, file, e.GET, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Echo) add(host, method, path string, handler HandlerFunc, middlewares ...MiddlewareFunc) *Route {
|
func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||||
|
name := handlerName(handler)
|
||||||
router := e.findRouter(host)
|
router := e.findRouter(host)
|
||||||
// FIXME: when handler+middleware are both nil ... make it behave like handler removal
|
// FIXME: when handler+middleware are both nil ... make it behave like handler removal
|
||||||
name := handlerName(handler)
|
router.Add(method, path, func(c Context) error {
|
||||||
route := router.add(method, path, name, func(c Context) error {
|
h := applyMiddleware(handler, middleware...)
|
||||||
h := applyMiddleware(handler, middlewares...)
|
|
||||||
return h(c)
|
return h(c)
|
||||||
})
|
})
|
||||||
|
r := &Route{
|
||||||
if e.OnAddRouteHandler != nil {
|
Method: method,
|
||||||
e.OnAddRouteHandler(host, *route, handler, middlewares)
|
Path: path,
|
||||||
|
Name: name,
|
||||||
}
|
}
|
||||||
|
e.router.routes[method+path] = r
|
||||||
return route
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add registers a new route for an HTTP method and path with matching handler
|
// Add registers a new route for an HTTP method and path with matching handler
|
||||||
@ -615,7 +565,7 @@ func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI generates an URI from handler.
|
// URI generates a URI from handler.
|
||||||
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
func (e *Echo) URI(handler HandlerFunc, params ...interface{}) string {
|
||||||
name := handlerName(handler)
|
name := handlerName(handler)
|
||||||
return e.Reverse(name, params...)
|
return e.Reverse(name, params...)
|
||||||
@ -626,15 +576,37 @@ func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
|
|||||||
return e.URI(h, params...)
|
return e.URI(h, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse generates a URL from route name and provided parameters.
|
// Reverse generates an URL from route name and provided parameters.
|
||||||
func (e *Echo) Reverse(name string, params ...interface{}) string {
|
func (e *Echo) Reverse(name string, params ...interface{}) string {
|
||||||
return e.router.Reverse(name, params...)
|
uri := new(bytes.Buffer)
|
||||||
|
ln := len(params)
|
||||||
|
n := 0
|
||||||
|
for _, r := range e.router.routes {
|
||||||
|
if r.Name == name {
|
||||||
|
for i, l := 0, len(r.Path); i < l; i++ {
|
||||||
|
if (r.Path[i] == ':' || r.Path[i] == '*') && n < ln {
|
||||||
|
for ; i < l && r.Path[i] != '/'; i++ {
|
||||||
|
}
|
||||||
|
uri.WriteString(fmt.Sprintf("%v", params[n]))
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
if i < l {
|
||||||
|
uri.WriteByte(r.Path[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uri.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routes returns the registered routes for default router.
|
// Routes returns the registered routes.
|
||||||
// In case when Echo serves multiple hosts/domains use `e.Routers()["domain2.site"].Routes()` to get specific host routes.
|
|
||||||
func (e *Echo) Routes() []*Route {
|
func (e *Echo) Routes() []*Route {
|
||||||
return e.router.Routes()
|
routes := make([]*Route, 0, len(e.router.routes))
|
||||||
|
for _, v := range e.router.routes {
|
||||||
|
routes = append(routes, v)
|
||||||
|
}
|
||||||
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcquireContext returns an empty `Context` instance from the pool.
|
// AcquireContext returns an empty `Context` instance from the pool.
|
||||||
@ -654,7 +626,7 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Acquire context
|
// Acquire context
|
||||||
c := e.pool.Get().(*context)
|
c := e.pool.Get().(*context)
|
||||||
c.Reset(r, w)
|
c.Reset(r, w)
|
||||||
var h HandlerFunc
|
var h func(Context) error
|
||||||
|
|
||||||
if e.premiddleware == nil {
|
if e.premiddleware == nil {
|
||||||
e.findRouter(r.Host).Find(r.Method, GetPath(r), c)
|
e.findRouter(r.Host).Find(r.Method, GetPath(r), c)
|
||||||
@ -728,7 +700,7 @@ func (e *Echo) StartTLS(address string, certFile, keyFile interface{}) (err erro
|
|||||||
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
|
func filepathOrContent(fileOrContent interface{}) (content []byte, err error) {
|
||||||
switch v := fileOrContent.(type) {
|
switch v := fileOrContent.(type) {
|
||||||
case string:
|
case string:
|
||||||
return os.ReadFile(v)
|
return ioutil.ReadFile(v)
|
||||||
case []byte:
|
case []byte:
|
||||||
return v, nil
|
return v, nil
|
||||||
default:
|
default:
|
||||||
@ -912,15 +884,6 @@ func (he *HTTPError) SetInternal(err error) *HTTPError {
|
|||||||
return he
|
return he
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithInternal returns clone of HTTPError with err set to HTTPError.Internal field
|
|
||||||
func (he *HTTPError) WithInternal(err error) *HTTPError {
|
|
||||||
return &HTTPError{
|
|
||||||
Code: he.Code,
|
|
||||||
Message: he.Message,
|
|
||||||
Internal: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap satisfies the Go 1.13 error wrapper interface.
|
// Unwrap satisfies the Go 1.13 error wrapper interface.
|
||||||
func (he *HTTPError) Unwrap() error {
|
func (he *HTTPError) Unwrap() error {
|
||||||
return he.Internal
|
return he.Internal
|
||||||
@ -950,8 +913,8 @@ func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc {
|
|||||||
|
|
||||||
// GetPath returns RawPath, if it's empty returns Path from URL
|
// GetPath returns RawPath, if it's empty returns Path from URL
|
||||||
// Difference between RawPath and Path is:
|
// Difference between RawPath and Path is:
|
||||||
// - Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
|
// * Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
|
||||||
// - RawPath is an optional field which only gets set if the default encoding is different from Path.
|
// * RawPath is an optional field which only gets set if the default encoding is different from Path.
|
||||||
func GetPath(r *http.Request) string {
|
func GetPath(r *http.Request) string {
|
||||||
path := r.URL.RawPath
|
path := r.URL.RawPath
|
||||||
if path == "" {
|
if path == "" {
|
||||||
|
21
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
21
vendor/github.com/labstack/echo/v4/echo_fs.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -10,6 +7,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -127,7 +125,7 @@ func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
|||||||
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS.
|
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS.
|
||||||
// fs.Fs.Open does not like relative paths ("./", "../") and absolute paths at all but prior echo.Filesystem we
|
// fs.Fs.Open does not like relative paths ("./", "../") and absolute paths at all but prior echo.Filesystem we
|
||||||
// were able to use paths like `./myfile.log`, `/etc/hosts` and these would work fine with `os.Open` but not with fs.Fs
|
// were able to use paths like `./myfile.log`, `/etc/hosts` and these would work fine with `os.Open` but not with fs.Fs
|
||||||
if !filepath.IsAbs(root) {
|
if isRelativePath(root) {
|
||||||
root = filepath.Join(dFS.prefix, root)
|
root = filepath.Join(dFS.prefix, root)
|
||||||
}
|
}
|
||||||
return &defaultFS{
|
return &defaultFS{
|
||||||
@ -138,6 +136,21 @@ func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
|||||||
return fs.Sub(currentFs, root)
|
return fs.Sub(currentFs, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isRelativePath(path string) bool {
|
||||||
|
if path == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if path[0] == '/' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "windows" && strings.IndexByte(path, ':') != -1 {
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#file_and_directory_names
|
||||||
|
// https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// MustSubFS creates sub FS from current filesystem or panic on failure.
|
// MustSubFS creates sub FS from current filesystem or panic on failure.
|
||||||
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
|
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
|
||||||
//
|
//
|
||||||
|
17
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
17
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
@ -1,22 +1,21 @@
|
|||||||
// 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) {
|
||||||
@ -24,12 +23,10 @@ func (g *Group) Use(middleware ...MiddlewareFunc) {
|
|||||||
if len(g.middleware) == 0 {
|
if len(g.middleware) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// group level middlewares are different from Echo `Pre` and `Use` middlewares (those are global). Group level middlewares
|
// Allow all requests to reach the group as they might get dropped if router
|
||||||
// are only executed if they are added to the Router with route.
|
// doesn't find a match, making none of the group middleware process.
|
||||||
// So we register catch all route (404 is a safe way to emulate route match) for this group and now during routing the
|
g.Any("", NotFoundHandler)
|
||||||
// Router would find route to match our request path and therefore guarantee the middleware(s) will get executed.
|
g.Any("/*", NotFoundHandler)
|
||||||
g.RouteNotFound("", NotFoundHandler)
|
|
||||||
g.RouteNotFound("/*", NotFoundHandler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
|
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
|
||||||
|
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,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
24
vendor/github.com/labstack/echo/v4/ip.go
generated
vendored
24
vendor/github.com/labstack/echo/v4/ip.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -67,7 +64,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 infrastructure".
|
configurable by client. Here "trustable" means "you are sure the IP address belongs to your infrastructre".
|
||||||
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)`.
|
||||||
@ -228,21 +225,13 @@ 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 ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
|
||||||
}
|
|
||||||
|
|
||||||
if checker.trust(net.ParseIP(directIP)) {
|
|
||||||
realIP = strings.TrimPrefix(realIP, "[")
|
|
||||||
realIP = strings.TrimSuffix(realIP, "]")
|
|
||||||
if rIP := net.ParseIP(realIP); rIP != nil {
|
|
||||||
return realIP
|
return realIP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return extractIP(req)
|
||||||
return directIP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,10 +248,7 @@ func ExtractIPFromXFFHeader(options ...TrustOption) IPExtractor {
|
|||||||
}
|
}
|
||||||
ips := append(strings.Split(strings.Join(xffs, ","), ","), directIP)
|
ips := append(strings.Split(strings.Join(xffs, ","), ","), directIP)
|
||||||
for i := len(ips) - 1; i >= 0; i-- {
|
for i := len(ips) - 1; i >= 0; i-- {
|
||||||
ips[i] = strings.TrimSpace(ips[i])
|
ip := net.ParseIP(strings.TrimSpace(ips[i]))
|
||||||
ips[i] = strings.TrimPrefix(ips[i], "[")
|
|
||||||
ips[i] = strings.TrimSuffix(ips[i], "]")
|
|
||||||
ip := net.ParseIP(ips[i])
|
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
// Unable to parse IP; cannot trust entire records
|
// Unable to parse IP; cannot trust entire records
|
||||||
return directIP
|
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,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
10
vendor/github.com/labstack/echo/v4/log.go
generated
vendored
10
vendor/github.com/labstack/echo/v4/log.go
generated
vendored
@ -1,15 +1,14 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/labstack/gommon/log"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/labstack/gommon/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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
|
||||||
@ -39,3 +38,4 @@ type Logger interface {
|
|||||||
Panicj(j log.JSON)
|
Panicj(j log.JSON)
|
||||||
Panicf(format string, args ...interface{})
|
Panicf(format string, args ...interface{})
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
17
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
17
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
@ -1,19 +1,17 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"net/http"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"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
|
||||||
|
|
||||||
@ -27,20 +25,21 @@ type BasicAuthConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BasicAuthValidator defines a function to validate BasicAuth credentials.
|
// BasicAuthValidator defines a function to validate BasicAuth credentials.
|
||||||
// The function should return a boolean indicating whether the credentials are valid,
|
BasicAuthValidator func(string, string, echo.Context) (bool, error)
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
|
32
vendor/github.com/labstack/echo/v4/middleware/body_dump.go
generated
vendored
32
vendor/github.com/labstack/echo/v4/middleware/body_dump.go
generated
vendored
@ -1,21 +1,19 @@
|
|||||||
// 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"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"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
|
||||||
|
|
||||||
@ -25,17 +23,20 @@ type BodyDumpConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BodyDumpHandler receives the request and response payload.
|
// BodyDumpHandler receives the request and response payload.
|
||||||
type BodyDumpHandler func(echo.Context, []byte, []byte)
|
BodyDumpHandler func(echo.Context, []byte, []byte)
|
||||||
|
|
||||||
type bodyDumpResponseWriter struct {
|
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.
|
||||||
//
|
//
|
||||||
@ -67,9 +68,9 @@ func BodyDumpWithConfig(config BodyDumpConfig) echo.MiddlewareFunc {
|
|||||||
// Request
|
// Request
|
||||||
reqBody := []byte{}
|
reqBody := []byte{}
|
||||||
if c.Request().Body != nil { // Read
|
if c.Request().Body != nil { // Read
|
||||||
reqBody, _ = io.ReadAll(c.Request().Body)
|
reqBody, _ = ioutil.ReadAll(c.Request().Body)
|
||||||
}
|
}
|
||||||
c.Request().Body = io.NopCloser(bytes.NewBuffer(reqBody)) // Reset
|
c.Request().Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) // Reset
|
||||||
|
|
||||||
// Response
|
// Response
|
||||||
resBody := new(bytes.Buffer)
|
resBody := new(bytes.Buffer)
|
||||||
@ -98,16 +99,9 @@ func (w *bodyDumpResponseWriter) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *bodyDumpResponseWriter) Flush() {
|
func (w *bodyDumpResponseWriter) Flush() {
|
||||||
err := responseControllerFlush(w.ResponseWriter)
|
w.ResponseWriter.(http.Flusher).Flush()
|
||||||
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 responseControllerHijack(w.ResponseWriter)
|
return w.ResponseWriter.(http.Hijacker).Hijack()
|
||||||
}
|
|
||||||
|
|
||||||
func (w *bodyDumpResponseWriter) Unwrap() http.ResponseWriter {
|
|
||||||
return w.ResponseWriter
|
|
||||||
}
|
}
|
||||||
|
19
vendor/github.com/labstack/echo/v4/middleware/body_limit.go
generated
vendored
19
vendor/github.com/labstack/echo/v4/middleware/body_limit.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -12,8 +9,9 @@ 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
|
||||||
|
|
||||||
@ -23,16 +21,20 @@ type BodyLimitConfig struct {
|
|||||||
limit int64
|
limit int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type limitedReader struct {
|
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.
|
||||||
//
|
//
|
||||||
@ -78,7 +80,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)
|
r.Reset(req.Body, c)
|
||||||
defer pool.Put(r)
|
defer pool.Put(r)
|
||||||
req.Body = r
|
req.Body = r
|
||||||
|
|
||||||
@ -100,8 +102,9 @@ func (r *limitedReader) Close() error {
|
|||||||
return r.reader.Close()
|
return r.reader.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *limitedReader) Reset(reader io.ReadCloser) {
|
func (r *limitedReader) Reset(reader io.ReadCloser, context echo.Context) {
|
||||||
r.reader = reader
|
r.reader = reader
|
||||||
|
r.context = context
|
||||||
r.read = 0
|
r.read = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
117
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
117
vendor/github.com/labstack/echo/v4/middleware/compress.go
generated
vendored
@ -1,13 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@ -16,50 +13,35 @@ 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.
|
|
||||||
// Optional. Default value 0.
|
|
||||||
//
|
|
||||||
// Most of the time you will not need to change the default. Compressing
|
|
||||||
// a short response might increase the transmitted data because of the
|
|
||||||
// gzip format overhead. Compressing the response will also consume CPU
|
|
||||||
// and time on the server and the client (for decompressing). Depending on
|
|
||||||
// your use case such a threshold might be useful.
|
|
||||||
//
|
|
||||||
// See also:
|
|
||||||
// https://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits
|
|
||||||
MinLength int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type gzipResponseWriter struct {
|
gzipResponseWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
wroteHeader bool
|
|
||||||
wroteBody bool
|
wroteBody bool
|
||||||
minLength int
|
|
||||||
minLengthExceeded bool
|
|
||||||
buffer *bytes.Buffer
|
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
||||||
// scheme.
|
// scheme.
|
||||||
@ -77,12 +59,8 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
|||||||
if config.Level == 0 {
|
if config.Level == 0 {
|
||||||
config.Level = DefaultGzipConfig.Level
|
config.Level = DefaultGzipConfig.Level
|
||||||
}
|
}
|
||||||
if config.MinLength < 0 {
|
|
||||||
config.MinLength = DefaultGzipConfig.MinLength
|
|
||||||
}
|
|
||||||
|
|
||||||
pool := gzipCompressPool(config)
|
pool := gzipCompressPool(config)
|
||||||
bpool := bufferPool()
|
|
||||||
|
|
||||||
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 {
|
||||||
@ -93,6 +71,7 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
|||||||
res := c.Response()
|
res := c.Response()
|
||||||
res.Header().Add(echo.HeaderVary, echo.HeaderAcceptEncoding)
|
res.Header().Add(echo.HeaderVary, echo.HeaderAcceptEncoding)
|
||||||
if strings.Contains(c.Request().Header.Get(echo.HeaderAcceptEncoding), gzipScheme) {
|
if strings.Contains(c.Request().Header.Get(echo.HeaderAcceptEncoding), gzipScheme) {
|
||||||
|
res.Header().Set(echo.HeaderContentEncoding, gzipScheme) // Issue #806
|
||||||
i := pool.Get()
|
i := pool.Get()
|
||||||
w, ok := i.(*gzip.Writer)
|
w, ok := i.(*gzip.Writer)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -100,38 +79,19 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
rw := res.Writer
|
rw := res.Writer
|
||||||
w.Reset(rw)
|
w.Reset(rw)
|
||||||
|
grw := &gzipResponseWriter{Writer: w, ResponseWriter: rw}
|
||||||
buf := bpool.Get().(*bytes.Buffer)
|
|
||||||
buf.Reset()
|
|
||||||
|
|
||||||
grw := &gzipResponseWriter{Writer: w, ResponseWriter: rw, minLength: config.MinLength, buffer: buf}
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// There are different reasons for cases when we have not yet written response to the client and now need to do so.
|
|
||||||
// a) handler response had only response code and no response body (ala 404 or redirects etc). Response code need to be written now.
|
|
||||||
// b) body is shorter than our minimum length threshold and being buffered currently and needs to be written
|
|
||||||
if !grw.wroteBody {
|
if !grw.wroteBody {
|
||||||
if res.Header().Get(echo.HeaderContentEncoding) == gzipScheme {
|
if res.Header().Get(echo.HeaderContentEncoding) == gzipScheme {
|
||||||
res.Header().Del(echo.HeaderContentEncoding)
|
res.Header().Del(echo.HeaderContentEncoding)
|
||||||
}
|
}
|
||||||
if grw.wroteHeader {
|
|
||||||
rw.WriteHeader(grw.code)
|
|
||||||
}
|
|
||||||
// We have to reset response to it's pristine state when
|
// We have to reset response to it's pristine state when
|
||||||
// nothing is written to body or error is returned.
|
// nothing is written to body or error is returned.
|
||||||
// See issue #424, #407.
|
// See issue #424, #407.
|
||||||
res.Writer = rw
|
res.Writer = rw
|
||||||
w.Reset(io.Discard)
|
w.Reset(ioutil.Discard)
|
||||||
} else if !grw.minLengthExceeded {
|
|
||||||
// Write uncompressed response
|
|
||||||
res.Writer = rw
|
|
||||||
if grw.wroteHeader {
|
|
||||||
grw.ResponseWriter.WriteHeader(grw.code)
|
|
||||||
}
|
|
||||||
grw.buffer.WriteTo(rw)
|
|
||||||
w.Reset(io.Discard)
|
|
||||||
}
|
}
|
||||||
w.Close()
|
w.Close()
|
||||||
bpool.Put(buf)
|
|
||||||
pool.Put(w)
|
pool.Put(w)
|
||||||
}()
|
}()
|
||||||
res.Writer = grw
|
res.Writer = grw
|
||||||
@ -143,11 +103,7 @@ func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
func (w *gzipResponseWriter) WriteHeader(code int) {
|
func (w *gzipResponseWriter) WriteHeader(code int) {
|
||||||
w.Header().Del(echo.HeaderContentLength) // Issue #444
|
w.Header().Del(echo.HeaderContentLength) // Issue #444
|
||||||
|
w.ResponseWriter.WriteHeader(code)
|
||||||
w.wroteHeader = true
|
|
||||||
|
|
||||||
// Delay writing of the header until we know if we'll actually compress the response
|
|
||||||
w.code = code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gzipResponseWriter) Write(b []byte) (int, error) {
|
func (w *gzipResponseWriter) Write(b []byte) (int, error) {
|
||||||
@ -155,50 +111,18 @@ func (w *gzipResponseWriter) Write(b []byte) (int, error) {
|
|||||||
w.Header().Set(echo.HeaderContentType, http.DetectContentType(b))
|
w.Header().Set(echo.HeaderContentType, http.DetectContentType(b))
|
||||||
}
|
}
|
||||||
w.wroteBody = true
|
w.wroteBody = true
|
||||||
|
|
||||||
if !w.minLengthExceeded {
|
|
||||||
n, err := w.buffer.Write(b)
|
|
||||||
|
|
||||||
if w.buffer.Len() >= w.minLength {
|
|
||||||
w.minLengthExceeded = true
|
|
||||||
|
|
||||||
// The minimum length is exceeded, add Content-Encoding header and write the header
|
|
||||||
w.Header().Set(echo.HeaderContentEncoding, gzipScheme) // Issue #806
|
|
||||||
if w.wroteHeader {
|
|
||||||
w.ResponseWriter.WriteHeader(w.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.Writer.Write(w.buffer.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.Writer.Write(b)
|
return w.Writer.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gzipResponseWriter) Flush() {
|
func (w *gzipResponseWriter) Flush() {
|
||||||
if !w.minLengthExceeded {
|
|
||||||
// Enforce compression because we will not know how much more data will come
|
|
||||||
w.minLengthExceeded = true
|
|
||||||
w.Header().Set(echo.HeaderContentEncoding, gzipScheme) // Issue #806
|
|
||||||
if w.wroteHeader {
|
|
||||||
w.ResponseWriter.WriteHeader(w.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Writer.Write(w.buffer.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Writer.(*gzip.Writer).Flush()
|
w.Writer.(*gzip.Writer).Flush()
|
||||||
_ = responseControllerFlush(w.ResponseWriter)
|
if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
|
||||||
|
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 responseControllerHijack(w.ResponseWriter)
|
return w.ResponseWriter.(http.Hijacker).Hijack()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
||||||
@ -211,7 +135,7 @@ func (w *gzipResponseWriter) Push(target string, opts *http.PushOptions) error {
|
|||||||
func gzipCompressPool(config GzipConfig) sync.Pool {
|
func gzipCompressPool(config GzipConfig) sync.Pool {
|
||||||
return sync.Pool{
|
return sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
w, err := gzip.NewWriterLevel(io.Discard, config.Level)
|
w, err := gzip.NewWriterLevel(ioutil.Discard, config.Level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -219,12 +143,3 @@ func gzipCompressPool(config GzipConfig) sync.Pool {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func bufferPool() sync.Pool {
|
|
||||||
return sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
return b
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
75
vendor/github.com/labstack/echo/v4/middleware/context_timeout.go
generated
vendored
75
vendor/github.com/labstack/echo/v4/middleware/context_timeout.go
generated
vendored
@ -1,75 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ContextTimeoutConfig defines the config for ContextTimeout middleware.
|
|
||||||
type ContextTimeoutConfig struct {
|
|
||||||
// Skipper defines a function to skip middleware.
|
|
||||||
Skipper Skipper
|
|
||||||
|
|
||||||
// ErrorHandler is a function when error aries in middleware execution.
|
|
||||||
ErrorHandler func(err error, c echo.Context) error
|
|
||||||
|
|
||||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
|
||||||
Timeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContextTimeout returns a middleware which returns error (503 Service Unavailable error) to client
|
|
||||||
// when underlying method returns context.DeadlineExceeded error.
|
|
||||||
func ContextTimeout(timeout time.Duration) echo.MiddlewareFunc {
|
|
||||||
return ContextTimeoutWithConfig(ContextTimeoutConfig{Timeout: timeout})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContextTimeoutWithConfig returns a Timeout middleware with config.
|
|
||||||
func ContextTimeoutWithConfig(config ContextTimeoutConfig) echo.MiddlewareFunc {
|
|
||||||
mw, err := config.ToMiddleware()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return mw
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToMiddleware converts Config to middleware.
|
|
||||||
func (config ContextTimeoutConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
|
|
||||||
if config.Timeout == 0 {
|
|
||||||
return nil, errors.New("timeout must be set")
|
|
||||||
}
|
|
||||||
if config.Skipper == nil {
|
|
||||||
config.Skipper = DefaultSkipper
|
|
||||||
}
|
|
||||||
if config.ErrorHandler == nil {
|
|
||||||
config.ErrorHandler = func(err error, c echo.Context) error {
|
|
||||||
if err != nil && errors.Is(err, context.DeadlineExceeded) {
|
|
||||||
return echo.ErrServiceUnavailable.WithInternal(err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
||||||
return func(c echo.Context) error {
|
|
||||||
if config.Skipper(c) {
|
|
||||||
return next(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
timeoutContext, cancel := context.WithTimeout(c.Request().Context(), config.Timeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
c.SetRequest(c.Request().WithContext(timeoutContext))
|
|
||||||
|
|
||||||
if err := next(c); err != nil {
|
|
||||||
return config.ErrorHandler(err, c)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}, nil
|
|
||||||
}
|
|
39
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
39
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -12,8 +9,9 @@ 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
|
||||||
|
|
||||||
@ -41,7 +39,7 @@ type CORSConfig struct {
|
|||||||
// 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:"-"`
|
AllowOriginFunc func(origin string) (bool, error) `yaml:"allow_origin_func"`
|
||||||
|
|
||||||
// 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
|
||||||
@ -81,15 +79,6 @@ type CORSConfig struct {
|
|||||||
// 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
|
|
||||||
// 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)
|
|
||||||
// attacks. See: https://github.com/labstack/echo/issues/2400 for discussion on the subject.
|
|
||||||
//
|
|
||||||
// Optional. Default value is false.
|
|
||||||
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.
|
||||||
//
|
//
|
||||||
@ -101,20 +90,22 @@ type CORSConfig struct {
|
|||||||
// 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 - meaning header is not sent.
|
// Optional. Default value 0. The header is set only if MaxAge > 0.
|
||||||
//
|
//
|
||||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
||||||
MaxAge int `yaml:"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)].
|
||||||
@ -150,8 +141,8 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
|||||||
allowOriginPatterns := []string{}
|
allowOriginPatterns := []string{}
|
||||||
for _, origin := range config.AllowOrigins {
|
for _, origin := range config.AllowOrigins {
|
||||||
pattern := regexp.QuoteMeta(origin)
|
pattern := regexp.QuoteMeta(origin)
|
||||||
pattern = strings.ReplaceAll(pattern, "\\*", ".*")
|
pattern = strings.Replace(pattern, "\\*", ".*", -1)
|
||||||
pattern = strings.ReplaceAll(pattern, "\\?", ".")
|
pattern = strings.Replace(pattern, "\\?", ".", -1)
|
||||||
pattern = "^" + pattern + "$"
|
pattern = "^" + pattern + "$"
|
||||||
allowOriginPatterns = append(allowOriginPatterns, pattern)
|
allowOriginPatterns = append(allowOriginPatterns, pattern)
|
||||||
}
|
}
|
||||||
@ -159,11 +150,7 @@ 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 {
|
||||||
@ -216,7 +203,7 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
|||||||
} else {
|
} else {
|
||||||
// Check allowed origins
|
// Check allowed origins
|
||||||
for _, o := range config.AllowOrigins {
|
for _, o := range config.AllowOrigins {
|
||||||
if o == "*" && config.AllowCredentials && config.UnsafeWildcardOriginWithAllowCredentials {
|
if o == "*" && config.AllowCredentials {
|
||||||
allowOrigin = origin
|
allowOrigin = origin
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -286,7 +273,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)
|
||||||
|
23
vendor/github.com/labstack/echo/v4/middleware/csrf.go
generated
vendored
23
vendor/github.com/labstack/echo/v4/middleware/csrf.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,10 +6,12 @@ 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
|
||||||
|
|
||||||
@ -68,13 +67,15 @@ type CSRFConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CSRFErrorHandler is a function which is executed for creating custom errors.
|
// CSRFErrorHandler is a function which is executed for creating custom errors.
|
||||||
type CSRFErrorHandler func(err error, c echo.Context) error
|
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,
|
||||||
@ -83,6 +84,7 @@ var DefaultCSRFConfig = CSRFConfig{
|
|||||||
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
|
||||||
@ -101,7 +103,6 @@ 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
|
||||||
}
|
}
|
||||||
@ -118,9 +119,9 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
|
|||||||
config.CookieSecure = true
|
config.CookieSecure = true
|
||||||
}
|
}
|
||||||
|
|
||||||
extractors, cErr := CreateExtractors(config.TokenLookup)
|
extractors, err := createExtractors(config.TokenLookup, "")
|
||||||
if cErr != nil {
|
if err != nil {
|
||||||
panic(cErr)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
@ -131,7 +132,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 = randomString(config.TokenLength)
|
token = random.String(config.TokenLength) // Generate token
|
||||||
} else {
|
} else {
|
||||||
token = k.Value // Reuse token
|
token = k.Value // Reuse token
|
||||||
}
|
}
|
||||||
|
11
vendor/github.com/labstack/echo/v4/middleware/decompress.go
generated
vendored
11
vendor/github.com/labstack/echo/v4/middleware/decompress.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -12,14 +9,16 @@ 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"
|
||||||
@ -29,11 +28,13 @@ 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 {
|
||||||
|
23
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
23
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -27,26 +24,6 @@ var errFormExtractorValueMissing = errors.New("missing value in the form")
|
|||||||
// ValuesExtractor defines a function for extracting values (keys/tokens) from the given context.
|
// ValuesExtractor defines a function for extracting values (keys/tokens) from the given context.
|
||||||
type ValuesExtractor func(c echo.Context) ([]string, error)
|
type ValuesExtractor func(c echo.Context) ([]string, error)
|
||||||
|
|
||||||
// CreateExtractors creates ValuesExtractors from given lookups.
|
|
||||||
// Lookups is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
|
|
||||||
// to extract key from the request.
|
|
||||||
// Possible values:
|
|
||||||
// - "header:<name>" or "header:<name>:<cut-prefix>"
|
|
||||||
// `<cut-prefix>` is argument value to cut/trim prefix of the extracted value. This is useful if header
|
|
||||||
// value has static prefix like `Authorization: <auth-scheme> <authorisation-parameters>` where part that we
|
|
||||||
// want to cut is `<auth-scheme> ` note the space at the end.
|
|
||||||
// In case of basic authentication `Authorization: Basic <credentials>` prefix we want to remove is `Basic `.
|
|
||||||
// - "query:<name>"
|
|
||||||
// - "param:<name>"
|
|
||||||
// - "form:<name>"
|
|
||||||
// - "cookie:<name>"
|
|
||||||
//
|
|
||||||
// Multiple sources example:
|
|
||||||
// - "header:Authorization,header:X-Api-Key"
|
|
||||||
func CreateExtractors(lookups string) ([]ValuesExtractor, error) {
|
|
||||||
return createExtractors(lookups, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func createExtractors(lookups string, authScheme string) ([]ValuesExtractor, error) {
|
func createExtractors(lookups string, authScheme string) ([]ValuesExtractor, error) {
|
||||||
if lookups == "" {
|
if lookups == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
39
vendor/github.com/labstack/echo/v4/middleware/jwt.go
generated
vendored
39
vendor/github.com/labstack/echo/v4/middleware/jwt.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
//go:build go1.15
|
//go:build go1.15
|
||||||
// +build go1.15
|
// +build go1.15
|
||||||
|
|
||||||
@ -15,8 +12,9 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
// JWTConfig defines the config for JWT middleware.
|
// JWTConfig defines the config for JWT middleware.
|
||||||
type JWTConfig struct {
|
JWTConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -114,27 +112,29 @@ type JWTConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JWTSuccessHandler defines a function which is executed for a valid token.
|
// JWTSuccessHandler defines a function which is executed for a valid token.
|
||||||
type JWTSuccessHandler func(c echo.Context)
|
JWTSuccessHandler func(c echo.Context)
|
||||||
|
|
||||||
// JWTErrorHandler defines a function which is executed for an invalid token.
|
// JWTErrorHandler defines a function which is executed for an invalid token.
|
||||||
type JWTErrorHandler func(err error) error
|
JWTErrorHandler func(err error) error
|
||||||
|
|
||||||
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
|
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
|
||||||
type JWTErrorHandlerWithContext func(err error, c echo.Context) error
|
JWTErrorHandlerWithContext func(err error, c echo.Context) error
|
||||||
|
)
|
||||||
|
|
||||||
// Algorithms
|
// Algorithms
|
||||||
const (
|
const (
|
||||||
AlgorithmHS256 = "HS256"
|
AlgorithmHS256 = "HS256"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrJWTMissing is error that is returned when no JWToken was extracted from the request.
|
// Errors
|
||||||
var ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
|
var (
|
||||||
|
ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
|
||||||
// ErrJWTInvalid is error that is returned when middleware could not parse JWT correctly.
|
ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
|
||||||
var ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
// DefaultJWTConfig is the default JWT auth middleware config.
|
// DefaultJWTConfig is the default JWT auth middleware config.
|
||||||
var DefaultJWTConfig = JWTConfig{
|
DefaultJWTConfig = JWTConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
SigningMethod: AlgorithmHS256,
|
SigningMethod: AlgorithmHS256,
|
||||||
ContextKey: "user",
|
ContextKey: "user",
|
||||||
@ -144,6 +144,7 @@ var DefaultJWTConfig = JWTConfig{
|
|||||||
Claims: jwt.MapClaims{},
|
Claims: jwt.MapClaims{},
|
||||||
KeyFunc: nil,
|
KeyFunc: nil,
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// JWT returns a JSON Web Token (JWT) auth middleware.
|
// JWT returns a JSON Web Token (JWT) auth middleware.
|
||||||
//
|
//
|
||||||
@ -153,8 +154,6 @@ var DefaultJWTConfig = JWTConfig{
|
|||||||
//
|
//
|
||||||
// See: https://jwt.io/introduction
|
// See: https://jwt.io/introduction
|
||||||
// See `JWTConfig.TokenLookup`
|
// See `JWTConfig.TokenLookup`
|
||||||
//
|
|
||||||
// Deprecated: Please use https://github.com/labstack/echo-jwt instead
|
|
||||||
func JWT(key interface{}) echo.MiddlewareFunc {
|
func JWT(key interface{}) echo.MiddlewareFunc {
|
||||||
c := DefaultJWTConfig
|
c := DefaultJWTConfig
|
||||||
c.SigningKey = key
|
c.SigningKey = key
|
||||||
@ -163,8 +162,6 @@ func JWT(key interface{}) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
// JWTWithConfig returns a JWT auth middleware with config.
|
// JWTWithConfig returns a JWT auth middleware with config.
|
||||||
// See: `JWT()`.
|
// See: `JWT()`.
|
||||||
//
|
|
||||||
// Deprecated: Please use https://github.com/labstack/echo-jwt instead
|
|
||||||
func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
||||||
// Defaults
|
// Defaults
|
||||||
if config.Skipper == nil {
|
if config.Skipper == nil {
|
||||||
@ -195,9 +192,9 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
|||||||
config.ParseTokenFunc = config.defaultParseToken
|
config.ParseTokenFunc = config.defaultParseToken
|
||||||
}
|
}
|
||||||
|
|
||||||
extractors, cErr := createExtractors(config.TokenLookup, config.AuthScheme)
|
extractors, err := createExtractors(config.TokenLookup, config.AuthScheme)
|
||||||
if cErr != nil {
|
if err != nil {
|
||||||
panic(cErr)
|
panic(err)
|
||||||
}
|
}
|
||||||
if len(config.TokenLookupFuncs) > 0 {
|
if len(config.TokenLookupFuncs) > 0 {
|
||||||
extractors = append(config.TokenLookupFuncs, extractors...)
|
extractors = append(config.TokenLookupFuncs, extractors...)
|
||||||
@ -265,7 +262,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config *JWTConfig) defaultParseToken(auth string, c echo.Context) (interface{}, error) {
|
func (config *JWTConfig) defaultParseToken(auth string, c echo.Context) (interface{}, error) {
|
||||||
var token *jwt.Token
|
token := new(jwt.Token)
|
||||||
var err error
|
var err error
|
||||||
// Issue #647, #656
|
// Issue #647, #656
|
||||||
if _, ok := config.Claims.(jwt.MapClaims); ok {
|
if _, ok := config.Claims.(jwt.MapClaims); ok {
|
||||||
|
33
vendor/github.com/labstack/echo/v4/middleware/key_auth.go
generated
vendored
33
vendor/github.com/labstack/echo/v4/middleware/key_auth.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,8 +6,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
// KeyAuthConfig defines the config for KeyAuth middleware.
|
// KeyAuthConfig defines the config for KeyAuth middleware.
|
||||||
type KeyAuthConfig struct {
|
KeyAuthConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -51,23 +49,26 @@ type KeyAuthConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// KeyAuthValidator defines a function to validate KeyAuth credentials.
|
// KeyAuthValidator defines a function to validate KeyAuth credentials.
|
||||||
type KeyAuthValidator func(auth string, c echo.Context) (bool, error)
|
KeyAuthValidator func(auth string, c echo.Context) (bool, error)
|
||||||
|
|
||||||
// KeyAuthErrorHandler defines a function which is executed for an invalid key.
|
// KeyAuthErrorHandler defines a function which is executed for an invalid key.
|
||||||
type KeyAuthErrorHandler func(err error, c echo.Context) error
|
KeyAuthErrorHandler func(err error, c echo.Context) error
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// DefaultKeyAuthConfig is the default KeyAuth middleware config.
|
||||||
|
DefaultKeyAuthConfig = KeyAuthConfig{
|
||||||
|
Skipper: DefaultSkipper,
|
||||||
|
KeyLookup: "header:" + echo.HeaderAuthorization,
|
||||||
|
AuthScheme: "Bearer",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// ErrKeyAuthMissing is error type when KeyAuth middleware is unable to extract value from lookups
|
// ErrKeyAuthMissing is error type when KeyAuth middleware is unable to extract value from lookups
|
||||||
type ErrKeyAuthMissing struct {
|
type ErrKeyAuthMissing struct {
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultKeyAuthConfig is the default KeyAuth middleware config.
|
|
||||||
var DefaultKeyAuthConfig = KeyAuthConfig{
|
|
||||||
Skipper: DefaultSkipper,
|
|
||||||
KeyLookup: "header:" + echo.HeaderAuthorization,
|
|
||||||
AuthScheme: "Bearer",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns errors text
|
// Error returns errors text
|
||||||
func (e *ErrKeyAuthMissing) Error() string {
|
func (e *ErrKeyAuthMissing) Error() string {
|
||||||
return e.Err.Error()
|
return e.Err.Error()
|
||||||
@ -107,9 +108,9 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc {
|
|||||||
panic("echo: key-auth middleware requires a validator function")
|
panic("echo: key-auth middleware requires a validator function")
|
||||||
}
|
}
|
||||||
|
|
||||||
extractors, cErr := createExtractors(config.KeyLookup, config.AuthScheme)
|
extractors, err := createExtractors(config.KeyLookup, config.AuthScheme)
|
||||||
if cErr != nil {
|
if err != nil {
|
||||||
panic(cErr)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
25
vendor/github.com/labstack/echo/v4/middleware/logger.go
generated
vendored
25
vendor/github.com/labstack/echo/v4/middleware/logger.go
generated
vendored
@ -1,6 +1,3 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -17,8 +14,9 @@ import (
|
|||||||
"github.com/valyala/fasttemplate"
|
"github.com/valyala/fasttemplate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
// LoggerConfig defines the config for Logger middleware.
|
// LoggerConfig defines the config for Logger middleware.
|
||||||
type LoggerConfig struct {
|
LoggerConfig struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper Skipper
|
Skipper Skipper
|
||||||
|
|
||||||
@ -37,7 +35,6 @@ type LoggerConfig struct {
|
|||||||
// - host
|
// - host
|
||||||
// - method
|
// - method
|
||||||
// - path
|
// - path
|
||||||
// - route
|
|
||||||
// - protocol
|
// - protocol
|
||||||
// - referer
|
// - referer
|
||||||
// - user_agent
|
// - user_agent
|
||||||
@ -50,7 +47,6 @@ type LoggerConfig struct {
|
|||||||
// - header:<NAME>
|
// - header:<NAME>
|
||||||
// - query:<NAME>
|
// - query:<NAME>
|
||||||
// - form:<NAME>
|
// - form:<NAME>
|
||||||
// - custom (see CustomTagFunc field)
|
|
||||||
//
|
//
|
||||||
// Example "${remote_ip} ${status}"
|
// Example "${remote_ip} ${status}"
|
||||||
//
|
//
|
||||||
@ -60,11 +56,6 @@ type LoggerConfig struct {
|
|||||||
// Optional. Default value DefaultLoggerConfig.CustomTimeFormat.
|
// Optional. Default value DefaultLoggerConfig.CustomTimeFormat.
|
||||||
CustomTimeFormat string `yaml:"custom_time_format"`
|
CustomTimeFormat string `yaml:"custom_time_format"`
|
||||||
|
|
||||||
// CustomTagFunc is function called for `${custom}` tag to output user implemented text by writing it to buf.
|
|
||||||
// Make sure that outputted text creates valid JSON string with other logged tags.
|
|
||||||
// Optional.
|
|
||||||
CustomTagFunc func(c echo.Context, buf *bytes.Buffer) (int, error)
|
|
||||||
|
|
||||||
// Output is a writer where logs in JSON format are written.
|
// Output is a writer where logs in JSON format are written.
|
||||||
// Optional. Default value os.Stdout.
|
// Optional. Default value os.Stdout.
|
||||||
Output io.Writer
|
Output io.Writer
|
||||||
@ -73,9 +64,11 @@ type LoggerConfig struct {
|
|||||||
colorer *color.Color
|
colorer *color.Color
|
||||||
pool *sync.Pool
|
pool *sync.Pool
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
// DefaultLoggerConfig is the default Logger middleware config.
|
// DefaultLoggerConfig is the default Logger middleware config.
|
||||||
var DefaultLoggerConfig = LoggerConfig{
|
DefaultLoggerConfig = LoggerConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}",` +
|
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}",` +
|
||||||
`"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` +
|
`"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` +
|
||||||
@ -84,6 +77,7 @@ var DefaultLoggerConfig = LoggerConfig{
|
|||||||
CustomTimeFormat: "2006-01-02 15:04:05.00000",
|
CustomTimeFormat: "2006-01-02 15:04:05.00000",
|
||||||
colorer: color.New(),
|
colorer: color.New(),
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Logger returns a middleware that logs HTTP requests.
|
// Logger returns a middleware that logs HTTP requests.
|
||||||
func Logger() echo.MiddlewareFunc {
|
func Logger() echo.MiddlewareFunc {
|
||||||
@ -132,11 +126,6 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
if _, err = config.template.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
|
if _, err = config.template.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
|
||||||
switch tag {
|
switch tag {
|
||||||
case "custom":
|
|
||||||
if config.CustomTagFunc == nil {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return config.CustomTagFunc(c, buf)
|
|
||||||
case "time_unix":
|
case "time_unix":
|
||||||
return buf.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
|
return buf.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
case "time_unix_milli":
|
case "time_unix_milli":
|
||||||
@ -173,8 +162,6 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
|
|||||||
p = "/"
|
p = "/"
|
||||||
}
|
}
|
||||||
return buf.WriteString(p)
|
return buf.WriteString(p)
|
||||||
case "route":
|
|
||||||
return buf.WriteString(c.Path())
|
|
||||||
case "protocol":
|
case "protocol":
|
||||||
return buf.WriteString(req.Proto)
|
return buf.WriteString(req.Proto)
|
||||||
case "referer":
|
case "referer":
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user