github.com/qiniu/go-sdk/v7@v7.27.0/storagev2/uptoken/uploadtoken.go (about) 1 package uptoken 2 3 import ( 4 "context" 5 "encoding/base64" 6 "encoding/json" 7 "errors" 8 "strings" 9 "sync" 10 11 "github.com/qiniu/go-sdk/v7/storagev2/credentials" 12 ) 13 14 // ErrInvalidUpToken 非法的上传凭证 15 var ErrInvalidUpToken = errors.New("invalid upToken") 16 17 type ( 18 // PutPolicyProvider 获取上传策略接口 19 PutPolicyProvider interface { 20 GetPutPolicy(context.Context) (PutPolicy, error) 21 } 22 // AccessKeyProvider 获取 AccessKey 接口 23 AccessKeyProvider interface { 24 GetAccessKey(context.Context) (string, error) 25 } 26 // UpTokenProvider 获取上传凭证接口 27 UpTokenProvider interface { 28 GetUpToken(context.Context) (string, error) 29 } 30 // Provider 获取上传凭证,AccessKey 和上传策略接口 31 Provider interface { 32 PutPolicyProvider 33 AccessKeyProvider 34 UpTokenProvider 35 } 36 signer struct { 37 putPolicy PutPolicy 38 credentialsProvider credentials.CredentialsProvider 39 mu sync.Mutex 40 credentials *credentials.Credentials 41 upToken string 42 } 43 parser struct { 44 upToken string 45 mu sync.Mutex 46 putPolicy PutPolicy 47 accessKey string 48 splits []string 49 } 50 ) 51 52 // NewSigner 创建上传凭证签发器 53 // 54 // 需要注意的是 NewSigner 仅仅只会通过 credentials.CredentialsProvider 获取一次鉴权参数,之后就会缓存该鉴权参数,不会反复获取 55 func NewSigner(putPolicy PutPolicy, credentialsProvider credentials.CredentialsProvider) Provider { 56 return &signer{putPolicy: putPolicy, credentialsProvider: credentialsProvider} 57 } 58 59 func (signer *signer) GetPutPolicy(context.Context) (PutPolicy, error) { 60 return signer.putPolicy, nil 61 } 62 63 func (signer *signer) GetAccessKey(ctx context.Context) (string, error) { 64 credentials, err := signer.getCredentials(ctx) 65 if err != nil { 66 return "", err 67 } 68 return credentials.AccessKey, nil 69 } 70 71 func (signer *signer) GetUpToken(ctx context.Context) (string, error) { 72 signer.mu.Lock() 73 if signer.upToken != "" { 74 defer signer.mu.Unlock() 75 return signer.upToken, nil 76 } 77 signer.mu.Unlock() 78 79 credentials, err := signer.getCredentials(ctx) 80 if err != nil { 81 return "", err 82 } 83 84 putPolicyJson, err := json.Marshal(signer.putPolicy) 85 if err != nil { 86 return "", err 87 } 88 89 upToken := credentials.SignWithData(putPolicyJson) 90 91 signer.mu.Lock() 92 if signer.upToken == "" { 93 signer.upToken = upToken 94 } 95 signer.mu.Unlock() 96 97 return signer.upToken, nil 98 } 99 100 func (signer *signer) getCredentials(ctx context.Context) (*credentials.Credentials, error) { 101 signer.mu.Lock() 102 if signer.credentials != nil { 103 defer signer.mu.Unlock() 104 return signer.credentials, nil 105 } 106 signer.mu.Unlock() 107 108 var creds *credentials.Credentials 109 var err error 110 if signer.credentialsProvider != nil { 111 creds, err = signer.credentialsProvider.Get(ctx) 112 if err != nil { 113 return nil, err 114 } 115 } else if defaultCreds := credentials.Default(); defaultCreds != nil { 116 creds = defaultCreds 117 } 118 119 if creds != nil { 120 signer.mu.Lock() 121 if signer.credentials == nil { 122 signer.credentials = creds 123 } 124 signer.mu.Unlock() 125 } 126 127 return creds, nil 128 } 129 130 // NewParser 创建上传凭证签发器 131 func NewParser(upToken string) Provider { 132 return &parser{upToken: upToken} 133 } 134 135 func (parser *parser) GetPutPolicy(ctx context.Context) (PutPolicy, error) { 136 parser.mu.Lock() 137 if parser.putPolicy != nil { 138 defer parser.mu.Unlock() 139 return parser.putPolicy, nil 140 } 141 parser.mu.Unlock() 142 143 splits, err := parser.getSplits() 144 if err != nil { 145 return PutPolicy{}, err 146 } 147 148 putPolicyJson, err := base64.URLEncoding.DecodeString(splits[2]) 149 if err != nil { 150 return PutPolicy{}, ErrInvalidUpToken 151 } 152 153 var putPolicy PutPolicy 154 if err := json.Unmarshal(putPolicyJson, &putPolicy); err != nil { 155 return PutPolicy{}, err 156 } 157 158 parser.mu.Lock() 159 if parser.putPolicy == nil { 160 parser.putPolicy = putPolicy 161 } 162 parser.mu.Unlock() 163 164 return parser.putPolicy, nil 165 } 166 167 func (parser *parser) GetAccessKey(ctx context.Context) (string, error) { 168 parser.mu.Lock() 169 if parser.accessKey != "" { 170 defer parser.mu.Unlock() 171 return parser.accessKey, nil 172 } 173 parser.mu.Unlock() 174 175 splits, err := parser.getSplits() 176 if err != nil { 177 return "", err 178 } 179 180 accessKey := splits[0] 181 182 parser.mu.Lock() 183 if parser.accessKey == "" { 184 parser.accessKey = accessKey 185 } 186 parser.mu.Unlock() 187 188 return parser.accessKey, nil 189 } 190 191 func (parser *parser) getSplits() ([]string, error) { 192 parser.mu.Lock() 193 if len(parser.splits) > 0 { 194 defer parser.mu.Unlock() 195 return parser.splits, nil 196 } 197 parser.mu.Unlock() 198 199 splits := strings.Split(parser.upToken, ":") 200 if len(splits) == 5 && splits[0] == "" { 201 splits = splits[2:] 202 } 203 if len(splits) != 3 { 204 return nil, ErrInvalidUpToken 205 } 206 207 parser.mu.Lock() 208 if len(parser.splits) == 0 { 209 parser.splits = splits 210 } 211 parser.mu.Unlock() 212 213 return parser.splits, nil 214 } 215 216 func (parser *parser) GetUpToken(context.Context) (string, error) { 217 return parser.upToken, nil 218 }