Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 123 additions & 48 deletions storagev2/uptoken/uploadtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,21 @@ type (
signer struct {
putPolicy PutPolicy
credentialsProvider credentials.CredentialsProvider
onceCredentials sync.Once
upToken string
mu sync.Mutex
credentials *credentials.Credentials
credentialsInited bool
upToken string
upTokenInited bool
}
parser struct {
upToken string
putPolicy PutPolicy
accessKey string
splits []string
upToken string
mu sync.Mutex
putPolicy PutPolicy
putPolicyInited bool
accessKey string
accessKeyInited bool
splits []string
splitsInited bool
}
)

Expand All @@ -60,93 +66,162 @@ func (signer *signer) GetPutPolicy(context.Context) (PutPolicy, error) {
}

func (signer *signer) GetAccessKey(ctx context.Context) (string, error) {
var err error
credentials, err := signer.onceGetCredentials(ctx)
credentials, err := signer.getCredentials(ctx)
if err != nil {
return "", err
}
return credentials.AccessKey, nil
}

func (signer *signer) GetUpToken(ctx context.Context) (string, error) {
return signer.onceGetUpToken(ctx)
}

func (signer *signer) onceGetCredentials(ctx context.Context) (*credentials.Credentials, error) {
var err error
signer.onceCredentials.Do(func() {
if signer.credentialsProvider != nil {
signer.credentials, err = signer.credentialsProvider.Get(ctx)
} else if defaultCreds := credentials.Default(); defaultCreds != nil {
signer.credentials = defaultCreds
}
})
return signer.credentials, err
}

func (signer *signer) onceGetUpToken(ctx context.Context) (string, error) {
var err error
if signer.upToken != "" {
signer.mu.Lock()
if signer.upTokenInited {
defer signer.mu.Unlock()
return signer.upToken, nil
}
credentials, err := signer.onceGetCredentials(ctx)
signer.mu.Unlock()

credentials, err := signer.getCredentials(ctx)
if err != nil {
return "", nil
return "", err
}

putPolicyJson, err := json.Marshal(signer.putPolicy)
if err != nil {
return "", nil
return "", err
}

upToken := credentials.SignWithData(putPolicyJson)

signer.mu.Lock()
defer signer.mu.Unlock()
if !signer.upTokenInited {
signer.upToken = upToken
signer.upTokenInited = true
}
signer.upToken = credentials.SignWithData(putPolicyJson)
return signer.upToken, nil
}

func (signer *signer) getCredentials(ctx context.Context) (*credentials.Credentials, error) {
signer.mu.Lock()
if signer.credentialsInited {
defer signer.mu.Unlock()
return signer.credentials, nil
}
signer.mu.Unlock()

var creds *credentials.Credentials
var err error
if signer.credentialsProvider != nil {
creds, err = signer.credentialsProvider.Get(ctx)
if err != nil {
return nil, err
}
} else if defaultCreds := credentials.Default(); defaultCreds != nil {
creds = defaultCreds
}

signer.mu.Lock()
defer signer.mu.Unlock()
if !signer.credentialsInited {
signer.credentials = creds
signer.credentialsInited = true
}
return signer.credentials, nil
}

// NewParser 创建上传凭证签发器
func NewParser(upToken string) Provider {
return &parser{upToken: upToken}
}

func (parser *parser) GetPutPolicy(context.Context) (PutPolicy, error) {
if parser.putPolicy != nil {
parser.mu.Lock()
if parser.putPolicyInited {
defer parser.mu.Unlock()
return parser.putPolicy, nil
}
splits, ok := parser.onceGetSplits()
if !ok {
return nil, ErrInvalidUpToken
parser.mu.Unlock()

splits, err := parser.getSplits()
if err != nil {
return PutPolicy{}, err
}

putPolicyJson, err := base64.URLEncoding.DecodeString(splits[2])
if err != nil {
return nil, ErrInvalidUpToken
return PutPolicy{}, ErrInvalidUpToken
}

var putPolicy PutPolicy
if err := json.Unmarshal(putPolicyJson, &putPolicy); err != nil {
return PutPolicy{}, err
}
err = json.Unmarshal(putPolicyJson, &parser.putPolicy)
return parser.putPolicy, err

parser.mu.Lock()
defer parser.mu.Unlock()
if !parser.putPolicyInited {
parser.putPolicy = putPolicy
parser.putPolicyInited = true
}
return parser.putPolicy, nil
}

func (parser *parser) GetAccessKey(context.Context) (string, error) {
if parser.accessKey != "" {
parser.mu.Lock()
if parser.accessKeyInited {
defer parser.mu.Unlock()
return parser.accessKey, nil
}
splits, ok := parser.onceGetSplits()
if !ok {
return "", ErrInvalidUpToken
parser.mu.Unlock()

splits, err := parser.getSplits()
if err != nil {
return "", err
}

accessKey := splits[0]

parser.mu.Lock()
defer parser.mu.Unlock()
if !parser.accessKeyInited {
parser.accessKey = accessKey
parser.accessKeyInited = true
}
parser.accessKey = splits[0]
return parser.accessKey, nil
}

func (parser *parser) onceGetSplits() ([]string, bool) {
if len(parser.splits) > 0 {
return parser.splits, true
func (parser *parser) getSplits() ([]string, error) {
parser.mu.Lock()
if parser.splitsInited {
defer parser.mu.Unlock()
if parser.splits == nil {
return nil, ErrInvalidUpToken
}
return parser.splits, nil
}
parser.mu.Unlock()

splits := strings.Split(parser.upToken, ":")
if len(splits) == 5 && splits[0] == "" {
splits = splits[2:]
}
if len(splits) != 3 {
return nil, false
parser.mu.Lock()
defer parser.mu.Unlock()
if !parser.splitsInited {
parser.splitsInited = true
}
return nil, ErrInvalidUpToken
}

parser.mu.Lock()
defer parser.mu.Unlock()
if !parser.splitsInited {
parser.splits = splits
parser.splitsInited = true
}
parser.splits = splits
return parser.splits, true
return parser.splits, nil
}

func (parser *parser) GetUpToken(context.Context) (string, error) {
Expand Down
Loading