Skip to content

Commit dafc973

Browse files
author
jojoliang
committed
add getPresignedURL2
1 parent 462b1e2 commit dafc973

File tree

4 files changed

+168
-1
lines changed

4 files changed

+168
-1
lines changed

cos.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424

2525
const (
2626
// Version current go sdk version
27-
Version = "0.7.43"
27+
Version = "0.7.44"
2828
UserAgent = "cos-go-sdk-v5/" + Version
2929
contentTypeXML = "application/xml"
3030
defaultServiceBaseURL = "http://service.cos.myqcloud.com"
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/tencentyun/cos-go-sdk-v5"
7+
"net/http"
8+
"net/url"
9+
"os"
10+
"strings"
11+
"time"
12+
)
13+
14+
func main() {
15+
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
16+
b := &cos.BaseURL{BucketURL: u}
17+
c := cos.NewClient(b, &http.Client{
18+
Transport: &cos.AuthorizationTransport{
19+
// 通过环境变量获取密钥
20+
// 环境变量 COS_SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
21+
SecretID: os.Getenv("COS_SECRETID"),
22+
// 环境变量 COS_SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
23+
SecretKey: os.Getenv("COS_SECRETKEY"),
24+
SessionToken: "<token>", // 请替换成您的临时密钥
25+
},
26+
})
27+
28+
name := "exampleobject"
29+
ctx := context.Background()
30+
31+
// 获取预签名
32+
presignedURL, err := c.Object.GetPresignedURL2(ctx, http.MethodPut, name, time.Hour, nil)
33+
if err != nil {
34+
fmt.Printf("Error: %v\n", err)
35+
return
36+
}
37+
fmt.Printf("url: %v\n", presignedURL.String())
38+
// 通过预签名方式上传对象
39+
data := "test upload with presignedURL"
40+
f := strings.NewReader(data)
41+
req, err := http.NewRequest(http.MethodPut, presignedURL.String(), f)
42+
if err != nil {
43+
fmt.Printf("Error: %v\n", err)
44+
}
45+
_, err = http.DefaultClient.Do(req)
46+
if err != nil {
47+
fmt.Printf("Error: %v\n", err)
48+
}
49+
}

object.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,81 @@ func (s *ObjectService) GetPresignedURL(ctx context.Context, httpMethod, name, a
187187
return req.URL, nil
188188
}
189189

190+
func (s *ObjectService) GetPresignedURL2(ctx context.Context, httpMethod, name string, expired time.Duration, opt interface{}, signHost ...bool) (*url.URL, error) {
191+
// 兼容 name 以 / 开头的情况
192+
if strings.HasPrefix(name, "/") {
193+
name = encodeURIComponent("/") + encodeURIComponent(name[1:], []byte{'/'})
194+
} else {
195+
name = encodeURIComponent(name, []byte{'/'})
196+
}
197+
198+
cred := s.client.GetCredential()
199+
if cred == nil {
200+
return nil, fmt.Errorf("GetCredential failed")
201+
}
202+
sendOpt := sendOptions{
203+
baseURL: s.client.BaseURL.BucketURL,
204+
uri: "/" + name,
205+
method: httpMethod,
206+
optQuery: opt,
207+
optHeader: opt,
208+
}
209+
mark := "?"
210+
if popt, ok := opt.(*PresignedURLOptions); ok {
211+
if popt != nil && popt.Query != nil {
212+
qs := popt.Query.Encode()
213+
if qs != "" {
214+
sendOpt.uri = fmt.Sprintf("%s?%s", sendOpt.uri, qs)
215+
mark = "&"
216+
}
217+
}
218+
}
219+
if cred.SessionToken != "" {
220+
sendOpt.uri = fmt.Sprintf("%s%s%s", sendOpt.uri, mark, url.Values{"x-cos-security-token": []string{cred.SessionToken}}.Encode())
221+
}
222+
223+
req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader)
224+
if err != nil {
225+
return nil, err
226+
}
227+
228+
var authTime *AuthTime
229+
if opt != nil {
230+
if opt, ok := opt.(*presignedURLTestingOptions); ok {
231+
authTime = opt.authTime
232+
}
233+
}
234+
if authTime == nil {
235+
authTime = NewAuthTime(expired)
236+
}
237+
signedHost := true
238+
if len(signHost) > 0 {
239+
signedHost = signHost[0]
240+
}
241+
authorization := newAuthorization(cred.SecretID, cred.SecretKey, req, authTime, signedHost)
242+
if opt != nil {
243+
if opt, ok := opt.(*PresignedURLOptions); ok {
244+
if opt.SignMerged {
245+
sign := encodeURIComponent(authorization)
246+
if req.URL.RawQuery == "" {
247+
req.URL.RawQuery = fmt.Sprintf("sign=%s", sign)
248+
} else {
249+
req.URL.RawQuery = fmt.Sprintf("%s&sign=%s", req.URL.RawQuery, sign)
250+
}
251+
return req.URL, nil
252+
}
253+
}
254+
}
255+
sign := encodeURIComponent(authorization, []byte{'&', '='})
256+
257+
if req.URL.RawQuery == "" {
258+
req.URL.RawQuery = fmt.Sprintf("%s", sign)
259+
} else {
260+
req.URL.RawQuery = fmt.Sprintf("%s&%s", req.URL.RawQuery, sign)
261+
}
262+
return req.URL, nil
263+
}
264+
190265
func (s *ObjectService) GetSignature(ctx context.Context, httpMethod, name, ak, sk string, expired time.Duration, opt *PresignedURLOptions, signHost ...bool) string {
191266
// 兼容 name 以 / 开头的情况
192267
if strings.HasPrefix(name, "/") {

object_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,49 @@ func TestObjectService_GetPresignedURL(t *testing.T) {
216216
}
217217
}
218218

219+
func TestObjectService_GetPresignedURL2(t *testing.T) {
220+
setup()
221+
defer teardown()
222+
223+
u, _ := url.Parse(server.URL)
224+
client := NewClient(&BaseURL{u, u, u, u, u}, &http.Client{
225+
Transport: &AuthorizationTransport{
226+
SecretID: "QmFzZTY0IGlzIGEgZ*******",
227+
SecretKey: "ZfbOA78asKUYBcXFrJD0a1I*******",
228+
},
229+
})
230+
231+
exceptSign := "q-sign-algorithm=sha1&q-ak=QmFzZTY0IGlzIGEgZ*******&q-sign-time=1622702557;1622706157&q-key-time=1622702557;1622706157&q-header-list=&q-url-param-list=&q-signature=0f359fe9d29e7fa0c738ce6c8feaf4ed1e84f287"
232+
exceptURL := &url.URL{
233+
Scheme: "http",
234+
Host: client.Host,
235+
Path: "/test.jpg",
236+
RawQuery: exceptSign,
237+
}
238+
239+
c := context.Background()
240+
name := "test.jpg"
241+
startTime := time.Unix(int64(1622702557), 0)
242+
endTime := time.Unix(int64(1622706157), 0)
243+
opt := presignedURLTestingOptions{
244+
authTime: &AuthTime{
245+
SignStartTime: startTime,
246+
SignEndTime: endTime,
247+
KeyStartTime: startTime,
248+
KeyEndTime: endTime,
249+
},
250+
}
251+
252+
presignedURL, err := client.Object.GetPresignedURL2(c, http.MethodPut, name, time.Hour, opt)
253+
if err != nil {
254+
t.Fatal(err)
255+
}
256+
257+
if reflect.DeepEqual(exceptURL, presignedURL) {
258+
t.Fatalf("Wrong PreSignedURL!")
259+
}
260+
}
261+
219262
func TestObjectService_Put(t *testing.T) {
220263
setup()
221264
defer teardown()

0 commit comments

Comments
 (0)