| @@ -3,6 +3,7 @@ package cmdline | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| "gitlink.org.cn/cloudream/storage/client/internal/config" | |||||
| "gitlink.org.cn/cloudream/storage/client/internal/http" | "gitlink.org.cn/cloudream/storage/client/internal/http" | ||||
| ) | ) | ||||
| @@ -17,8 +18,13 @@ func ServeHTTP(ctx CommandContext, args []string) error { | |||||
| listenAddr = args[0] | listenAddr = args[0] | ||||
| } | } | ||||
| awsAuth, err := http.NewAWSAuth(config.Cfg().AuthAccessKey, config.Cfg().AuthSecretKey) | |||||
| if err != nil { | |||||
| return fmt.Errorf("new aws auth: %w", err) | |||||
| } | |||||
| // 创建一个新的HTTP服务器实例。 | // 创建一个新的HTTP服务器实例。 | ||||
| httpSvr, err := http.NewServer(listenAddr, ctx.Cmdline.Svc) | |||||
| httpSvr, err := http.NewServer(listenAddr, ctx.Cmdline.Svc, awsAuth) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("new http server: %w", err) | return fmt.Errorf("new http server: %w", err) | ||||
| } | } | ||||
| @@ -22,7 +22,10 @@ type Config struct { | |||||
| Connectivity connectivity.Config `json:"connectivity"` | Connectivity connectivity.Config `json:"connectivity"` | ||||
| Downloader downloader.Config `json:"downloader"` | Downloader downloader.Config `json:"downloader"` | ||||
| DownloadStrategy strategy.Config `json:"downloadStrategy"` | DownloadStrategy strategy.Config `json:"downloadStrategy"` | ||||
| StorageID cdssdk.StorageID `json:"storageID"` // TODO 进行访问量统计时,当前客户端所属的存储ID。临时解决方案。 | |||||
| StorageID cdssdk.StorageID `json:"storageID"` // TODO 进行访问量统计时,当前客户端所属的存储ID。临时解决方案。 | |||||
| AuthAccessKey string `json:"authAccessKey"` // TODO 临时办法 | |||||
| AuthSecretKey string `json:"authSecretKey"` | |||||
| MaxHTTPBodySize int64 `json:"maxHttpBodySize"` | |||||
| } | } | ||||
| var cfg Config | var cfg Config | ||||
| @@ -0,0 +1,197 @@ | |||||
| package http | |||||
| import ( | |||||
| "bytes" | |||||
| "context" | |||||
| "crypto/sha256" | |||||
| "encoding/hex" | |||||
| "fmt" | |||||
| "io" | |||||
| "net/http" | |||||
| "strings" | |||||
| "time" | |||||
| "github.com/aws/aws-sdk-go-v2/aws" | |||||
| v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" | |||||
| "github.com/aws/aws-sdk-go-v2/credentials" | |||||
| "github.com/gin-gonic/gin" | |||||
| "gitlink.org.cn/cloudream/common/consts/errorcode" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | |||||
| "gitlink.org.cn/cloudream/storage/client/internal/config" | |||||
| ) | |||||
| const ( | |||||
| AuthRegion = "any" | |||||
| AuthService = "jcs" | |||||
| AuthorizationHeader = "Authorization" | |||||
| ) | |||||
| type AWSAuth struct { | |||||
| cred aws.Credentials | |||||
| signer *v4.Signer | |||||
| } | |||||
| func NewAWSAuth(accessKey string, secretKey string) (*AWSAuth, error) { | |||||
| prod := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "") | |||||
| cred, err := prod.Retrieve(context.TODO()) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| return &AWSAuth{ | |||||
| cred: cred, | |||||
| signer: v4.NewSigner(), | |||||
| }, nil | |||||
| } | |||||
| func (a *AWSAuth) Auth(c *gin.Context) { | |||||
| authorizationHeader := c.GetHeader(AuthorizationHeader) | |||||
| if authorizationHeader == "" { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.Unauthorized, "authorization header is missing")) | |||||
| return | |||||
| } | |||||
| _, headers, reqSig, err := parseAuthorizationHeader(authorizationHeader) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.Unauthorized, "invalid Authorization header format")) | |||||
| return | |||||
| } | |||||
| // 限制请求体大小 | |||||
| rd := io.LimitReader(c.Request.Body, config.Cfg().MaxHTTPBodySize) | |||||
| body, err := io.ReadAll(rd) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "read request body failed")) | |||||
| return | |||||
| } | |||||
| payloadHash := sha256.Sum256(body) | |||||
| hexPayloadHash := hex.EncodeToString(payloadHash[:]) | |||||
| // 构造验签用的请求 | |||||
| verifyReq, err := http.NewRequest(c.Request.Method, c.Request.URL.String(), nil) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusOK, Failed(errorcode.OperationFailed, err.Error())) | |||||
| return | |||||
| } | |||||
| for _, h := range headers { | |||||
| verifyReq.Header.Add(h, c.Request.Header.Get(h)) | |||||
| } | |||||
| verifyReq.Host = c.Request.Host | |||||
| timestamp, err := time.Parse("20060102T150405Z", c.GetHeader("X-Amz-Date")) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "invalid X-Amz-Date header format")) | |||||
| return | |||||
| } | |||||
| signer := v4.NewSigner() | |||||
| err = signer.SignHTTP(context.TODO(), a.cred, verifyReq, hexPayloadHash, AuthService, AuthRegion, timestamp) | |||||
| if err != nil { | |||||
| logger.Warnf("sign request: %v", err) | |||||
| c.AbortWithStatusJSON(http.StatusOK, Failed(errorcode.OperationFailed, "sign request failed")) | |||||
| return | |||||
| } | |||||
| verifySig := a.getSignature(verifyReq) | |||||
| if !strings.EqualFold(verifySig, reqSig) { | |||||
| c.AbortWithStatusJSON(http.StatusOK, Failed(errorcode.Unauthorized, "signature mismatch")) | |||||
| return | |||||
| } | |||||
| c.Request.Body = io.NopCloser(bytes.NewReader(body)) | |||||
| c.Next() | |||||
| } | |||||
| func (a *AWSAuth) AuthWithoutBody(c *gin.Context) { | |||||
| authorizationHeader := c.GetHeader(AuthorizationHeader) | |||||
| if authorizationHeader == "" { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.Unauthorized, "authorization header is missing")) | |||||
| return | |||||
| } | |||||
| _, headers, reqSig, err := parseAuthorizationHeader(authorizationHeader) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.Unauthorized, "invalid Authorization header format")) | |||||
| return | |||||
| } | |||||
| // 构造验签用的请求 | |||||
| verifyReq, err := http.NewRequest(c.Request.Method, c.Request.URL.String(), nil) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusOK, Failed(errorcode.OperationFailed, err.Error())) | |||||
| return | |||||
| } | |||||
| for _, h := range headers { | |||||
| verifyReq.Header.Add(h, c.Request.Header.Get(h)) | |||||
| } | |||||
| verifyReq.Host = c.Request.Host | |||||
| timestamp, err := time.Parse("20060102T150405Z", c.GetHeader("X-Amz-Date")) | |||||
| if err != nil { | |||||
| c.AbortWithStatusJSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "invalid X-Amz-Date header format")) | |||||
| return | |||||
| } | |||||
| err = a.signer.SignHTTP(context.TODO(), a.cred, verifyReq, "", AuthService, AuthRegion, timestamp) | |||||
| if err != nil { | |||||
| logger.Warnf("sign request: %v", err) | |||||
| c.AbortWithStatusJSON(http.StatusOK, Failed(errorcode.OperationFailed, "sign request failed")) | |||||
| return | |||||
| } | |||||
| verifySig := a.getSignature(verifyReq) | |||||
| if strings.EqualFold(verifySig, reqSig) { | |||||
| c.AbortWithStatusJSON(http.StatusOK, Failed(errorcode.Unauthorized, "signature mismatch")) | |||||
| return | |||||
| } | |||||
| c.Next() | |||||
| } | |||||
| // 解析 Authorization 头部 | |||||
| func parseAuthorizationHeader(authorizationHeader string) (string, []string, string, error) { | |||||
| if !strings.HasPrefix(authorizationHeader, "AWS4-HMAC-SHA256 ") { | |||||
| return "", nil, "", fmt.Errorf("invalid Authorization header format") | |||||
| } | |||||
| authorizationHeader = strings.TrimPrefix(authorizationHeader, "AWS4-HMAC-SHA256") | |||||
| parts := strings.Split(authorizationHeader, ",") | |||||
| if len(parts) != 3 { | |||||
| return "", nil, "", fmt.Errorf("invalid Authorization header format") | |||||
| } | |||||
| var credential, signedHeaders, signature string | |||||
| for _, part := range parts { | |||||
| part = strings.TrimSpace(part) | |||||
| if strings.HasPrefix(part, "Credential=") { | |||||
| credential = strings.TrimPrefix(part, "Credential=") | |||||
| } | |||||
| if strings.HasPrefix(part, "SignedHeaders=") { | |||||
| signedHeaders = strings.TrimPrefix(part, "SignedHeaders=") | |||||
| } | |||||
| if strings.HasPrefix(part, "Signature=") { | |||||
| signature = strings.TrimPrefix(part, "Signature=") | |||||
| } | |||||
| } | |||||
| if credential == "" || signedHeaders == "" || signature == "" { | |||||
| return "", nil, "", fmt.Errorf("missing necessary parts in Authorization header") | |||||
| } | |||||
| headers := strings.Split(signedHeaders, ";") | |||||
| return credential, headers, signature, nil | |||||
| } | |||||
| func (a *AWSAuth) getSignature(req *http.Request) string { | |||||
| auth := req.Header.Get(AuthorizationHeader) | |||||
| idx := strings.Index(auth, "Signature=") | |||||
| if idx == -1 { | |||||
| return "" | |||||
| } | |||||
| return auth[idx+len("Signature="):] | |||||
| } | |||||
| @@ -158,6 +158,11 @@ func (s *ObjectService) Download(ctx *gin.Context) { | |||||
| ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "download object failed")) | ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "download object failed")) | ||||
| return | return | ||||
| } | } | ||||
| if file.File == nil { | |||||
| log.Warnf("object not found: %d", req.ObjectID) | |||||
| ctx.JSON(http.StatusOK, Failed(errorcode.DataNotFound, "object not found")) | |||||
| return | |||||
| } | |||||
| defer file.File.Close() | defer file.File.Close() | ||||
| ctx.Header("Content-Disposition", "attachment; filename="+url.PathEscape(path.Base(file.Object.Path))) | ctx.Header("Content-Disposition", "attachment; filename="+url.PathEscape(path.Base(file.Object.Path))) | ||||
| @@ -11,15 +11,17 @@ type Server struct { | |||||
| engine *gin.Engine | engine *gin.Engine | ||||
| listenAddr string | listenAddr string | ||||
| svc *services.Service | svc *services.Service | ||||
| awsAuth *AWSAuth | |||||
| } | } | ||||
| func NewServer(listenAddr string, svc *services.Service) (*Server, error) { | |||||
| func NewServer(listenAddr string, svc *services.Service, awsAuth *AWSAuth) (*Server, error) { | |||||
| engine := gin.New() | engine := gin.New() | ||||
| return &Server{ | return &Server{ | ||||
| engine: engine, | engine: engine, | ||||
| listenAddr: listenAddr, | listenAddr: listenAddr, | ||||
| svc: svc, | svc: svc, | ||||
| awsAuth: awsAuth, | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| @@ -83,36 +85,36 @@ func (s *Server) initRouters() { | |||||
| func (s *Server) routeV1(eg *gin.Engine) { | func (s *Server) routeV1(eg *gin.Engine) { | ||||
| v1 := eg.Group("/v1") | v1 := eg.Group("/v1") | ||||
| v1.GET(cdsapi.ObjectListPathByPath, s.Object().ListByPath) | |||||
| v1.POST(cdsapi.ObjectListByIDsPath, s.Object().ListByIDs) | |||||
| v1.GET(cdsapi.ObjectDownloadPath, s.Object().Download) | |||||
| v1.GET(cdsapi.ObjectDownloadByPathPath, s.Object().DownloadByPath) | |||||
| v1.POST(cdsapi.ObjectUploadPath, s.Object().Upload) | |||||
| v1.GET(cdsapi.ObjectGetPackageObjectsPath, s.Object().GetPackageObjects) | |||||
| v1.POST(cdsapi.ObjectUpdateInfoPath, s.Object().UpdateInfo) | |||||
| v1.POST(cdsapi.ObjectUpdateInfoByPathPath, s.Object().UpdateInfoByPath) | |||||
| v1.POST(cdsapi.ObjectMovePath, s.Object().Move) | |||||
| v1.POST(cdsapi.ObjectDeletePath, s.Object().Delete) | |||||
| v1.POST(cdsapi.ObjectDeleteByPathPath, s.Object().DeleteByPath) | |||||
| v1.POST(cdsapi.ObjectClonePath, s.Object().Clone) | |||||
| v1.GET(cdsapi.PackageGetPath, s.Package().Get) | |||||
| v1.GET(cdsapi.PackageGetByFullNamePath, s.Package().GetByFullName) | |||||
| v1.POST(cdsapi.PackageCreatePath, s.Package().Create) | |||||
| v1.POST(cdsapi.PackageCreateLoadPath, s.Package().CreateLoad) | |||||
| v1.POST(cdsapi.PackageDeletePath, s.Package().Delete) | |||||
| v1.POST(cdsapi.PackageClonePath, s.Package().Clone) | |||||
| v1.GET(cdsapi.PackageListBucketPackagesPath, s.Package().ListBucketPackages) | |||||
| v1.GET(cdsapi.PackageGetCachedStoragesPath, s.Package().GetCachedStorages) | |||||
| v1.POST(cdsapi.StorageLoadPackagePath, s.Storage().LoadPackage) | |||||
| v1.POST(cdsapi.StorageCreatePackagePath, s.Storage().CreatePackage) | |||||
| v1.GET(cdsapi.StorageGetPath, s.Storage().Get) | |||||
| v1.POST(cdsapi.CacheMovePackagePath, s.Cache().MovePackage) | |||||
| v1.GET(cdsapi.BucketGetByNamePath, s.Bucket().GetByName) | |||||
| v1.POST(cdsapi.BucketCreatePath, s.Bucket().Create) | |||||
| v1.POST(cdsapi.BucketDeletePath, s.Bucket().Delete) | |||||
| v1.GET(cdsapi.BucketListUserBucketsPath, s.Bucket().ListUserBuckets) | |||||
| v1.GET(cdsapi.ObjectListPathByPath, s.awsAuth.Auth, s.Object().ListByPath) | |||||
| v1.POST(cdsapi.ObjectListByIDsPath, s.awsAuth.Auth, s.Object().ListByIDs) | |||||
| v1.GET(cdsapi.ObjectDownloadPath, s.awsAuth.Auth, s.Object().Download) | |||||
| v1.GET(cdsapi.ObjectDownloadByPathPath, s.awsAuth.Auth, s.Object().DownloadByPath) | |||||
| v1.POST(cdsapi.ObjectUploadPath, s.awsAuth.AuthWithoutBody, s.Object().Upload) | |||||
| v1.GET(cdsapi.ObjectGetPackageObjectsPath, s.awsAuth.Auth, s.Object().GetPackageObjects) | |||||
| v1.POST(cdsapi.ObjectUpdateInfoPath, s.awsAuth.Auth, s.Object().UpdateInfo) | |||||
| v1.POST(cdsapi.ObjectUpdateInfoByPathPath, s.awsAuth.Auth, s.Object().UpdateInfoByPath) | |||||
| v1.POST(cdsapi.ObjectMovePath, s.awsAuth.Auth, s.Object().Move) | |||||
| v1.POST(cdsapi.ObjectDeletePath, s.awsAuth.Auth, s.Object().Delete) | |||||
| v1.POST(cdsapi.ObjectDeleteByPathPath, s.awsAuth.Auth, s.Object().DeleteByPath) | |||||
| v1.POST(cdsapi.ObjectClonePath, s.awsAuth.Auth, s.Object().Clone) | |||||
| v1.GET(cdsapi.PackageGetPath, s.awsAuth.Auth, s.Package().Get) | |||||
| v1.GET(cdsapi.PackageGetByFullNamePath, s.awsAuth.Auth, s.Package().GetByFullName) | |||||
| v1.POST(cdsapi.PackageCreatePath, s.awsAuth.Auth, s.Package().Create) | |||||
| v1.POST(cdsapi.PackageCreateLoadPath, s.awsAuth.Auth, s.Package().CreateLoad) | |||||
| v1.POST(cdsapi.PackageDeletePath, s.awsAuth.Auth, s.Package().Delete) | |||||
| v1.POST(cdsapi.PackageClonePath, s.awsAuth.Auth, s.Package().Clone) | |||||
| v1.GET(cdsapi.PackageListBucketPackagesPath, s.awsAuth.Auth, s.Package().ListBucketPackages) | |||||
| v1.GET(cdsapi.PackageGetCachedStoragesPath, s.awsAuth.Auth, s.Package().GetCachedStorages) | |||||
| v1.POST(cdsapi.StorageLoadPackagePath, s.awsAuth.Auth, s.Storage().LoadPackage) | |||||
| v1.POST(cdsapi.StorageCreatePackagePath, s.awsAuth.Auth, s.Storage().CreatePackage) | |||||
| v1.GET(cdsapi.StorageGetPath, s.awsAuth.Auth, s.Storage().Get) | |||||
| v1.POST(cdsapi.CacheMovePackagePath, s.awsAuth.Auth, s.Cache().MovePackage) | |||||
| v1.GET(cdsapi.BucketGetByNamePath, s.awsAuth.Auth, s.Bucket().GetByName) | |||||
| v1.POST(cdsapi.BucketCreatePath, s.awsAuth.Auth, s.Bucket().Create) | |||||
| v1.POST(cdsapi.BucketDeletePath, s.awsAuth.Auth, s.Bucket().Delete) | |||||
| v1.GET(cdsapi.BucketListUserBucketsPath, s.awsAuth.Auth, s.Bucket().ListUserBuckets) | |||||
| } | } | ||||
| @@ -39,5 +39,8 @@ | |||||
| "downloadStrategy": { | "downloadStrategy": { | ||||
| "highLatencyHub": 35 | "highLatencyHub": 35 | ||||
| }, | }, | ||||
| "storageID": 0 | |||||
| "storageID": 0, | |||||
| "authAccessKey": "", | |||||
| "authSecretKey": "", | |||||
| "maxHttpBodySize": 5242880 | |||||
| } | } | ||||
| @@ -7,14 +7,12 @@ toolchain go1.23.2 | |||||
| replace gitlink.org.cn/cloudream/common v0.0.0 => ../common | replace gitlink.org.cn/cloudream/common v0.0.0 => ../common | ||||
| require ( | require ( | ||||
| github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible | |||||
| github.com/aws/aws-sdk-go-v2 v1.32.6 | github.com/aws/aws-sdk-go-v2 v1.32.6 | ||||
| github.com/aws/aws-sdk-go-v2/credentials v1.17.47 | github.com/aws/aws-sdk-go-v2/credentials v1.17.47 | ||||
| github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 | github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 | ||||
| github.com/gin-gonic/gin v1.7.7 | github.com/gin-gonic/gin v1.7.7 | ||||
| github.com/go-sql-driver/mysql v1.7.1 | github.com/go-sql-driver/mysql v1.7.1 | ||||
| github.com/hashicorp/golang-lru/v2 v2.0.5 | github.com/hashicorp/golang-lru/v2 v2.0.5 | ||||
| github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible | |||||
| github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf | github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf | ||||
| github.com/jedib0t/go-pretty/v6 v6.4.7 | github.com/jedib0t/go-pretty/v6 v6.4.7 | ||||
| github.com/klauspost/reedsolomon v1.11.8 | github.com/klauspost/reedsolomon v1.11.8 | ||||
| @@ -22,7 +20,6 @@ require ( | |||||
| github.com/samber/lo v1.38.1 | github.com/samber/lo v1.38.1 | ||||
| github.com/smartystreets/goconvey v1.8.1 | github.com/smartystreets/goconvey v1.8.1 | ||||
| github.com/spf13/cobra v1.8.0 | github.com/spf13/cobra v1.8.0 | ||||
| github.com/tencentyun/cos-go-sdk-v5 v0.7.56 | |||||
| gitlink.org.cn/cloudream/common v0.0.0 | gitlink.org.cn/cloudream/common v0.0.0 | ||||
| google.golang.org/grpc v1.57.0 | google.golang.org/grpc v1.57.0 | ||||
| google.golang.org/protobuf v1.31.0 | google.golang.org/protobuf v1.31.0 | ||||
| @@ -39,14 +36,10 @@ require ( | |||||
| github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect | ||||
| github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect | ||||
| github.com/aws/smithy-go v1.22.1 // indirect | github.com/aws/smithy-go v1.22.1 // indirect | ||||
| github.com/clbanning/mxj v1.8.4 // indirect | |||||
| github.com/google/go-querystring v1.0.0 // indirect | |||||
| github.com/google/uuid v1.3.1 // indirect | github.com/google/uuid v1.3.1 // indirect | ||||
| github.com/jinzhu/inflection v1.0.0 // indirect | github.com/jinzhu/inflection v1.0.0 // indirect | ||||
| github.com/jinzhu/now v1.1.5 // indirect | github.com/jinzhu/now v1.1.5 // indirect | ||||
| github.com/mozillazg/go-httpheader v0.2.1 // indirect | |||||
| github.com/stretchr/testify v1.8.4 // indirect | github.com/stretchr/testify v1.8.4 // indirect | ||||
| golang.org/x/time v0.7.0 // indirect | |||||
| gopkg.in/yaml.v2 v2.4.0 // indirect | gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| ) | ) | ||||
| @@ -1,6 +1,3 @@ | |||||
| github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= | |||||
| github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= | |||||
| github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= | |||||
| github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= | github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= | ||||
| github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= | github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= | ||||
| github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= | github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= | ||||
| @@ -29,8 +26,6 @@ github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= | |||||
| github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= | github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= | ||||
| github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= | github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= | ||||
| github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= | github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= | ||||
| github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= | |||||
| github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= | |||||
| github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= | github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= | ||||
| github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= | github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= | ||||
| @@ -58,7 +53,6 @@ github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9 | |||||
| github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= | ||||
| github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= | ||||
| github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= | ||||
| github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= | |||||
| github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||||
| github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||||
| github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | ||||
| @@ -66,10 +60,7 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu | |||||
| github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||
| github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||||
| github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | |||||
| github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | |||||
| 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.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | |||||
| github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= | github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= | ||||
| github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= | github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= | ||||
| @@ -81,8 +72,6 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l | |||||
| github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= | ||||
| github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= | github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= | ||||
| github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= | github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= | ||||
| github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible h1:XQVXdk+WAJ4fSNB6mMRuYNvFWou7BZs6SZB925hPrnk= | |||||
| github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s= | |||||
| github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= | github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= | ||||
| github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= | github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= | ||||
| github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | ||||
| @@ -117,7 +106,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP | |||||
| github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||||
| github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | ||||
| github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | ||||
| github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | |||||
| github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | ||||
| github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||
| 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= | ||||
| @@ -126,8 +114,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ | |||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/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/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= | |||||
| github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= | |||||
| github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= | github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= | ||||
| @@ -163,10 +149,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO | |||||
| github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||||
| github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | ||||
| github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||||
| github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= | |||||
| github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0= | |||||
| github.com/tencentyun/cos-go-sdk-v5 v0.7.56 h1:fOA3l3XbVN2kTjQKYPvhDms0Fq8zDcinO3boXodFaLw= | |||||
| github.com/tencentyun/cos-go-sdk-v5 v0.7.56/go.mod h1:8+hG+mQMuRP/OIS9d83syAvXvrMj9HhkND6Q1fLghw0= | |||||
| github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= | ||||
| github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | ||||
| github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= | github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= | ||||
| @@ -231,8 +213,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | |||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= | ||||
| golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||
| golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= | |||||
| golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= | |||||
| 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-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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||||