Skip to content

Commit

Permalink
feat: support the provider upyun #55
Browse files Browse the repository at this point in the history
  • Loading branch information
saltbo committed Jul 8, 2021
1 parent 3acf79f commit 32658ac
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 20 deletions.
2 changes: 1 addition & 1 deletion internal/pkg/fakefs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (f *File) PreSignPutURL(matter *model.Matter) (url string, headers http.Hea
return "", nil, err
}

url, headers, err = provider.SignedPutURL(matter.Object, matter.Type, storage.PublicRead())
url, headers, err = provider.SignedPutURL(matter.Object, matter.Type, matter.Size, storage.PublicRead())
if err != nil {
return
}
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Provider interface {
SetupCORS() error
List(prefix string) ([]Object, error)
Move(object, newObject string) error
SignedPutURL(key, filetype string, public bool) (url string, headers http.Header, err error)
SignedPutURL(key, filetype string, filesize int64, public bool) (url string, headers http.Header, err error)
SignedGetURL(key, filename string) (url string, err error)
PublicURL(key string) (url string)
ObjectDelete(key string) error
Expand Down Expand Up @@ -61,7 +61,7 @@ var supportProviders = map[string]Constructor{
"OSS": NewOSSProvider,
"S3": NewS3Provider,
"US3": NewUS3Provider,
//"USS": NewUSSProvider,
"USS": NewUSSProvider,
//"od": NewODProvider,
//"gd": NewGDProvider,
}
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/provider/provider_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (m *MockProvider) Move(object, newObject string) error {
return nil
}

func (m *MockProvider) SignedPutURL(key, filetype string, public bool) (url string, headers http.Header, err error) {
func (m *MockProvider) SignedPutURL(key, filetype string, filesize int64, public bool) (url string, headers http.Header, err error) {
headers = make(http.Header)
headers.Add("", "")
return fmt.Sprintf("http://dl.test.com/%s", key), headers, nil
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/provider/provider_s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (p *S3Provider) Move(object, newObject string) error {
return p.ObjectDelete(object)
}

func (p *S3Provider) SignedPutURL(key, filetype string, public bool) (string, http.Header, error) {
func (p *S3Provider) SignedPutURL(key, filetype string, filesize int64, public bool) (string, http.Header, error) {
acl := s3.ObjectCannedACLAuthenticatedRead
if public {
acl = s3.ObjectCannedACLPublicRead
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestSignedPutURL(t *testing.T) {
disk, err := New(dc)
assert.NoError(t, err)

_, headers, err := disk.SignedPutURL(key, "text/plain", false)
_, headers, err := disk.SignedPutURL(key, "text/plain", 0, false)
assert.NoError(t, err)

assert.Equal(t, s3.ObjectCannedACLAuthenticatedRead, headers.Get("x-amz-acl"))
Expand Down
44 changes: 30 additions & 14 deletions internal/pkg/provider/provider_uss.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ import (
"encoding/base64"
"fmt"
"net/http"
"path/filepath"
"strings"
"time"

"github.com/saltbo/gopkg/strutil"
"github.com/upyun/go-sdk/v3/upyun"
)

// USSProvider 又拍云
type USSProvider struct {
conf *Config
client *upyun.UpYun
}

func NewUSSProvider(conf *Config) (Provider, error) {
return &USSProvider{
conf: conf,
client: upyun.NewUpYun(&upyun.UpYunConfig{
Bucket: conf.Bucket,
Operator: conf.AccessKey,
Expand All @@ -41,25 +43,26 @@ func (p *USSProvider) Move(object, newObject string) error {
panic("implement me")
}

func (p *USSProvider) SignedPutURL(key, filetype string, public bool) (url string, headers http.Header, err error) {
func (p *USSProvider) SignedPutURL(key, filetype string, filesize int64, public bool) (url string, headers http.Header, err error) {
//expireAt := time.Now().Add(time.Minute * 15).Unix()
//headers.Set("X-Upyun-Expire", fmt.Sprint(expireAt))
//headers.Set("X-Upyun-Uri-Prefix", uriPrefix)
headers = make(http.Header)
expireAt := time.Now().Add(time.Minute * 15).Unix()
uriPrefix := fmt.Sprintf("/%s/%s", p.client.Bucket, strings.TrimSuffix(key, filepath.Ext(key)))
headers.Set("X-Upyun-Expire", fmt.Sprint(expireAt))
headers.Set("X-Upyun-Uri-Prefix", uriPrefix)
headers.Set("Content-Type", filetype)
headers.Set("Authorization", p.buildSign("PUT", uriPrefix, fmt.Sprint(expireAt)))
uri := fmt.Sprintf("/%s/%s", p.client.Bucket, key)
date := time.Now().UTC().Format(http.TimeFormat)
headers.Set("X-Date", date)
headers.Set("Authorization", p.buildOldSign("PUT", uri, date, fmt.Sprint(filesize)))
return fmt.Sprintf("http://v0.api.upyun.com/%s/%s", p.client.Bucket, key), headers, err
}

func (p *USSProvider) SignedGetURL(key, filename string) (url string, err error) {
//_upt
// todo 官方文档没找到相关实现,在Cloudreve里看到了_upt这个参数,可以参考实现
return "", err
expireAt := time.Now().Add(time.Minute * 15).Unix()
upt := p.buildUpt(expireAt, fmt.Sprintf("/%s", key))
return fmt.Sprintf("%s?_upt=%s", p.PublicURL(key), upt), err
}

func (p *USSProvider) PublicURL(key string) (url string) {
return fmt.Sprintf("http://v0.api.upyun.com/%s/%s", p.client.Bucket, key)
return fmt.Sprintf("%s/%s", p.conf.CustomHost, key)
}

func (p *USSProvider) ObjectDelete(key string) error {
Expand All @@ -82,8 +85,21 @@ func (p *USSProvider) ObjectsDelete(keys []string) error {
}

func (p *USSProvider) buildSign(items ...string) string {
mac := hmac.New(sha1.New, []byte(p.client.Password))
mac := hmac.New(sha1.New, []byte(strutil.Md5Hex(p.conf.AccessSecret)))
mac.Write([]byte(strings.Join(items, "&")))
signStr := base64.StdEncoding.EncodeToString(mac.Sum(nil))
return fmt.Sprintf("UPYUN %s:%s", p.client.Operator, signStr)
return fmt.Sprintf("UpYun %s:%s", p.client.Operator, signStr)
}

func (p USSProvider) buildUpt(expireAt int64, uri string) string {
// sign = MD5( secret & etime & URI )
//_upt = sign { 中间 8 位 }+etime
signStr := strings.Join([]string{p.conf.AccessSecret, fmt.Sprint(expireAt), uri}, "&")
return strutil.Md5Hex(signStr)[12:20] + fmt.Sprint(expireAt)
}

func (p *USSProvider) buildOldSign(items ...string) string {
items = append(items, strutil.Md5Hex(p.conf.AccessSecret))
signStr := strutil.Md5Hex(strings.Join(items, "&"))
return fmt.Sprintf("UpYun %s:%s", p.client.Operator, signStr)
}

0 comments on commit 32658ac

Please sign in to comment.