diff --git a/code/go/0chain.net/blobbercore/handler/grpc_commit_handler.go b/code/go/0chain.net/blobbercore/handler/grpc_commit_handler.go index 43a4975ce..cb522cbd2 100644 --- a/code/go/0chain.net/blobbercore/handler/grpc_commit_handler.go +++ b/code/go/0chain.net/blobbercore/handler/grpc_commit_handler.go @@ -28,7 +28,7 @@ func (b *blobberGRPCService) Commit(ctx context.Context, req *blobbergrpc.Commit if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Header.Set("Content-Type", writer.FormDataContentType()) resp, err := CommitHandler(ctx, r) diff --git a/code/go/0chain.net/blobbercore/handler/grpc_handler.go b/code/go/0chain.net/blobbercore/handler/grpc_handler.go index 99ea0fdc3..67989eeb6 100644 --- a/code/go/0chain.net/blobbercore/handler/grpc_handler.go +++ b/code/go/0chain.net/blobbercore/handler/grpc_handler.go @@ -22,7 +22,7 @@ func (b *blobberGRPCService) GetAllocation(ctx context.Context, request *blobber if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), "") + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), "") r.Form = map[string][]string{"id": {request.Id}} resp, err := AllocationHandler(ctx, r) @@ -38,7 +38,7 @@ func (b *blobberGRPCService) GetFileMetaData(ctx context.Context, req *blobbergr if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path_hash": {req.PathHash}, "path": {req.Path}, @@ -58,7 +58,7 @@ func (b *blobberGRPCService) GetFileStats(ctx context.Context, req *blobbergrpc. if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, @@ -77,7 +77,7 @@ func (b *blobberGRPCService) ListEntities(ctx context.Context, req *blobbergrpc. if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, @@ -97,7 +97,7 @@ func (b *blobberGRPCService) GetObjectPath(ctx context.Context, req *blobbergrpc if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "block_num": {req.BlockNum}, @@ -116,7 +116,7 @@ func (b *blobberGRPCService) GetReferencePath(ctx context.Context, req *blobberg if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "paths": {req.Paths}, @@ -135,7 +135,7 @@ func (b *blobberGRPCService) GetObjectTree(ctx context.Context, req *blobbergrpc if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, } @@ -153,7 +153,7 @@ func (b *blobberGRPCService) CalculateHash(ctx context.Context, req *blobbergrpc if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "paths": {req.Paths}, @@ -172,7 +172,7 @@ func (b *blobberGRPCService) CommitMetaTxn(ctx context.Context, req *blobbergrpc if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, @@ -193,7 +193,7 @@ func (b *blobberGRPCService) Collaborator(ctx context.Context, req *blobbergrpc. if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, diff --git a/code/go/0chain.net/blobbercore/handler/grpc_helpers.go b/code/go/0chain.net/blobbercore/handler/grpc_helpers.go new file mode 100644 index 000000000..9f9889b4e --- /dev/null +++ b/code/go/0chain.net/blobbercore/handler/grpc_helpers.go @@ -0,0 +1,72 @@ +package handler + +import ( + "context" + "github.com/0chain/blobber/code/go/0chain.net/blobbercore/blobbergrpc/proto" + "github.com/0chain/blobber/code/go/0chain.net/core/common" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + "net/http" +) + +type gRPCHeaderMetadata struct { + Client string + ClientKey string + ClientSignature string +} + + +func registerGRPCServices(r *mux.Router, server *grpc.Server) { + blobberService := newGRPCBlobberService() + grpcGatewayHandler := runtime.NewServeMux( + runtime.WithIncomingHeaderMatcher(CustomMatcher), + ) + + blobbergrpc.RegisterBlobberServiceServer(server, blobberService) + _ = blobbergrpc.RegisterBlobberServiceHandlerServer(context.Background(), grpcGatewayHandler, blobberService) + r.PathPrefix("/").Handler(grpcGatewayHandler) +} + +func getGRPCMetaDataFromCtx(ctx context.Context) *gRPCHeaderMetadata { + metaData := &gRPCHeaderMetadata{} + + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return metaData + } + + getMetaData := func(key string) string { + list := md.Get(key) + if len(list) > 0 { + return list[0] + } + return "" + } + + metaData.Client = getMetaData(common.ClientHeader) + metaData.ClientKey = getMetaData(common.ClientKeyHeader) + metaData.ClientSignature = getMetaData(common.ClientSignatureHeader) + return metaData +} + +func httpRequestWithMetaData(r *http.Request, md *gRPCHeaderMetadata, alloc string) { + r.Header.Set(common.ClientHeader, md.Client) + r.Header.Set(common.ClientKeyHeader, md.ClientKey) + r.Header.Set(common.ClientSignatureHeader, md.ClientSignature) + *r = *mux.SetURLVars(r, map[string]string{"allocation": alloc}) +} + +func CustomMatcher(key string) (string, bool) { + switch key { + case common.ClientHeader: + return key, true + case common.ClientKeyHeader: + return key, true + case common.ClientSignatureHeader: + return key, true + default: + return runtime.DefaultHeaderMatcher(key) + } +} diff --git a/code/go/0chain.net/blobbercore/handler/grpc_middleware.go b/code/go/0chain.net/blobbercore/handler/grpc_middleware.go index ec027b6fd..42097f244 100644 --- a/code/go/0chain.net/blobbercore/handler/grpc_middleware.go +++ b/code/go/0chain.net/blobbercore/handler/grpc_middleware.go @@ -83,7 +83,6 @@ func NewGRPCServerWithMiddlewares(limiter grpc_ratelimit.Limiter, r *mux.Router) wrappedServer.ServeHTTP(w, r) return } - h.ServeHTTP(w, r) }) }) diff --git a/code/go/0chain.net/blobbercore/handler/helper.go b/code/go/0chain.net/blobbercore/handler/helper.go deleted file mode 100644 index 7e9004957..000000000 --- a/code/go/0chain.net/blobbercore/handler/helper.go +++ /dev/null @@ -1,20 +0,0 @@ -package handler - -import ( - "context" - - blobbergrpc "github.com/0chain/blobber/code/go/0chain.net/blobbercore/blobbergrpc/proto" - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - "google.golang.org/grpc" -) - -func registerGRPCServices(r *mux.Router, server *grpc.Server) { - blobberService := newGRPCBlobberService() - grpcGatewayHandler := runtime.NewServeMux() - - blobbergrpc.RegisterBlobberServiceServer(server, blobberService) - _ = blobbergrpc.RegisterBlobberServiceHandlerServer(context.Background(), grpcGatewayHandler, blobberService) - r.PathPrefix("/").Handler(grpcGatewayHandler) - -} diff --git a/code/go/0chain.net/blobbercore/handler/metadata.go b/code/go/0chain.net/blobbercore/handler/metadata.go deleted file mode 100644 index c07a14ea6..000000000 --- a/code/go/0chain.net/blobbercore/handler/metadata.go +++ /dev/null @@ -1,46 +0,0 @@ -package handler - -import ( - "context" - "net/http" - - "github.com/gorilla/mux" - - "github.com/0chain/blobber/code/go/0chain.net/core/common" - "google.golang.org/grpc/metadata" -) - -type GRPCMetaData struct { - Client string - ClientKey string - ClientSignature string -} - -func GetGRPCMetaDataFromCtx(ctx context.Context) *GRPCMetaData { - metaData := &GRPCMetaData{} - - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - return metaData - } - - getMetaData := func(key string) string { - list := md.Get(key) - if len(list) > 0 { - return list[0] - } - return "" - } - - metaData.Client = getMetaData(common.ClientHeader) - metaData.ClientKey = getMetaData(common.ClientKeyHeader) - metaData.ClientSignature = getMetaData(common.ClientSignatureHeader) - return metaData -} - -func httpRequestWithMetaData(r *http.Request, md *GRPCMetaData, alloc string) { - r.Header.Set(common.ClientHeader, md.Client) - r.Header.Set(common.ClientKeyHeader, md.ClientKey) - r.Header.Set(common.ClientSignatureHeader, md.ClientSignature) - *r = *mux.SetURLVars(r, map[string]string{"allocation": alloc}) -} diff --git a/code/go/0chain.net/blobbercore/handler/object_operation_grpc_handler.go b/code/go/0chain.net/blobbercore/handler/object_operation_grpc_handler.go index 27bb7cc54..dcb069c77 100644 --- a/code/go/0chain.net/blobbercore/handler/object_operation_grpc_handler.go +++ b/code/go/0chain.net/blobbercore/handler/object_operation_grpc_handler.go @@ -12,7 +12,7 @@ func (b *blobberGRPCService) UpdateObjectAttributes(ctx context.Context, req *bl if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, @@ -33,7 +33,7 @@ func (b *blobberGRPCService) CopyObject(ctx context.Context, req *blobbergrpc.Co if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, @@ -54,7 +54,7 @@ func (b *blobberGRPCService) RenameObject(ctx context.Context, req *blobbergrpc. if err != nil { return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "path_hash": {req.PathHash}, @@ -76,7 +76,7 @@ func (b *blobberGRPCService) DownloadFile(ctx context.Context, req *blobbergrpc. return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) resp, err := DownloadHandler(ctx, r) if err != nil { @@ -93,7 +93,7 @@ func (b *blobberGRPCService) UploadFile(ctx context.Context, req *blobbergrpc.Up return nil, err } - httpRequestWithMetaData(r, GetGRPCMetaDataFromCtx(ctx), req.Allocation) + httpRequestWithMetaData(r, getGRPCMetaDataFromCtx(ctx), req.Allocation) r.Form = map[string][]string{ "path": {req.Path}, "connection_id": {req.ConnectionId}, diff --git a/code/go/0chain.net/blobbercore/handler/protocol.go b/code/go/0chain.net/blobbercore/handler/protocol.go index b232ff92f..c3bfad812 100644 --- a/code/go/0chain.net/blobbercore/handler/protocol.go +++ b/code/go/0chain.net/blobbercore/handler/protocol.go @@ -1,18 +1,18 @@ package handler import ( - "sync" - "time" - "errors" "context" "encoding/json" + "errors" + "sync" + "time" "github.com/0chain/blobber/code/go/0chain.net/blobbercore/config" + "github.com/0chain/blobber/code/go/0chain.net/core/chain" . "github.com/0chain/blobber/code/go/0chain.net/core/logging" "github.com/0chain/blobber/code/go/0chain.net/core/node" "github.com/0chain/blobber/code/go/0chain.net/core/transaction" "github.com/0chain/blobber/code/go/0chain.net/core/util" - "github.com/0chain/blobber/code/go/0chain.net/core/chain" "github.com/0chain/gosdk/zcncore" "go.uber.org/zap" diff --git a/go.sum b/go.sum index 519280b70..0b3b0d780 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/0chain/gosdk v1.1.6 h1:urbc9aTp57HAUVgJWP6TsSgRKX61hLBwtSyMV/ngCBo= -github.com/0chain/gosdk v1.1.6/go.mod h1:edV5GwogiT6nK2+s4QcFCz3saUhkuFK6EIqNJfOt8xc= github.com/0chain/gosdk v1.2.68-0.20210701180605-719eb403820c h1:cTxcdg5VcfHLoiT1C33gskjN2RJQqkOXpIuuUXBUAig= github.com/0chain/gosdk v1.2.68-0.20210701180605-719eb403820c/go.mod h1:EntD+g2xA5SLUAm6JABMhkYAlTOmp0XhSnf/5xfwnV4= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= @@ -44,9 +42,7 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= 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-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= @@ -97,7 +93,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -243,7 +238,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/herumi/bls-go-binary v0.0.0-20191119080710-898950e1a520 h1:3ek8BJos3JW72rvPzGAWZwJ/iXjOyPSCUI4nAFnTPvg= github.com/herumi/bls-go-binary v0.0.0-20191119080710-898950e1a520/go.mod h1:uTBfU/n3h1aOYIl5nNTbLn5dUfNkF1P97JTaz3bdvro= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/idubinskiy/schematyper v0.0.0-20190118213059-f71b40dac30d/go.mod h1:xVHEhsiSJJnT0jlcQpQUg+GyoLf0i0xciM1kqWTGT58= github.com/improbable-eng/grpc-web v0.14.0 h1:GdoK+cXABdB+1keuqsV1drSFO2XLYIxqt/4Rj8SWGBk= github.com/improbable-eng/grpc-web v0.14.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -525,7 +519,6 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -548,12 +541,10 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200329125638-4c31acba0007/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=