You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

presigned.go 5.1 kB

7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package api
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "net/url"
  7. "time"
  8. v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
  9. "github.com/aws/aws-sdk-go-v2/credentials"
  10. "github.com/google/go-querystring/query"
  11. clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
  12. )
  13. type PresignedService struct {
  14. *Client
  15. }
  16. func (c *Client) Presigned() *PresignedService {
  17. return &PresignedService{
  18. Client: c,
  19. }
  20. }
  21. const PresignedObjectListByPathPath = "/v1/presigned/object/listByPath"
  22. type PresignedObjectListByPath struct {
  23. ObjectListByPath
  24. }
  25. func (c *PresignedService) ObjectListByPath(req PresignedObjectListByPath, expireIn int) (string, error) {
  26. return c.presign(req, PresignedObjectListByPathPath, http.MethodGet, expireIn)
  27. }
  28. const PresignedObjectDownloadByPathPath = "/v1/presigned/object/downloadByPath"
  29. type PresignedObjectDownloadByPath struct {
  30. PackageID clitypes.PackageID `form:"packageID" url:"packageID" binding:"required"`
  31. Path string `form:"path" url:"path" binding:"required"`
  32. Offset int64 `form:"offset" url:"offset,omitempty"`
  33. Length *int64 `form:"length" url:"length,omitempty"`
  34. }
  35. func (c *PresignedService) ObjectDownloadByPath(req PresignedObjectDownloadByPath, expireIn int) (string, error) {
  36. return c.presign(req, PresignedObjectDownloadByPathPath, http.MethodGet, expireIn)
  37. }
  38. const PresignedObjectDownloadPath = "/v1/presigned/object/download"
  39. type PresignedObjectDownload struct {
  40. ObjectID clitypes.ObjectID `form:"objectID" url:"objectID" binding:"required"`
  41. Offset int64 `form:"offset" url:"offset,omitempty"`
  42. Length *int64 `form:"length" url:"length,omitempty"`
  43. }
  44. func (c *PresignedService) ObjectDownload(req PresignedObjectDownload, expireIn int) (string, error) {
  45. return c.presign(req, PresignedObjectDownloadPath, http.MethodGet, expireIn)
  46. }
  47. const PresignedObjectUploadPath = "/v1/presigned/object/upload"
  48. type PresignedObjectUpload struct {
  49. PackageID clitypes.PackageID `form:"packageID" binding:"required" url:"packageID"`
  50. Path string `form:"path" binding:"required" url:"path"`
  51. Affinity clitypes.UserSpaceID `form:"affinity" url:"affinity,omitempty"`
  52. LoadTo []clitypes.UserSpaceID `form:"loadTo" url:"loadTo,omitempty"`
  53. LoadToPath []string `form:"loadToPath" url:"loadToPath,omitempty"`
  54. }
  55. type PresignedObjectUploadResp struct {
  56. Object clitypes.Object `json:"object"`
  57. }
  58. func (c *PresignedService) ObjectUpload(req PresignedObjectUpload, expireIn int) (string, error) {
  59. return c.presign(req, PresignedObjectUploadPath, http.MethodPost, expireIn)
  60. }
  61. const PresignedObjectNewMultipartUploadPath = "/v1/presigned/object/newMultipartUpload"
  62. type PresignedObjectNewMultipartUpload struct {
  63. PackageID clitypes.PackageID `form:"packageID" binding:"required" url:"packageID"`
  64. Path string `form:"path" binding:"required" url:"path"`
  65. }
  66. type PresignedObjectNewMultipartUploadResp struct {
  67. Object clitypes.Object `json:"object"`
  68. }
  69. func (c *PresignedService) ObjectNewMultipartUpload(req PresignedObjectNewMultipartUpload, expireIn int) (string, error) {
  70. return c.presign(req, PresignedObjectNewMultipartUploadPath, http.MethodPost, expireIn)
  71. }
  72. const PresignedObjectUploadPartPath = "/v1/presigned/object/uploadPart"
  73. type PresignedObjectUploadPart struct {
  74. ObjectID clitypes.ObjectID `form:"objectID" binding:"required" url:"objectID"`
  75. Index int `form:"index" binding:"required" url:"index"`
  76. }
  77. type PresignedUploadPartResp struct{}
  78. func (c *PresignedService) ObjectUploadPart(req PresignedObjectUploadPart, expireIn int) (string, error) {
  79. return c.presign(req, PresignedObjectUploadPartPath, http.MethodPost, expireIn)
  80. }
  81. const PresignedObjectCompleteMultipartUploadPath = "/v1/presigned/object/completeMultipartUpload"
  82. type PresignedObjectCompleteMultipartUpload struct {
  83. ObjectID clitypes.ObjectID `form:"objectID" binding:"required" url:"objectID"`
  84. Indexes []int `form:"indexes" binding:"required" url:"indexes"`
  85. }
  86. type PresignedObjectCompleteMultipartUploadResp struct {
  87. Object clitypes.Object `json:"object"`
  88. }
  89. func (c *PresignedService) ObjectCompleteMultipartUpload(req PresignedObjectCompleteMultipartUpload, expireIn int) (string, error) {
  90. return c.presign(req, PresignedObjectCompleteMultipartUploadPath, http.MethodPost, expireIn)
  91. }
  92. func (c *PresignedService) presign(req any, path string, method string, expireIn int) (string, error) {
  93. u, err := url.Parse(c.cfg.URL)
  94. if err != nil {
  95. return "", err
  96. }
  97. u = u.JoinPath(path)
  98. us, err := query.Values(req)
  99. if err != nil {
  100. return "", err
  101. }
  102. us.Add("X-Expires", fmt.Sprintf("%v", expireIn))
  103. u.RawQuery = us.Encode()
  104. prod := credentials.NewStaticCredentialsProvider(c.cfg.AccessKey, c.cfg.SecretKey, "")
  105. cred, err := prod.Retrieve(context.TODO())
  106. if err != nil {
  107. return "", err
  108. }
  109. r, err := http.NewRequest(method, u.String(), nil)
  110. if err != nil {
  111. return "", err
  112. }
  113. signer := v4.NewSigner()
  114. signedURL, _, err := signer.PresignHTTP(context.Background(), cred, r, "", AuthService, AuthRegion, time.Now())
  115. return signedURL, err
  116. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。