From 73c2443d255b0dc27557c21cacd73a05002cc16f Mon Sep 17 00:00:00 2001 From: WeebDataHoarder <57538841+WeebDataHoarder@users.noreply.github.com> Date: Tue, 8 Feb 2022 18:27:27 +0100 Subject: [PATCH] Update to go 1.18, added Garbage collection for badger --- .drone.yml | 2 +- Dockerfile | 2 +- FinalCommander.go | 304 +++++++++++++++++++++++--------------------- README.md | 5 +- content/database.go | 31 ++++- go.mod | 20 +-- go.sum | 41 +++--- 7 files changed, 219 insertions(+), 186 deletions(-) diff --git a/.drone.yml b/.drone.yml index 95b5e49..1b95d3a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,7 +5,7 @@ name: default steps: - name: backend - image: golang:1.17-bullseye + image: golang:1.18-rc-bullseye commands: - go build -v -o fcmm . diff --git a/Dockerfile b/Dockerfile index 7ccbc0f..aec7055 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17-bullseye +FROM golang:1.18-rc-bullseye COPY . /src diff --git a/FinalCommander.go b/FinalCommander.go index b136586..8829d88 100644 --- a/FinalCommander.go +++ b/FinalCommander.go @@ -76,6 +76,160 @@ func setCORSHeaders(ctx *httputils.RequestContext) { ctx.SetResponseHeader("Cross-Origin-Opener-Policy", "unsafe-none") } +func handleHexHash(pathElements []string, ctx *httputils.RequestContext, host string) { + + if len(pathElements) < 3 { + ctx.SetResponseCode(http.StatusBadRequest) + return + } + + hashType := strings.ToLower(pathElements[1]) + + hash, err := hex.DecodeString(pathElements[2]) + if err != nil { + ctx.SetResponseCode(http.StatusBadRequest) + return + } + + var mh multihash.Multihash + if hashType == "sha256" && len(hash) == 32 { + mh, _ = multihash.Encode(hash, multihash.SHA2_256) + } else if hashType == "md5" && len(hash) == 16 { + mh, _ = multihash.Encode(hash, multihash.MD5) + } else { + ctx.SetResponseCode(http.StatusNotImplemented) + return + } + key := content.NewHashIdentifierFromMultihash(mh) + + var skip []int + + entry := getContentEntry(key) + + if len(pathElements) > 3 { + + if pathElements[3] == "information" { + ctx.SetResponseCode(http.StatusOK) + ctx.SetResponseHeader("Content-Type", "application/json") + if entry != nil { + b, _ := json.Marshal(struct { + Known bool `json:"known"` + CID string `json:"cid"` + AccessTime int64 `json:"accessTime"` + CheckTime int64 `json:"checkTime"` + InvalidCount int `json:"invalidCount"` + }{ + Known: true, + CID: entry.CID().String(), + AccessTime: entry.AccessTime, + CheckTime: entry.CheckTime, + InvalidCount: len(entry.InvalidList), + }) + + ctx.ServeBytes(b) + } else { + b, _ := json.Marshal(struct { + Known bool `json:"known"` + CID string `json:"cid"` + }{ + Known: false, + CID: key.CID().String(), + }) + + ctx.ServeBytes(b) + } + return + } else if pathElements[3] == "drop" { //Drop key from cache + ctx.SetResponseCode(http.StatusOK) + ctx.SetResponseHeader("Content-Type", "text/plain") + _ = db.RemoveEntry(key) + if entry != nil && !entry.Key.Equals(key) { + _ = db.RemoveEntry(&entry.Key) + } + ctx.ServeBytes([]byte{}) + return + } + + //TODO: update entries with these instant returns + data, err := MakyuuIchaival.Bech32Encoding.DecodeString(pathElements[3]) + if err != nil { + ctx.SetResponseCode(http.StatusBadRequest) + return + } + skip = utilities.DecodeIntegerList(data) + } + + if entry != nil { + oldSkip := skip + skip = entry.InvalidList + for _, ci := range oldSkip { + if !entry.InInvalidList(ci) { + skip = append(skip, ci) + } + } + contentServer := selectNextContentServer(skip) + if contentServer == nil { + ctx.SetResponseCode(http.StatusNotFound) + return + } + + ctx.DoRedirect(contentServer.GetContentURL(entry, privateKey, skip)+host, http.StatusFound) + } else { + contentServer := selectNextContentServer(skip) + if contentServer == nil { + ctx.SetResponseCode(http.StatusNotFound) + return + } + + //TODO: only trigger this when we don't get a 404 + go func() { + var newInvalidList []int + var e *content.Entry + + for _, c := range contentServers { + if !c.GetCheckResult() { + continue + } + + result, err := c.CheckEntryKey(key, privateKey) + if result != nil { + if e == nil { + e = &content.Entry{ + Key: *result, + Version: 0, + AccessTime: time.Now().UTC().Unix(), + CheckTime: time.Now().UTC().Unix() + 3600*24*3, // Check sooner after addition, not all servers might have it yet + } + } + } else if err == nil { + newInvalidList = append(newInvalidList, c.Index) + } + } + + if e != nil { + if !key.IsKey() { //Check for entry already existing + entry := getContentEntry(&e.Key) + + if entry != nil { + e = entry + } + //Add alias mapping + _ = db.SetAlias(&content.Alias{ + Key: *key, + Identifier: e.Key, + }) + } + + e.AccessTime = time.Now().UTC().Unix() + e.InvalidList = newInvalidList + _ = db.SetEntry(e) + } + }() + + ctx.DoRedirect(contentServer.GetHashURL(mh, privateKey, skip)+host, http.StatusFound) + } +} + func handle(ctx *httputils.RequestContext) { if len(ctx.GetRequestHeader("Host")) > 0 && ctx.GetRequestHeader("Host") == ctx.GetTLSServerName() { //Prevents rebinding / DNS stuff ctx.SetResponseCode(http.StatusNotFound) @@ -98,155 +252,9 @@ func handle(ctx *httputils.RequestContext) { setOtherHeaders(ctx) setCORSHeaders(ctx) pathElements := strings.Split(ctx.GetPath(), "/") - if len(pathElements) < 3 { - ctx.SetResponseCode(http.StatusBadRequest) - return - } - hashType := strings.ToLower(pathElements[1]) - - hash, err := hex.DecodeString(pathElements[2]) - if err != nil { - ctx.SetResponseCode(http.StatusBadRequest) - return - } - - var mh multihash.Multihash - if hashType == "sha256" && len(hash) == 32 { - mh, _ = multihash.Encode(hash, multihash.SHA2_256) - } else if hashType == "md5" && len(hash) == 16 { - mh, _ = multihash.Encode(hash, multihash.MD5) - } else { - ctx.SetResponseCode(http.StatusNotImplemented) - return - } - key := content.NewHashIdentifierFromMultihash(mh) - - var skip []int - - entry := getContentEntry(key) - - if len(pathElements) > 3 { - - if pathElements[3] == "information" { - ctx.SetResponseCode(http.StatusOK) - ctx.SetResponseHeader("Content-Type", "application/json") - if entry != nil { - b, _ := json.Marshal(struct { - Known bool `json:"known"` - CID string `json:"cid"` - AccessTime int64 `json:"accessTime"` - CheckTime int64 `json:"checkTime"` - InvalidCount int `json:"invalidCount"` - }{ - Known: true, - CID: entry.CID().String(), - AccessTime: entry.AccessTime, - CheckTime: entry.CheckTime, - InvalidCount: len(entry.InvalidList), - }) - - ctx.ServeBytes(b) - } else { - b, _ := json.Marshal(struct { - Known bool `json:"known"` - CID string `json:"cid"` - }{ - Known: false, - CID: key.CID().String(), - }) - - ctx.ServeBytes(b) - } - return - } else if pathElements[3] == "drop" { //Drop key from cache - ctx.SetResponseCode(http.StatusNoContent) - _ = db.RemoveEntry(key) - if entry != nil && !entry.Key.Equals(key) { - _ = db.RemoveEntry(&entry.Key) - } - ctx.ServeBytes([]byte{}) - return - } - - //TODO: update entries with these instant returns - data, err := MakyuuIchaival.Bech32Encoding.DecodeString(pathElements[3]) - if err != nil { - ctx.SetResponseCode(http.StatusBadRequest) - return - } - skip = utilities.DecodeIntegerList(data) - } - - if entry != nil { - oldSkip := skip - skip = entry.InvalidList - for _, ci := range oldSkip { - if !entry.InInvalidList(ci) { - skip = append(skip, ci) - } - } - contentServer := selectNextContentServer(skip) - if contentServer == nil { - ctx.SetResponseCode(http.StatusNotFound) - return - } - - ctx.DoRedirect(contentServer.GetContentURL(entry, privateKey, skip)+host, http.StatusFound) - } else { - contentServer := selectNextContentServer(skip) - if contentServer == nil { - ctx.SetResponseCode(http.StatusNotFound) - return - } - - //TODO: only trigger this when we don't get a 404 - go func() { - var newInvalidList []int - var e *content.Entry - - for _, c := range contentServers { - if !c.GetCheckResult() { - continue - } - - result, err := c.CheckEntryKey(key, privateKey) - if result != nil { - if e == nil { - e = &content.Entry{ - Key: *result, - Version: 0, - AccessTime: time.Now().UTC().Unix(), - CheckTime: time.Now().UTC().Unix() + 3600*24*3, // Check sooner after addition, not all servers might have it yet - } - } - } else if err == nil { - newInvalidList = append(newInvalidList, c.Index) - } - } - - if e != nil { - if !key.IsKey() { //Check for entry already existing - entry := getContentEntry(&e.Key) - - if entry != nil { - e = entry - } - //Add alias mapping - _ = db.SetAlias(&content.Alias{ - Key: *key, - Identifier: e.Key, - }) - } - - e.AccessTime = time.Now().UTC().Unix() - e.InvalidList = newInvalidList - _ = db.SetEntry(e) - } - }() - - ctx.DoRedirect(contentServer.GetHashURL(mh, privateKey, skip)+host, http.StatusFound) - } + //TODO: handle ni RFC 6920 + handleHexHash(pathElements, ctx, host) } else if ctx.IsOptions() { setOtherHeaders(ctx) setCORSHeaders(ctx) diff --git a/README.md b/README.md index b0eaeab..23590fa 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ Content-addressable storage redirector. ## Usage +* `$ PRIVATE_KEY= ./fcmm -servers "server1:7777/100,server2:7777/100, -certificate example.crt -keypair example.key` +* Running without `PRIVATE_KEY` will generate an Ed25519 keypair first time, then exit. + `$ go run .` Build via `$ go build -o fcmm` @@ -13,7 +16,7 @@ Build via `$ go build -o fcmm` * Use pip certbot * Edit .env to add paths to certificates -``` +```bash $ certbot certonly \ --standalone \ --key-type=ecdsa --elliptic-curve=secp256r1 \ diff --git a/content/database.go b/content/database.go index 3198cb8..86e18ed 100644 --- a/content/database.go +++ b/content/database.go @@ -3,10 +3,13 @@ package content import ( "fmt" "github.com/dgraph-io/badger/v3" + "time" ) type Database struct { - handle *badger.DB + handle *badger.DB + closeChannel chan bool + gcTicker *time.Ticker } func OpenDatabase(path string) (*Database, error) { @@ -17,9 +20,28 @@ func OpenDatabase(path string) (*Database, error) { return nil, err } - return &Database{ - handle: db, - }, nil + database := &Database{ + handle: db, + gcTicker: time.NewTicker(time.Minute * 5), + closeChannel: make(chan bool), + } + + go func() { + defer database.gcTicker.Stop() + + for { + select { + case <-database.gcTicker.C: + for database.handle.RunValueLogGC(0.5) == nil { + + } + case <-database.closeChannel: + return + } + } + }() + + return database, nil } func (db *Database) GetEntry(key HashIdentifier) *Entry { @@ -83,5 +105,6 @@ func (db *Database) getChain(txn *badger.Txn, key HashIdentifier) (*Entry, error } func (db *Database) Close() error { + db.closeChannel <- true return db.handle.Close() } diff --git a/go.mod b/go.mod index 7e5009b..3ecd0a7 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module git.gammaspectra.live/S.O.N.G/FinalCommander -go 1.17 +go 1.18 require ( - git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220119201433-39050c16549d + git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220208171845-da95775a33e7 github.com/cloudflare/circl v1.1.0 github.com/dgraph-io/badger/v3 v3.2103.2 github.com/ipfs/go-cid v0.1.0 @@ -17,7 +17,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/dgrr/http2 v0.3.3 // indirect + github.com/dgrr/http2 v0.3.4 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect @@ -27,8 +27,8 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/flatbuffers v2.0.5+incompatible // indirect - github.com/klauspost/compress v1.14.1 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/klauspost/compress v1.14.2 // indirect + github.com/klauspost/cpuid/v2 v2.0.11 // indirect github.com/lucas-clemente/quic-go v0.25.0 // indirect github.com/marten-seemann/qpack v0.2.1 // indirect github.com/marten-seemann/qtls-go1-16 v0.1.4 // indirect @@ -46,15 +46,15 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.32.0 // indirect + github.com/valyala/fasthttp v1.33.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect + golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect golang.org/x/mod v0.5.1 // indirect - golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect + golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.8 // indirect + golang.org/x/tools v0.1.9 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index a0edb99..eabba0e 100644 --- a/go.sum +++ b/go.sum @@ -7,10 +7,8 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220118183219-7bfcd667a183 h1:wF+oxs88n5p2O5ixy/vJN4KYefYOgwVmx+8a0xB7TPc= -git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220118183219-7bfcd667a183/go.mod h1:z6KcP5RPhMxDJaVU48sBhiYRCJ6ZJBbx1iIhkUrrhfY= -git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220119201433-39050c16549d h1:hgO2pPDG/cSFmCh7uzvbqvWHzSdPfO7sk2GuY929JyA= -git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220119201433-39050c16549d/go.mod h1:z6KcP5RPhMxDJaVU48sBhiYRCJ6ZJBbx1iIhkUrrhfY= +git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220208171845-da95775a33e7 h1:4n8x8qK1YwRQX3CotVqiuYG7v7TbrSNECxTUwTfGppM= +git.gammaspectra.live/S.O.N.G/MakyuuIchaival v0.0.0-20220208171845-da95775a33e7/go.mod h1:Z2MpldBF7zZIAFVVXkbHa/VbZWqMFj/6FqIgR73l+VE= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -47,8 +45,8 @@ github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHH github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrr/http2 v0.3.3 h1:F5BlR5CCMCSoEuD6oQcUk9fercKwg01LoArgUP1ycJ4= -github.com/dgrr/http2 v0.3.3/go.mod h1:OrmrVjQp6qa+E3VEiNB+fqpfl+8D9k1ZbBfK4RKU8D0= +github.com/dgrr/http2 v0.3.4 h1:yFiuwKV+SaGcySqsw4FsbdOswfZfSU7sgVXPN1zmykU= +github.com/dgrr/http2 v0.3.4/go.mod h1:OrmrVjQp6qa+E3VEiNB+fqpfl+8D9k1ZbBfK4RKU8D0= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= @@ -137,12 +135,13 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds= github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw= +github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A= +github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= 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.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -267,8 +266,8 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT 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/fasthttp v1.28.0/go.mod h1:cmWIqlu99AO/RKcp1HWaViTqc57FswJOfYYdPJBl8BA= -github.com/valyala/fasthttp v1.32.0 h1:keswgWzyKyNIIjz2a7JmCYHOOIkRp6HMx9oTV6QrZWY= -github.com/valyala/fasthttp v1.32.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/fasthttp v1.33.0 h1:mHBKd98J5NcXuBddgjvim1i3kWzlng1SzLhrnBOU9g8= +github.com/valyala/fasthttp v1.33.0/go.mod h1:KJRK/MXx0J+yd0c5hlR+s1tIHD72sniU8ZJjl97LIw4= github.com/valyala/fastrand v1.0.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= @@ -279,7 +278,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/yuin/goldmark v1.1.27/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/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= @@ -297,8 +295,9 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab h1:lnZ4LoV0UMdibeCUfIB2a4uFwRu491WX/VB2reB8xNc= +golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -329,10 +328,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs= -golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -374,9 +373,9 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc 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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc= +golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -401,8 +400,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w= -golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= 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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=