Feature Name | Description | Example code |
Generate Presigned URL. | COS supports using presigned URLs for Object upload and download. The principle is to embed the signature into the URL to generate a signed link. | |
Presigned URL for Multipart Upload | Upload objects in parts using a presigned URL, including initializing parts, uploading parts, and completing the presigned generation for parts. |
func (s *ObjectService) GetPresignedURL(ctx context.Context, httpMethod, key, ak, sk string, expired time.Duration, opt interface{}, signHost ...bool) (*url.URL, error)
type PresignedURLOptions struct {Query *url.ValuesHeader *http.Header}
Parameter Name | Type | Description |
httpMethod | string | HTTP Request Method |
key | string | An object key (Key) is the unique identifier of an object within a bucket. For details, see Object Key (Note: Users do not need to encode the key). |
ak | string | SecretId |
sk | string | SecretKey |
expired | time.Duration | Signature validity period |
opt | interface{} | Extension. It is recommended to fill in a parameter of type *PresignedURLOptions. Can be nil. |
PresignedURLOptions | struct | Specifies the request parameters and request headers to be signed. |
Query | struct | The request parameters to be signed. Signing multiple request parameters with the same Key is not supported, for example, key=value1&key=value2. |
Header | struct | The request headers to be signed. Signing multiple request headers with the same Key is not supported, for example: Header: value1 Header: value2 |
signHost | bool | Optional. The default value is true. It specifies whether to sign the Header Host when a signature is obtained. You can choose not to sign the Header Host, but this may cause request failures or security vulnerabilities. |
package mainimport ("context""github.com/tencentyun/cos-go-sdk-v5""net/http""net/url""os""strings""time")func main() {The bucket name is composed of bucketname-appid, where the appid must be included. You can view the bucket name in the COS console at https://console.cloud.tencent.com/cos5/bucket.Replace with the user's region. The bucket region can be viewed in the "Bucket Overview" section of the COS console at https://console.cloud.tencent.com/. For details about regions, see https://cloud.tencent.com/document/product/436/6224.u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")b := &cos.BaseURL{BucketURL: u}client := cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{// Obtain credentials through environment variables// The environment variable SECRETID represents the user's SecretId. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.SecretID: os.Getenv("SECRETID"), // The user's SecretId. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.// The environment variable SECRETKEY represents the user's SecretKey. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.SecretKey: os.Getenv("SECRETKEY"), // The user's SecretKey. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.},})// Obtain credentials through environment variables// The environment variable SECRETID represents the user's SecretId. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.ak := os.Getenv("SECRETID") // The user's SecretId. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.// The environment variable SECRETKEY represents the user's SecretKey. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.sk := os.Getenv("SECRETKEY") // The user's SecretKey. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.name := "exampleobject"ctx := context.Background()f := strings.NewReader("test")// 1. Upload an object using the standard method_, err := client.Object.Put(ctx, name, f, nil)if err != nil {panic(err)}// Obtain a pre-signed URLpresignedURL, err := client.Object.GetPresignedURL(ctx, http.MethodPut, name, ak, sk, time.Hour, nil)if err != nil {panic(err)}// 2. Upload an object using the pre-signed methoddata := "test upload with presignedURL"f = strings.NewReader(data)req, err := http.NewRequest(http.MethodPut, presignedURL.String(), f)if err != nil {panic(err)}// Users can set request headers as needed.req.Header.Set("Content-Type", "text/html")_, err = http.DefaultClient.Do(req)if err != nil {panic(err)}}
package mainimport ("bytes""context""errors""github.com/tencentyun/cos-go-sdk-v5""io""net/http""net/url""os""time")func main() {The bucket name is composed of bucketname-appid, where the appid must be included. You can view the bucket name in the COS console at https://console.cloud.tencent.com/cos5/bucket.Replace with the user's region. The bucket region can be viewed in the "Bucket Overview" section of the COS console at https://console.cloud.tencent.com/. For details about regions, see https://cloud.tencent.com/document/product/436/6224.u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")b := &cos.BaseURL{BucketURL: u}client := cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{// Obtain credentials through environment variables// The environment variable SECRETID represents the user's SecretId. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.SecretID: os.Getenv("SECRETID"), // The user's SecretId. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.// The environment variable SECRETKEY represents the user's SecretKey. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.SecretKey: os.Getenv("SECRETKEY"), // The user's SecretKey. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.},})// Obtain credentials through environment variables// The environment variable SECRETID represents the user's SecretId. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.ak := os.Getenv("SECRETID") // The user's SecretId. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.// The environment variable SECRETKEY represents the user's SecretKey. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.sk := os.Getenv("SECRETKEY") // The user's SecretKey. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.name := "exampleobject"ctx := context.Background()// 1. Download an object using the standard methodresp, err := client.Object.Get(ctx, name, nil)if err != nil {panic(err)}bs, _ := io.ReadAll(resp.Body)resp.Body.Close()// Obtain a pre-signed URLpresignedURL, err := client.Object.GetPresignedURL(ctx, http.MethodGet, name, ak, sk, time.Hour, nil)if err != nil {panic(err)}// 2. Download an object using a pre-signed URLresp2, err := http.Get(presignedURL.String())if err != nil {panic(err)}bs2, _ := io.ReadAll(resp2.Body)resp2.Body.Close()if bytes.Compare(bs2, bs) != 0 {panic(errors.New("content is not consistent"))}}
package mainimport ("context""fmt""github.com/tencentyun/cos-go-sdk-v5""net/http""net/url""os""time""strings")// By using tags, users can include request parameters or headers in the signature.type URLToken struct {SessionToken string `url:"x-cos-security-token,omitempty" header:"-"`}func main() {// Replace with your temporary credentialstak := os.Getenv("SECRETID") // The user's temporary SecretId. Grant permissions following the principle of least privilege to reduce usage risks. For information on obtaining temporary credentials, see https://www.tencentcloud.com/document/product/436/14048?from_cn_redirect=1.tsk := os.Getenv("SECRETKEY") // The user's temporary SecretKey. Permissions are granted following the principle of least privilege to reduce usage risks. For information on obtaining temporary credentials, see https://www.tencentcloud.com/document/product/436/14048?from_cn_redirect=1.token := &URLToken{SessionToken: "<token>",}u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{})name := "exampleobject"ctx := context.Background()// Method 1: Set the x-cos-security-token via PresignedURLOptions// PresignedURLOptions allows users to add request parameters and headers.opt := &cos.PresignedURLOptions{Query: &url.Values{},Header: &http.Header{},}opt.Query.Add("x-cos-security-token", "<token>")// Obtain a pre-signed URLpresignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodPut, name, tak, tsk, time.Hour, opt)if err != nil {fmt.Printf("Error: %v\\n", err)return}// Upload an object using the pre-signed methoddata := "test upload with presignedURL"f := strings.NewReader(data)req, err := http.NewRequest(http.MethodPut, presignedURL.String(), f)if err != nil {fmt.Printf("Error: %v\\n", err)}_, err = http.DefaultClient.Do(req)if err != nil {fmt.Printf("Error: %v\\n", err)}// Method 2: Set the x-cos-security-token via a tag// Obtain a pre-signed URLpresignedURL, err = c.Object.GetPresignedURL(ctx, http.MethodPut, name, tak, tsk, time.Hour, token)if err != nil {fmt.Printf("Error: %v\\n", err)return}f = strings.NewReader(data)req, err = http.NewRequest(http.MethodPut, presignedURL.String(), f)if err != nil {fmt.Printf("Error: %v\\n", err)}_, err = http.DefaultClient.Do(req)if err != nil {fmt.Printf("Error: %v\\n", err)}}
package mainimport ("context""fmt""github.com/tencentyun/cos-go-sdk-v5""net/http""net/url""os""time")// By using tags, users can include request parameters or headers in the signature.type URLToken struct {SessionToken string `url:"x-cos-security-token,omitempty" header:"-"`}func main() {// Replace with your temporary credentialstak := os.Getenv("SECRETID") // The user's temporary SecretId. Grant permissions following the principle of least privilege to reduce usage risks. For information on obtaining temporary credentials, see https://www.tencentcloud.com/document/product/436/14048?from_cn_redirect=1.tsk := os.Getenv("SECRETKEY") // The user's temporary SecretKey. Permissions are granted following the principle of least privilege to reduce usage risks. For information on obtaining temporary credentials, see https://www.tencentcloud.com/document/product/436/14048?from_cn_redirect=1.token := &URLToken{SessionToken: "<token>",}u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{})name := "exampleobject"ctx := context.Background()// Method 1: Set the x-cos-security-token via PresignedURLOptions// PresignedURLOptions allows users to add request parameters and headers.opt := &cos.PresignedURLOptions{Query: &url.Values{},Header: &http.Header{},}opt.Query.Add("x-cos-security-token", "<token>")// Obtain a pre-signed URLpresignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodGet, name, tak, tsk, time.Hour, opt)if err != nil {fmt.Printf("Error: %v\\n", err)return}// Access an object using a pre-signed URLresp, err := http.Get(presignedURL.String())if err != nil {fmt.Printf("Error: %v\\n", err)}defer resp.Body.Close()fmt.Println(presignedURL.String())fmt.Printf("resp:%v\\n", resp)// Method 2: Set the x-cos-security-token via a tag// Obtain a pre-signed URLpresignedURL, err = c.Object.GetPresignedURL(ctx, http.MethodGet, name, tak, tsk, time.Hour, token)if err != nil {fmt.Printf("Error: %v\\n", err)return}// Access an object using a pre-signed URLresp, err = http.Get(presignedURL.String())if err != nil {fmt.Printf("Error: %v\\n", err)}defer resp.Body.Close()fmt.Println(presignedURL.String())fmt.Printf("resp:%v\\n", resp)}
package mainimport ("context""fmt""github.com/tencentyun/cos-go-sdk-v5""net/http""net/url""os""time")func main() {// Obtain credentials via environment variables// The environment variable SECRETID represents the user's SecretId. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.ak := os.Getenv("SECRETID") // The user's SecretId. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.// The environment variable SECRETKEY represents the user's SecretKey. Log in to the CAM console to view the key at https://console.tencentcloud.com/cam/capi.sk := os.Getenv("SECRETKEY") // The user's SecretKey. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.// Change to the user's custom domainu, _ := url.Parse("https://<custom-domain>")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{})name := "exampleobject"ctx := context.Background()// Obtain a pre-signed URLpresignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodGet, name, ak, sk, time.Hour, nil)if err != nil {fmt.Printf("Error: %v\\n", err)return}// Access an object using a pre-signed URLresp, err := http.Get(presignedURL.String())if err != nil {fmt.Printf("Error: %v\\n", err)}defer resp.Body.Close()fmt.Println(presignedURL.String())fmt.Printf("resp:%v\\n", resp)}
package mainimport ("context""fmt""github.com/tencentyun/cos-go-sdk-v5""net/http""net/url""os""time")func main() {// Replace with your temporary credentialstak := os.Getenv("SECRETID") // The user's SecretId. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.tsk := os.Getenv("SECRETKEY") // The user's SecretKey. It is recommended to use sub-account credentials, granting permissions following the principle of least privilege to reduce usage risks. For information on obtaining sub-account credentials, see https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1.u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{})name := "exampleobject"ctx := context.Background()// PresignedURLOptions allows users to add request parameters and headers.opt := &cos.PresignedURLOptions{// HTTP request parameters. The parameters passed in must match those in the actual request, which prevents users from tampering with the parameters of this HTTP request.Query: &url.Values{},// HTTP request headers. The headers passed in must be included in the actual request, which prevents users from tampering with the HTTP request headers signed here.Header: &http.Header{},}// Add request parameters. The returned pre-signed url will contain these parameters.opt.Query.Add("x-cos-security-token", "<token>")// Add request headers. The returned pre-signed url only includes the headers in its signature. You must still set the corresponding headers when making the request.opt.Header.Add("Content-Type", "text/html")// The SDK includes the Host Header in the signature by default. This means the Host Header is signed when you do not pass the signHost parameter or when SignHost = true.// When signHost = false, the Host Header is not included in the signature. Omitting the Host Header from the signature may cause request failures or security vulnerabilities.var signHost bool = true// Obtain a pre-signed URL. The signature includes the host.presignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodPut, name, tak, tsk, time.Hour, opt, signHost)if err != nil {fmt.Printf("Error: %v\\n", err)return}// Access an object using a pre-signed URLreq, _ := http.NewRequest(http.MethodPut, presignedURL.String(), strings.NewReader("test"))// Set the corresponding header when making the request.req.Header.Set("Content-Type", "text/html")resp, err := http.DefaultClient.Do(req)if err != nil {fmt.Printf("Error: %v\\n", err)}defer resp.Body.Close()fmt.Println(presignedURL.String())fmt.Printf("resp:%v\\n", resp)}
package mainimport ("bytes""context""encoding/xml""fmt""io""io/ioutil""math/rand""net/http""net/url""os""time""github.com/tencentyun/cos-go-sdk-v5")func logStatus(err error) {if err == nil {return}if cos.IsNotFoundError(err) {fmt.Println("WARN: Resource is not existed")} else if e, ok := cos.IsCOSError(err); ok {fmt.Printf("ERROR: Code: %v\\n", e.Code)fmt.Printf("ERROR: Message: %v\\n", e.Message)fmt.Printf("ERROR: Resource: %v\\n", e.Resource)fmt.Printf("ERROR: RequestId: %v\\n", e.RequestID)} else {fmt.Printf("ERROR: %v\\n", err)}}func main() {ak := os.Getenv("SECRETID")sk := os.Getenv("SECRETKEY")// The bucket name is composed of bucketname-appid.u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: ak,SecretKey: sk,},})name := "test/multipart_presigned_example"ctx := context.Background()// ===================== Step 1: Pre-sign an InitiateMultipartUpload Request =====================// The InitiateMultipartUpload operation requires the POST method and the uploads query parameter.initOpt := &cos.PresignedURLOptions{Query: &url.Values{},}initOpt.Query.Set("uploads", "")initPresignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodPost, name, ak, sk, time.Hour, initOpt)if err != nil {logStatus(err)return}fmt.Printf("InitMultipartUpload PresignedURL: %s\\n\\n", initPresignedURL.String())// Initiate an InitiateMultipartUpload request using a pre-signed URL.initReq, _ := http.NewRequest(http.MethodPost, initPresignedURL.String(), nil)initResp, err := http.DefaultClient.Do(initReq)if err != nil {fmt.Printf("InitiateMultipartUpload request failed: %v\\n", err)return}defer initResp.Body.Close()initBody, _ := ioutil.ReadAll(initResp.Body)if initResp.StatusCode != 200 {fmt.Printf("InitiateMultipartUpload failed, status: %s, body: %s\\n", initResp.Status, string(initBody))return}var initResult cos.InitiateMultipartUploadResultif err := xml.Unmarshal(initBody, &initResult); err != nil {fmt.Printf("Parse InitiateMultipartUpload response failed: %v\\n", err)return}uploadID := initResult.UploadIDfmt.Printf("InitiateMultipartUpload succeeded. UploadID: %s\\n\\n", uploadID)// ===================== Step -2: Pre-sign an UploadPart Request =====================// Simulate three chunks, each containing 1 MB of random data.partCount := 3partSize := 1 * 1024 * 1024 // 1MBparts := make([]cos.Object, 0, partCount)for i := 1; i <= partCount; i++ {// Generate a pre-signed URL with the partNumber and uploadId query parameters.partOpt := &cos.PresignedURLOptions{Query: &url.Values{},}partOpt.Query.Set("partNumber", fmt.Sprintf("%d", i))partOpt.Query.Set("uploadId", uploadID)partPresignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodPut, name, ak, sk, time.Hour, partOpt)if err != nil {logStatus(err)return}fmt.Printf("UploadPart %d PresignedURL: %s\\n\\n", i, partPresignedURL.String())// Generate random data.data := make([]byte, partSize)rand.Read(data)// Upload a chunk using a pre-signed URL.partReq, _ := http.NewRequest(http.MethodPut, partPresignedURL.String(), bytes.NewReader(data))partReq.ContentLength = int64(len(data))partResp, err := http.DefaultClient.Do(partReq)if err != nil {fmt.Printf("UploadPart %d request failed: %v\\n", i, err)return}io.Copy(ioutil.Discard, partResp.Body)partResp.Body.Close()if partResp.StatusCode != 200 {fmt.Printf("UploadPart %d failed, status: %s\\n", i, partResp.Status)return}etag := partResp.Header.Get("ETag")fmt.Printf("UploadPart %d succeeded. ETag: %s\\n\\n", i, etag)parts = append(parts, cos.Object{PartNumber: i,ETag: etag,})}// ===================== Step 3: Pre-sign a CompleteMultipartUpload Request =====================completeOpt := &cos.PresignedURLOptions{Query: &url.Values{},}completeOpt.Query.Set("uploadId", uploadID)completePresignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodPost, name, ak, sk, time.Hour, completeOpt)if err != nil {logStatus(err)return}fmt.Printf("CompleteMultipartUpload PresignedURL: %s\\n\\n", completePresignedURL.String())// Construct the XML Body for CompleteMultipartUpload.completeBody := &cos.CompleteMultipartUploadOptions{Parts: parts,}xmlData, err := xml.Marshal(completeBody)if err != nil {fmt.Printf("Marshal CompleteMultipartUpload body failed: %v\\n", err)return}// Complete the multipart upload using a pre-signed URL.completeReq, _ := http.NewRequest(http.MethodPost, completePresignedURL.String(), bytes.NewReader(xmlData))completeReq.Header.Set("Content-Type", "application/xml")completeResp, err := http.DefaultClient.Do(completeReq)if err != nil {fmt.Printf("CompleteMultipartUpload request failed: %v\\n", err)return}defer completeResp.Body.Close()completeRespBody, _ := ioutil.ReadAll(completeResp.Body)if completeResp.StatusCode != 200 {fmt.Printf("CompleteMultipartUpload failed, status: %s, body: %s\\n", completeResp.Status, string(completeRespBody))return}var completeResult cos.CompleteMultipartUploadResultif err := xml.Unmarshal(completeRespBody, &completeResult); err != nil {fmt.Printf("Parse CompleteMultipartUpload response failed: %v\\n", err)return}fmt.Printf("Multipart upload completed!\\n")fmt.Printf(" Location: %s\\n", completeResult.Location)fmt.Printf(" Bucket: %s\\n", completeResult.Bucket)fmt.Printf(" Key: %s\\n", completeResult.Key)fmt.Printf(" ETag: %s\\n", completeResult.ETag)}
Was this page helpful?
You can also Contact sales or Submit a Ticket for help.
Help us improve! Rate your documentation experience in 5 mins.
Feedback