Browse Source

Merge pull request #82 from agin719/common-dev

Common dev
tags/v0.7.8
agin719 5 years ago
committed by GitHub
parent
commit
e870e71637
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      auth.go
  2. 177
      batch.go
  3. 20
      batch_test.go
  4. 58
      bucket.go
  5. 51
      bucket_encryption.go
  6. 100
      bucket_encryption_test.go
  7. 90
      bucket_origin.go
  8. 71
      bucket_policy.go
  9. 40
      bucket_referer.go
  10. 88
      bucket_referer_test.go
  11. 105
      bucket_test.go
  12. 24
      ci.go
  13. 4
      cos.go
  14. 56
      costesting/ci_test.go
  15. 24
      error.go
  16. 9
      example/batch/create_job.go
  17. 105
      example/batch/create_job_restore.go
  18. 35
      example/bucket/delPolicy.go
  19. 68
      example/bucket/encryption.go
  20. 38
      example/bucket/getLogging.go
  21. 64
      example/bucket/getObjectVersion.go
  22. 39
      example/bucket/getPolicy.go
  23. 92
      example/bucket/origin.go
  24. 63
      example/bucket/putPolicy.go
  25. 67
      example/bucket/referer.go
  26. 23
      example/object/MultiUpload.go
  27. 27
      example/object/abortMultipartUpload.go
  28. 70
      example/object/ci_put.go
  29. 35
      example/object/completeMultipartUpload.go
  30. 36
      example/object/copy.go
  31. 31
      example/object/copyPart.go
  32. 26
      example/object/delete.go
  33. 27
      example/object/deleteMultiple.go
  34. 42
      example/object/get.go
  35. 25
      example/object/getACL.go
  36. 24
      example/object/getAnonymous.go
  37. 32
      example/object/getByPresignedURL.go
  38. 24
      example/object/head.go
  39. 23
      example/object/initiateMultipartUpload.go
  40. 31
      example/object/listParts.go
  41. 26
      example/object/options.go
  42. 44
      example/object/presigned_url_with_token.go
  43. 35
      example/object/put.go
  44. 28
      example/object/putACL.go
  45. 24
      example/object/restore.go
  46. 81
      example/object/sse_c.go
  47. 75
      example/object/sse_cos.go
  48. 75
      example/object/tagging.go
  49. 23
      example/object/upload.go
  50. 29
      example/object/uploadFile.go
  51. 27
      example/object/uploadPart.go
  52. 96
      example/sts/sts_v3.go
  53. 1
      go.mod
  54. 2
      go.sum
  55. 88
      object.go

1
auth.go

@ -125,6 +125,7 @@ func newAuthorization(secretID, secretKey string, req *http.Request, authTime *A
keyTime := authTime.keyString()
signKey := calSignKey(secretKey, keyTime)
req.Header.Set("Host", req.Host)
formatHeaders := *new(string)
signedHeaderList := *new([]string)
formatHeaders, signedHeaderList = genFormatHeaders(req.Header)

177
batch.go

@ -10,100 +10,107 @@ import (
type BatchService service
type BatchRequestHeaders struct {
XCosAppid int `header:"x-cos-appid"`
ContentLength string `header:"Content-Length,omitempty"`
ContentType string `header:"Content-Type,omitempty"`
Headers *http.Header `header:"-"`
XCosAppid int `header:"x-cos-appid" xml:"-" url:"-"`
ContentLength string `header:"Content-Length,omitempty" xml:"-" url:"-"`
ContentType string `header:"Content-Type,omitempty" xml:"-" url:"-"`
Headers *http.Header `header:"-" xml:"-", url:"-"`
}
// BatchProgressSummary
type BatchProgressSummary struct {
NumberOfTasksFailed int `xml:"NumberOfTasksFailed"`
NumberOfTasksSucceeded int `xml:"NumberOfTasksSucceeded"`
TotalNumberOfTasks int `xml:"TotalNumberOfTasks"`
NumberOfTasksFailed int `xml:"NumberOfTasksFailed" header:"-" url:"-"`
NumberOfTasksSucceeded int `xml:"NumberOfTasksSucceeded" header:"-" url:"-"`
TotalNumberOfTasks int `xml:"TotalNumberOfTasks" header:"-" url:"-"`
}
// BatchJobReport
type BatchJobReport struct {
Bucket string `xml:"Bucket"`
Enabled string `xml:"Enabled"`
Format string `xml:"Format"`
Prefix string `xml:"Prefix,omitempty"`
ReportScope string `xml:"ReportScope"`
Bucket string `xml:"Bucket" header:"-" url:"-"`
Enabled string `xml:"Enabled" header:"-" url:"-"`
Format string `xml:"Format" header:"-" url:"-"`
Prefix string `xml:"Prefix,omitempty" header:"-" url:"-"`
ReportScope string `xml:"ReportScope" header:"-" url:"-"`
}
// BatchJobOperationCopy
type BatchMetadata struct {
Key string `xml:"Key"`
Value string `xml:"Value"`
Key string `xml:"Key" header:"-" url:"-"`
Value string `xml:"Value" header:"-" url:"-"`
}
type BatchNewObjectMetadata struct {
CacheControl string `xml:"CacheControl,omitempty"`
ContentDisposition string `xml:"ContentDisposition,omitempty"`
ContentEncoding string `xml:"ContentEncoding,omitempty"`
ContentType string `xml:"ContentType,omitempty"`
HttpExpiresDate string `xml:"HttpExpiresDate,omitempty"`
SSEAlgorithm string `xml:"SSEAlgorithm,omitempty"`
UserMetadata []BatchMetadata `xml:"UserMetadata>member,omitempty"`
CacheControl string `xml:"CacheControl,omitempty" header:"-" url:"-"`
ContentDisposition string `xml:"ContentDisposition,omitempty" header:"-" url:"-"`
ContentEncoding string `xml:"ContentEncoding,omitempty" header:"-" url:"-"`
ContentType string `xml:"ContentType,omitempty" header:"-" url:"-"`
HttpExpiresDate string `xml:"HttpExpiresDate,omitempty" header:"-" url:"-"`
SSEAlgorithm string `xml:"SSEAlgorithm,omitempty" header:"-" url:"-"`
UserMetadata []BatchMetadata `xml:"UserMetadata>member,omitempty" header:"-" url:"-"`
}
type BatchGrantee struct {
DisplayName string `xml:"DisplayName,omitempty"`
Identifier string `xml:"Identifier"`
TypeIdentifier string `xml:"TypeIdentifier"`
DisplayName string `xml:"DisplayName,omitempty" header:"-" url:"-"`
Identifier string `xml:"Identifier" header:"-" url:"-"`
TypeIdentifier string `xml:"TypeIdentifier" header:"-" url:"-"`
}
type BatchCOSGrant struct {
Grantee *BatchGrantee `xml:"Grantee"`
Permission string `xml:"Permission"`
Grantee *BatchGrantee `xml:"Grantee" header:"-" url:"-"`
Permission string `xml:"Permission" header:"-" url:"-"`
}
type BatchAccessControlGrants struct {
COSGrants *BatchCOSGrant `xml:"COSGrant,omitempty"`
COSGrants *BatchCOSGrant `xml:"COSGrant,omitempty" header:"-" url:"-"`
}
type BatchJobOperationCopy struct {
AccessControlGrants *BatchAccessControlGrants `xml:"AccessControlGrants,omitempty"`
CannedAccessControlList string `xml:"CannedAccessControlList,omitempty"`
MetadataDirective string `xml:"MetadataDirective,omitempty"`
ModifiedSinceConstraint int64 `xml:"ModifiedSinceConstraint,omitempty"`
UnModifiedSinceConstraint int64 `xml:"UnModifiedSinceConstraint,omitempty"`
NewObjectMetadata *BatchNewObjectMetadata `xml:"NewObjectMetadata,omitempty"`
StorageClass string `xml:"StorageClass,omitempty"`
TargetResource string `xml:"TargetResource"`
AccessControlGrants *BatchAccessControlGrants `xml:"AccessControlGrants,omitempty" header:"-" url:"-"`
CannedAccessControlList string `xml:"CannedAccessControlList,omitempty" header:"-" url:"-"`
MetadataDirective string `xml:"MetadataDirective,omitempty" header:"-" url:"-"`
ModifiedSinceConstraint int64 `xml:"ModifiedSinceConstraint,omitempty" header:"-" url:"-"`
UnModifiedSinceConstraint int64 `xml:"UnModifiedSinceConstraint,omitempty" header:"-" url:"-"`
NewObjectMetadata *BatchNewObjectMetadata `xml:"NewObjectMetadata,omitempty" header:"-" url:"-"`
StorageClass string `xml:"StorageClass,omitempty" header:"-" url:"-"`
TargetResource string `xml:"TargetResource" header:"-" url:"-"`
}
// BatchInitiateRestoreObject
type BatchInitiateRestoreObject struct {
ExpirationInDays int `xml:"ExpirationInDays"`
JobTier string `xml:"JobTier"`
}
// BatchJobOperation
type BatchJobOperation struct {
PutObjectCopy *BatchJobOperationCopy `xml:"COSPutObjectCopy,omitempty" header:"-"`
PutObjectCopy *BatchJobOperationCopy `xml:"COSPutObjectCopy,omitempty" header:"-" url:"-"`
RestoreObject *BatchInitiateRestoreObject `xml:"COSInitiateRestoreObject,omitempty" header:"-" url:"-"`
}
// BatchJobManifest
type BatchJobManifestLocation struct {
ETag string `xml:"ETag" header:"-"`
ObjectArn string `xml:"ObjectArn" header:"-"`
ObjectVersionId string `xml:"ObjectVersionId,omitempty" header:"-"`
ETag string `xml:"ETag" header:"-" url:"-"`
ObjectArn string `xml:"ObjectArn" header:"-" url:"-"`
ObjectVersionId string `xml:"ObjectVersionId,omitempty" header:"-" url:"-"`
}
type BatchJobManifestSpec struct {
Fields []string `xml:"Fields>member,omitempty" header:"-"`
Format string `xml:"Format" header:"-"`
Fields []string `xml:"Fields>member,omitempty" header:"-" url:"-"`
Format string `xml:"Format" header:"-" url:"-"`
}
type BatchJobManifest struct {
Location *BatchJobManifestLocation `xml:"Location" header:"-"`
Spec *BatchJobManifestSpec `xml:"Spec" header:"-"`
Location *BatchJobManifestLocation `xml:"Location" header:"-" url:"-"`
Spec *BatchJobManifestSpec `xml:"Spec" header:"-" url:"-"`
}
type BatchCreateJobOptions struct {
XMLName xml.Name `xml:"CreateJobRequest" header:"-"`
ClientRequestToken string `xml:"ClientRequestToken" header:"-"`
ConfirmationRequired string `xml:"ConfirmationRequired,omitempty" header:"-"`
Description string `xml:"Description,omitempty" header:"-"`
Manifest *BatchJobManifest `xml:"Manifest" header:"-"`
Operation *BatchJobOperation `xml:"Operation" header:"-"`
Priority int `xml:"Priority" header:"-"`
Report *BatchJobReport `xml:"Report" header:"-"`
RoleArn string `xml:"RoleArn" header:"-"`
XMLName xml.Name `xml:"CreateJobRequest" header:"-" url:"-"`
ClientRequestToken string `xml:"ClientRequestToken" header:"-" url:"-"`
ConfirmationRequired string `xml:"ConfirmationRequired,omitempty" header:"-" url:"-"`
Description string `xml:"Description,omitempty" header:"-" url:"-"`
Manifest *BatchJobManifest `xml:"Manifest" header:"-" url:"-"`
Operation *BatchJobOperation `xml:"Operation" header:"-" url:"-"`
Priority int `xml:"Priority" header:"-" url:"-"`
Report *BatchJobReport `xml:"Report" header:"-" url:"-"`
RoleArn string `xml:"RoleArn" header:"-" url:"-"`
}
type BatchCreateJobResult struct {
XMLName xml.Name `xml:"CreateJobResult"`
JobId string `xml:"JobId"`
JobId string `xml:"JobId,omitempty"`
}
func processETag(opt *BatchCreateJobOptions) *BatchCreateJobOptions {
@ -129,31 +136,31 @@ func (s *BatchService) CreateJob(ctx context.Context, opt *BatchCreateJobOptions
}
type BatchJobFailureReasons struct {
FailureCode string `xml:"FailureCode"`
FailureReason string `xml:"FailureReason"`
FailureCode string `xml:"FailureCode" header:"-" url:"-"`
FailureReason string `xml:"FailureReason" header:"-" url:"-"`
}
type BatchDescribeJob struct {
ConfirmationRequired string `xml:"ConfirmationRequired,omitempty"`
CreationTime string `xml:"CreationTime,omitempty"`
Description string `xml:"Description,omitempty"`
FailureReasons *BatchJobFailureReasons `xml:"FailureReasons>JobFailure,omitempty"`
JobId string `xml:"JobId"`
Manifest *BatchJobManifest `xml:"Manifest"`
Operation *BatchJobOperation `xml:"Operation"`
Priority int `xml:"Priority"`
ProgressSummary *BatchProgressSummary `xml:"ProgressSummary"`
Report *BatchJobReport `xml:"Report,omitempty"`
RoleArn string `xml:"RoleArn,omitempty"`
Status string `xml:"Status,omitempty"`
StatusUpdateReason string `xml:"StatusUpdateReason,omitempty"`
SuspendedCause string `xml:"SuspendedCause,omitempty"`
SuspendedDate string `xml:"SuspendedDate,omitempty"`
TerminationDate string `xml:"TerminationDate,omitempty"`
ConfirmationRequired string `xml:"ConfirmationRequired,omitempty" header:"-" url:"-"`
CreationTime string `xml:"CreationTime,omitempty" header:"-" url:"-"`
Description string `xml:"Description,omitempty" header:"-" url:"-"`
FailureReasons *BatchJobFailureReasons `xml:"FailureReasons>JobFailure,omitempty" header:"-" url:"-"`
JobId string `xml:"JobId" header:"-" url:"-"`
Manifest *BatchJobManifest `xml:"Manifest" header:"-" url:"-"`
Operation *BatchJobOperation `xml:"Operation" header:"-" url:"-"`
Priority int `xml:"Priority" header:"-" url:"-"`
ProgressSummary *BatchProgressSummary `xml:"ProgressSummary" header:"-" url:"-"`
Report *BatchJobReport `xml:"Report,omitempty" header:"-" url:"-"`
RoleArn string `xml:"RoleArn,omitempty" header:"-" url:"-"`
Status string `xml:"Status,omitempty" header:"-" url:"-"`
StatusUpdateReason string `xml:"StatusUpdateReason,omitempty" header:"-" url:"-"`
SuspendedCause string `xml:"SuspendedCause,omitempty" header:"-" url:"-"`
SuspendedDate string `xml:"SuspendedDate,omitempty" header:"-" url:"-"`
TerminationDate string `xml:"TerminationDate,omitempty" header:"-" url:"-"`
}
type BatchDescribeJobResult struct {
XMLName xml.Name `xml:"DescribeJobResult"`
Job *BatchDescribeJob `xml:"Job"`
Job *BatchDescribeJob `xml:"Job,omitempty"`
}
func (s *BatchService) DescribeJob(ctx context.Context, id string, headers *BatchRequestHeaders) (*BatchDescribeJobResult, *Response, error) {
@ -171,27 +178,27 @@ func (s *BatchService) DescribeJob(ctx context.Context, id string, headers *Batc
}
type BatchListJobsOptions struct {
JobStatuses string `url:"jobStatuses,omitempty" header:"-"`
MaxResults int `url:"maxResults,omitempty" header:"-"`
NextToken string `url:"nextToken,omitempty" header:"-"`
JobStatuses string `url:"jobStatuses,omitempty" header:"-" xml:"-"`
MaxResults int `url:"maxResults,omitempty" header:"-" xml:"-"`
NextToken string `url:"nextToken,omitempty" header:"-" xml:"-"`
}
type BatchListJobsMember struct {
CreationTime string `xml:"CreationTime,omitempty"`
Description string `xml:"Description,omitempty"`
JobId string `xml:"JobId,omitempty"`
Operation string `xml:"Operation,omitempty"`
Priority int `xml:"Priority,omitempty"`
ProgressSummary *BatchProgressSummary `xml:"ProgressSummary,omitempty"`
Status string `xml:"Status,omitempty"`
TerminationDate string `xml:"TerminationDate,omitempty"`
CreationTime string `xml:"CreationTime,omitempty" header:"-" url:"-"`
Description string `xml:"Description,omitempty" header:"-" url:"-"`
JobId string `xml:"JobId,omitempty" header:"-" url:"-"`
Operation string `xml:"Operation,omitempty" header:"-" url:"-"`
Priority int `xml:"Priority,omitempty" header:"-" url:"-"`
ProgressSummary *BatchProgressSummary `xml:"ProgressSummary,omitempty" header:"-" url:"-"`
Status string `xml:"Status,omitempty" header:"-" url:"-"`
TerminationDate string `xml:"TerminationDate,omitempty" header:"-" url:"-"`
}
type BatchListJobs struct {
Members []BatchListJobsMember `xml:"member,omitempty"`
Members []BatchListJobsMember `xml:"member,omitempty" header:"-" url:"-"`
}
type BatchListJobsResult struct {
XMLName xml.Name `xml:"ListJobsResult"`
Jobs *BatchListJobs `xml:"Jobs"`
Jobs *BatchListJobs `xml:"Jobs,omitempty"`
NextToken string `xml:"NextToken,omitempty"`
}

20
batch_test.go

@ -8,7 +8,7 @@ import (
"reflect"
"testing"
"github.com/google/uuid"
"github.com/google/uuid"
)
func TestBatchService_CreateJob(t *testing.T) {
@ -21,7 +21,7 @@ func TestBatchService_CreateJob(t *testing.T) {
Manifest: &BatchJobManifest{
Location: &BatchJobManifestLocation{
ETag: "15150651828fa9cdcb8356b6d1c7638b",
ObjectArn: "qcs::cos:ap-chengdu::sourcebucket-1250000000/manifests/batch-copy-manifest.csv",
ObjectArn: "qcs::cos:ap-chengdu:uid/1250000000:sourcebucket-1250000000/manifests/batch-copy-manifest.csv",
},
Spec: &BatchJobManifestSpec{
Fields: []string{"Bucket", "Key"},
@ -30,12 +30,12 @@ func TestBatchService_CreateJob(t *testing.T) {
},
Operation: &BatchJobOperation{
PutObjectCopy: &BatchJobOperationCopy{
TargetResource: "qcs::cos:ap-chengdu::destinationbucket-1250000000",
TargetResource: "qcs::cos:ap-chengdu:uid/1250000000:destinationbucket-1250000000",
},
},
Priority: 1,
Report: &BatchJobReport{
Bucket: "qcs::cos:ap-chengdu::sourcebucket-1250000000",
Bucket: "qcs::cos:ap-chengdu:uid/1250000000:sourcebucket-1250000000",
Enabled: "true",
Format: "Report_CSV_V1",
Prefix: "job-result",
@ -104,7 +104,7 @@ func TestBatchService_DescribeJob(t *testing.T) {
<Manifest>
<Location>
<ETag>&quot;15150651828fa9cdcb8356b6d1c7638b&quot;</ETag>
<ObjectArn>qcs::cos:ap-chengdu::sourcebucket-1250000000/manifests/batch-copy-manifest.csv</ObjectArn>
<ObjectArn>qcs::cos:ap-chengdu:uid/1250000000:sourcebucket-1250000000/manifests/batch-copy-manifest.csv</ObjectArn>
</Location>
<Spec>
<Fields>
@ -116,7 +116,7 @@ func TestBatchService_DescribeJob(t *testing.T) {
</Manifest>
<Operation>
<COSPutObjectCopy>
<TargetResource>qcs::cos:ap-chengdu::destinationbucket-1250000000</TargetResource>
<TargetResource>qcs::cos:ap-chengdu:uid/1250000000:destinationbucket-1250000000</TargetResource>
</COSPutObjectCopy>
</Operation>
<Priority>10</Priority>
@ -126,7 +126,7 @@ func TestBatchService_DescribeJob(t *testing.T) {
<TotalNumberOfTasks>10</TotalNumberOfTasks>
</ProgressSummary>
<Report>
<Bucket>qcs::cos:ap-chengdu::sourcebucket-1250000000</Bucket>
<Bucket>qcs::cos:ap-chengdu:uid/1250000000:sourcebucket-1250000000</Bucket>
<Enabled>true</Enabled>
<Format>Report_CSV_V1</Format>
<Prefix>job-result</Prefix>
@ -159,7 +159,7 @@ func TestBatchService_DescribeJob(t *testing.T) {
Manifest: &BatchJobManifest{
Location: &BatchJobManifestLocation{
ETag: "\"15150651828fa9cdcb8356b6d1c7638b\"",
ObjectArn: "qcs::cos:ap-chengdu::sourcebucket-1250000000/manifests/batch-copy-manifest.csv",
ObjectArn: "qcs::cos:ap-chengdu:uid/1250000000:sourcebucket-1250000000/manifests/batch-copy-manifest.csv",
},
Spec: &BatchJobManifestSpec{
Fields: []string{"Bucket", "Key"},
@ -168,7 +168,7 @@ func TestBatchService_DescribeJob(t *testing.T) {
},
Operation: &BatchJobOperation{
PutObjectCopy: &BatchJobOperationCopy{
TargetResource: "qcs::cos:ap-chengdu::destinationbucket-1250000000",
TargetResource: "qcs::cos:ap-chengdu:uid/1250000000:destinationbucket-1250000000",
},
},
Priority: 10,
@ -178,7 +178,7 @@ func TestBatchService_DescribeJob(t *testing.T) {
TotalNumberOfTasks: 10,
},
Report: &BatchJobReport{
Bucket: "qcs::cos:ap-chengdu::sourcebucket-1250000000",
Bucket: "qcs::cos:ap-chengdu:uid/1250000000:sourcebucket-1250000000",
Enabled: "true",
Format: "Report_CSV_V1",
Prefix: "job-result",

58
bucket.go

@ -102,3 +102,61 @@ type Bucket struct {
Region string `xml:"Location,omitempty"`
CreationDate string `xml:",omitempty"`
}
type BucketGetObjectVersionsOptions struct {
Prefix string `url:"prefix,omitempty"`
Delimiter string `url:"delimiter,omitempty"`
EncodingType string `url:"encoding-type,omitempty"`
KeyMarker string `url:"key-marker,omitempty"`
VersionIdMarker string `url:"version-id-marker,omitempty"`
MaxKeys int `url:"max-keys,omitempty"`
}
type BucketGetObjectVersionsResult struct {
XMLName xml.Name `xml:"ListVersionsResult"`
Name string `xml:"Name,omitempty"`
EncodingType string `xml:"EncodingType,omitempty"`
Prefix string `xml:"Prefix,omitempty"`
KeyMarker string `xml:"KeyMarker,omitempty"`
VersionIdMarker string `xml:"VersionIdMarker,omitempty"`
MaxKeys int `xml:"MaxKeys,omitempty"`
Delimiter string `xml:"Delimiter,omitempty"`
IsTruncated bool `xml:"IsTruncated,omitempty"`
NextKeyMarker string `xml:"NextKeyMarker,omitempty"`
NextVersionIdMarker string `xml:"NextVersionIdMarker,omitempty"`
CommonPrefixes []string `xml:"CommonPrefixes>Prefix,omitempty"`
Version []ListVersionsResultVersion `xml:"Version,omitempty"`
DeleteMarker []ListVersionsResultDeleteMarker `xml:"DeleteMarker,omitempty"`
}
type ListVersionsResultVersion struct {
Key string `xml:"Key,omitempty"`
VersionId string `xml:"VersionId,omitempty"`
IsLatest bool `xml:"IsLatest,omitempty"`
LastModified string `xml:"LastModified,omitempty"`
ETag string `xml:"ETag,omitempty"`
Size int `xml:"Size,omitempty"`
StorageClass string `xml:"StorageClass,omitempty"`
Owner *Owner `xml:"Owner,omitempty"`
}
type ListVersionsResultDeleteMarker struct {
Key string `xml:"Key,omitempty"`
VersionId string `xml:"VersionId,omitempty"`
IsLatest bool `xml:"IsLatest,omitempty"`
LastModified string `xml:"LastModified,omitempty"`
Owner *Owner `xml:"Owner,omitempty"`
}
func (s *BucketService) GetObjectVersions(ctx context.Context, opt *BucketGetObjectVersionsOptions) (*BucketGetObjectVersionsResult, *Response, error) {
var res BucketGetObjectVersionsResult
sendOpt := sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?versions",
method: http.MethodGet,
optQuery: opt,
result: &res,
}
resp, err := s.client.send(ctx, &sendOpt)
return &res, resp, err
}

51
bucket_encryption.go

@ -0,0 +1,51 @@
package cos
import (
"context"
"encoding/xml"
"net/http"
)
type BucketEncryptionConfiguration struct {
SSEAlgorithm string `xml:"SSEAlgorithm"`
}
type BucketPutEncryptionOptions struct {
XMLName xml.Name `xml:"ServerSideEncryptionConfiguration"`
Rule *BucketEncryptionConfiguration `xml:"Rule>ApplySideEncryptionConfiguration"`
}
type BucketGetEncryptionResult BucketPutEncryptionOptions
func (s *BucketService) PutEncryption(ctx context.Context, opt *BucketPutEncryptionOptions) (*Response, error) {
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?encryption",
method: http.MethodPut,
body: opt,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}
func (s *BucketService) GetEncryption(ctx context.Context) (*BucketGetEncryptionResult, *Response, error) {
var res BucketGetEncryptionResult
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?encryption",
method: http.MethodGet,
result: &res,
}
resp, err := s.client.send(ctx, sendOpt)
return &res, resp, err
}
func (s *BucketService) DeleteEncryption(ctx context.Context) (*Response, error) {
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?encryption",
method: http.MethodDelete,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}

100
bucket_encryption_test.go

@ -0,0 +1,100 @@
package cos
import (
"context"
"encoding/xml"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestBucketService_GetEncryption(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
vs := values{
"encryption": "",
}
testFormValues(t, r, vs)
fmt.Fprint(w, `<ServerSideEncryptionConfiguration>
<Rule>
<ApplySideEncryptionConfiguration>
<SSEAlgorithm>AES256</SSEAlgorithm>
</ApplySideEncryptionConfiguration>
</Rule>
</ServerSideEncryptionConfiguration>`)
})
res, _, err := client.Bucket.GetEncryption(context.Background())
if err != nil {
t.Fatalf("Bucket.GetEncryption returned error %v", err)
}
want := &BucketGetEncryptionResult{
XMLName: xml.Name{Local: "ServerSideEncryptionConfiguration"},
Rule: &BucketEncryptionConfiguration{
SSEAlgorithm: "AES256",
},
}
if !reflect.DeepEqual(res, want) {
t.Errorf("Bucket.GetEncryption returned %+v, want %+v", res, want)
}
}
func TestBucketService_PutEncryption(t *testing.T) {
setup()
defer teardown()
opt := &BucketPutEncryptionOptions{
Rule: &BucketEncryptionConfiguration{
SSEAlgorithm: "AES256",
},
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
vs := values{
"encryption": "",
}
testFormValues(t, r, vs)
body := new(BucketPutEncryptionOptions)
xml.NewDecoder(r.Body).Decode(body)
want := opt
want.XMLName = xml.Name{Local: "ServerSideEncryptionConfiguration"}
if !reflect.DeepEqual(body, want) {
t.Errorf("Bucket.PutEncryption request\n body: %+v\n, want %+v\n", body, want)
}
})
_, err := client.Bucket.PutEncryption(context.Background(), opt)
if err != nil {
t.Fatalf("Bucket.PutEncryption returned error: %v", err)
}
}
func TestBucketService_DeleteEncryption(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodDelete)
vs := values{
"encryption": "",
}
testFormValues(t, r, vs)
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Bucket.DeleteEncryption(context.Background())
if err != nil {
t.Fatalf("Bucket.DeleteEncryption returned error: %v", err)
}
}

90
bucket_origin.go

@ -0,0 +1,90 @@
package cos
import (
"context"
"encoding/xml"
"net/http"
)
type BucketPutOriginOptions struct {
XMLName xml.Name `xml:"OriginConfiguration"`
Rule []BucketOriginRule `xml:"OriginRule"`
}
type BucketOriginRule struct {
OriginType string `xml:"OriginType"`
OriginCondition *BucketOriginCondition `xml:"OriginCondition"`
OriginParameter *BucketOriginParameter `xml:"OriginParameter"`
OriginInfo *BucketOriginInfo `xml:"OriginInfo"`
}
type BucketOriginCondition struct {
HTTPStatusCode string `xml:"HTTPStatusCode,omitempty"`
Prefix string `xml:"Prefix,omitempty"`
}
type BucketOriginParameter struct {
Protocol string `xml:"Protocol,omitempty"`
FollowQueryString bool `xml:"FollowQueryString,omitempty"`
HttpHeader *BucketOriginHttpHeader `xml:"HttpHeader,omitempty"`
FollowRedirection bool `xml:"FollowRedirection,omitempty"`
HttpRedirectCode string `xml:"HttpRedirectCode,omitempty"`
CopyOriginData bool `xml:"CopyOriginData,omitempty"`
}
type BucketOriginHttpHeader struct {
// 目前还不支持 FollowAllHeaders
// FollowAllHeaders bool `xml:"FollowAllHeaders,omitempty"`
NewHttpHeaders []OriginHttpHeader `xml:"NewHttpHeaders>Header,omitempty"`
FollowHttpHeaders []OriginHttpHeader `xml:"FollowHttpHeaders>Header,omitempty"`
}
type OriginHttpHeader struct {
Key string `xml:"Key,omitempty"`
Value string `xml:"Value,omitempty"`
}
type BucketOriginInfo struct {
HostInfo string `xml:"HostInfo>HostName,omitempty"`
FileInfo *BucketOriginFileInfo `xml:"FileInfo,omitempty"`
}
type BucketOriginFileInfo struct {
PrefixDirective bool `xml:"PrefixDirective,omitempty"`
Prefix string `xml:"Prefix,omitempty"`
Suffix string `xml:"Suffix,omitempty"`
}
type BucketGetOriginResult BucketPutOriginOptions
func (s *BucketService) PutOrigin(ctx context.Context, opt *BucketPutOriginOptions) (*Response, error) {
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?origin",
method: http.MethodPut,
body: opt,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}
func (s *BucketService) GetOrigin(ctx context.Context) (*BucketGetOriginResult, *Response, error) {
var res BucketGetOriginResult
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?origin",
method: http.MethodGet,
result: &res,
}
resp, err := s.client.send(ctx, sendOpt)
return &res, resp, err
}
func (s *BucketService) DeleteOrigin(ctx context.Context) (*Response, error) {
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?origin",
method: http.MethodDelete,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}

71
bucket_policy.go

@ -0,0 +1,71 @@
package cos
import (
"bytes"
"context"
"encoding/json"
"net/http"
"strings"
)
type BucketStatement struct {
Principal map[string][]string `json:"principal,omitempty"`
Action []string `json:"action,omitempty"`
Effect string `json:"effect,omitempty"`
Resource []string `json:"resource,omitempty"`
Condition map[string]map[string]interface{} `json:"condition,omitempty"`
}
type BucketPutPolicyOptions struct {
Statement []BucketStatement `json:"statement,omitempty"`
Version string `json:"version,omitempty"`
Principal map[string][]string `json:"principal,omitempty"`
}
type BucketGetPolicyResult BucketPutPolicyOptions
func (s *BucketService) PutPolicy(ctx context.Context, opt *BucketPutPolicyOptions) (*Response, error) {
var f *strings.Reader
if opt != nil {
bs, err := json.Marshal(opt)
if err != nil {
return nil, err
}
body := string(bs)
f = strings.NewReader(body)
}
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?policy",
method: http.MethodPut,
body: f,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}
func (s *BucketService) GetPolicy(ctx context.Context) (*BucketGetPolicyResult, *Response, error) {
var bs bytes.Buffer
var res BucketGetPolicyResult
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?policy",
method: http.MethodGet,
result: &bs,
}
resp, err := s.client.send(ctx, sendOpt)
if err == nil {
err = json.Unmarshal(bs.Bytes(), &res)
}
return &res, resp, err
}
func (s *BucketService) DeletePolicy(ctx context.Context) (*Response, error) {
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?policy",
method: http.MethodDelete,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}

40
bucket_referer.go

@ -0,0 +1,40 @@
package cos
import (
"context"
"encoding/xml"
"net/http"
)
type BucketPutRefererOptions struct {
XMLName xml.Name `xml:"RefererConfiguration"`
Status string `xml:"Status"`
RefererType string `xml:"RefererType"`
DomainList []string `xml:"DomainList>Domain"`
EmptyReferConfiguration string `xml:"EmptyReferConfiguration,omitempty"`
}
type BucketGetRefererResult BucketPutRefererOptions
func (s *BucketService) PutReferer(ctx context.Context, opt *BucketPutRefererOptions) (*Response, error) {
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?referer",
method: http.MethodPut,
body: opt,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}
func (s *BucketService) GetReferer(ctx context.Context) (*BucketGetRefererResult, *Response, error) {
var res BucketGetRefererResult
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/?referer",
method: http.MethodGet,
result: &res,
}
resp, err := s.client.send(ctx, sendOpt)
return &res, resp, err
}

88
bucket_referer_test.go

@ -0,0 +1,88 @@
package cos
import (
"context"
"encoding/xml"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestBucketService_GetReferer(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
vs := values{
"referer": "",
}
testFormValues(t, r, vs)
fmt.Fprint(w, `<RefererConfiguration>
<Status>Enabled</Status>
<RefererType>White-List</RefererType>
<DomainList>
<Domain>*.qq.com</Domain>
<Domain>*.qcloud.com</Domain>
</DomainList>
<EmptyReferConfiguration>Allow</EmptyReferConfiguration>
</RefererConfiguration>`)
})
res, _, err := client.Bucket.GetReferer(context.Background())
if err != nil {
t.Fatalf("Bucket.GetReferer returned error %v", err)
}
want := &BucketGetRefererResult{
XMLName: xml.Name{Local: "RefererConfiguration"},
Status: "Enabled",
RefererType: "White-List",
DomainList: []string{
"*.qq.com",
"*.qcloud.com",
},
EmptyReferConfiguration: "Allow",
}
if !reflect.DeepEqual(res, want) {
t.Errorf("Bucket.GetReferer returned %+v, want %+v", res, want)
}
}
func TestBucketService_PutReferer(t *testing.T) {
setup()
defer teardown()
opt := &BucketPutRefererOptions{
Status: "Enabled",
RefererType: "White-List",
DomainList: []string{
"*.qq.com",
"*.qcloud.com",
},
EmptyReferConfiguration: "Allow",
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
vs := values{
"referer": "",
}
testFormValues(t, r, vs)
body := new(BucketPutRefererOptions)
xml.NewDecoder(r.Body).Decode(body)
want := opt
want.XMLName = xml.Name{Local: "RefererConfiguration"}
if !reflect.DeepEqual(body, want) {
t.Errorf("Bucket.PutReferer request\n body: %+v\nwant %+v\n", body, want)
}
})
_, err := client.Bucket.PutReferer(context.Background(), opt)
if err != nil {
t.Fatalf("Bucket.PutReferer returned error: %v", err)
}
}

105
bucket_test.go

@ -150,3 +150,108 @@ func TestBucketService_Head(t *testing.T) {
t.Fatalf("Bucket.Head returned error: %v", err)
}
}
func TestBucketService_GetObjectVersions(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
w.WriteHeader(http.StatusOK)
vs := values{
"versions": "",
"delimiter": "/",
}
testFormValues(t, r, vs)
fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?>
<ListVersionsResult>
<Name>examplebucket-1250000000</Name>
<Prefix/>
<KeyMarker/>
<VersionIdMarker/>
<MaxKeys>1000</MaxKeys>
<IsTruncated>false</IsTruncated>
<Delimiter>/</Delimiter>
<CommonPrefixes>
<Prefix>example-folder-1/</Prefix>
</CommonPrefixes>
<CommonPrefixes>
<Prefix>example-folder-2/</Prefix>
</CommonPrefixes>
<Version>
<Key>example-object-1.jpg</Key>
<VersionId>MTg0NDUxNzgxMjEzNTU3NTk1Mjg</VersionId>
<IsLatest>true</IsLatest>
<LastModified>2019-08-16T10:45:53.000Z</LastModified>
<ETag>&quot;5d1143df07a17b23320d0da161e2819e&quot;</ETag>
<Size>30</Size>
<StorageClass>STANDARD</StorageClass>
<Owner>
<ID>1250000000</ID>
<DisplayName>1250000000</DisplayName>
</Owner>
</Version>
<DeleteMarker>
<Key>example-object-1.jpg</Key>
<VersionId>MTg0NDUxNzgxMjEzNjE1OTcxMzM</VersionId>
<IsLatest>false</IsLatest>
<LastModified>2019-08-16T10:45:47.000Z</LastModified>
<Owner>
<ID>1250000000</ID>
<DisplayName>1250000000</DisplayName>
</Owner>
</DeleteMarker>
</ListVersionsResult>`)
})
want := &BucketGetObjectVersionsResult {
XMLName: xml.Name { Local: "ListVersionsResult" },
Name: "examplebucket-1250000000",
MaxKeys: 1000,
IsTruncated: false,
Delimiter: "/",
CommonPrefixes: []string {
"example-folder-1/",
"example-folder-2/",
},
Version: []ListVersionsResultVersion {
{
Key: "example-object-1.jpg",
VersionId: "MTg0NDUxNzgxMjEzNTU3NTk1Mjg",
IsLatest: true,
LastModified: "2019-08-16T10:45:53.000Z",
ETag: "\"5d1143df07a17b23320d0da161e2819e\"",
Size: 30,
StorageClass: "STANDARD",
Owner: &Owner {
ID: "1250000000",
DisplayName: "1250000000",
},
},
},
DeleteMarker: []ListVersionsResultDeleteMarker {
{
Key: "example-object-1.jpg",
VersionId: "MTg0NDUxNzgxMjEzNjE1OTcxMzM",
IsLatest: false,
LastModified: "2019-08-16T10:45:47.000Z",
Owner: &Owner {
ID: "1250000000",
DisplayName: "1250000000",
},
},
},
}
opt := &BucketGetObjectVersionsOptions {
Delimiter: "/",
}
res, _, err := client.Bucket.GetObjectVersions(context.Background(), opt)
if err != nil {
t.Fatalf("Bucket.GetObjectVersions returned error: %v", err)
}
if !reflect.DeepEqual(res, want) {
t.Errorf("Bucket.GetObjectVersions returned\n%+v\nwant\n%+v", res, want)
}
}

24
ci.go

@ -0,0 +1,24 @@
package cos
import (
"encoding/json"
)
type PicOperations struct {
IsPicInfo int `json:"is_pic_info,omitempty"`
Rules []PicOperationsRules `json:"rules,omitemtpy"`
}
type PicOperationsRules struct {
Bucket string `json:"bucket,omitempty"`
FileId string `json:"fileid"`
Rule string `json:"rule"`
}
func EncodePicOperations(pic *PicOperations) string {
bs, err := json.Marshal(pic)
if err != nil {
return ""
}
return string(bs)
}

4
cos.go

@ -21,7 +21,7 @@ import (
const (
// Version current go sdk version
Version = "0.7.3"
Version = "0.7.7"
userAgent = "cos-go-sdk-v5/" + Version
contentTypeXML = "application/xml"
defaultServiceBaseURL = "http://service.cos.myqcloud.com"
@ -329,6 +329,8 @@ type ACLHeaderOptions struct {
XCosGrantRead string `header:"x-cos-grant-read,omitempty" url:"-" xml:"-"`
XCosGrantWrite string `header:"x-cos-grant-write,omitempty" url:"-" xml:"-"`
XCosGrantFullControl string `header:"x-cos-grant-full-control,omitempty" url:"-" xml:"-"`
XCosGrantReadACP string `header:"x-cos-grant-read-acp,omitempty" url:"-" xml:"-"`
XCosGrantWriteACP string `header:"x-cos-grant-write-acp,omitempty" url:"-" xml:"-"`
}
// ACLGrantee is the param of ACLGrant

56
costesting/ci_test.go

@ -184,6 +184,15 @@ func (s *CosTestSuite) TestGetBucket() {
assert.Nil(s.T(), err, "GetBucket Failed")
}
func (s *CosTestSuite) TestGetObjectVersions() {
opt := &cos.BucketGetObjectVersionsOptions {
Prefix: "中文",
MaxKeys: 3,
}
_, _, err := s.Client.Bucket.GetObjectVersions(context.Background(), opt)
assert.Nil(s.T(), err, "GetObjectVersions Failed")
}
func (s *CosTestSuite) TestGetBucketLocation() {
v, _, err := s.Client.Bucket.GetLocation(context.Background())
assert.Nil(s.T(), err, "GetLocation Failed")
@ -751,7 +760,7 @@ func (s *CosTestSuite) TestBatch() {
Manifest: &cos.BatchJobManifest{
Location: &cos.BatchJobManifestLocation{
ETag: etag,
ObjectArn: "qcs::cos:" + kBatchRegion + "::" + kBatchBucket + "/" + manifest_name,
ObjectArn: "qcs::cos:" + kBatchRegion + ":uid/" + s.Appid + ":" + kBatchBucket + "/" + manifest_name,
},
Spec: &cos.BatchJobManifestSpec{
Fields: []string{"Bucket", "Key"},
@ -760,12 +769,12 @@ func (s *CosTestSuite) TestBatch() {
},
Operation: &cos.BatchJobOperation{
PutObjectCopy: &cos.BatchJobOperationCopy{
TargetResource: "qcs::cos:" + kBatchRegion + "::" + kTargetBatchBucket,
TargetResource: "qcs::cos:" + kBatchRegion + ":uid/" + s.Appid + ":" + kTargetBatchBucket,
},
},
Priority: 1,
Report: &cos.BatchJobReport{
Bucket: "qcs::cos:" + kBatchRegion + "::" + kBatchBucket,
Bucket: "qcs::cos:" + kBatchRegion + ":uid/" + s.Appid + ":" + kBatchBucket,
Enabled: "true",
Format: "Report_CSV_V1",
Prefix: "job-result",
@ -802,6 +811,7 @@ func (s *CosTestSuite) TestBatch() {
assert.Equal(s.T(), res3.JobId, jobid, "jobid failed")
assert.Equal(s.T(), res3.Priority, 3, "priority not right")
// 等待状态变成Suspended
for i := 0; i < 10; i = i + 1 {
res, _, err := client.Batch.DescribeJob(context.Background(), jobid, headers)
assert.Nil(s.T(), err, "describe job Failed")
@ -830,6 +840,46 @@ func (s *CosTestSuite) TestBatch() {
assert.Equal(s.T(), res4.StatusUpdateReason, "to test", "StatusUpdateReason failed")
}
func (s *CosTestSuite) TestEncryption() {
opt := &cos.BucketPutEncryptionOptions{
Rule: &cos.BucketEncryptionConfiguration{
SSEAlgorithm: "AES256",
},
}
_, err := s.Client.Bucket.PutEncryption(context.Background(), opt)
assert.Nil(s.T(), err, "PutEncryption Failed")
res, _, err := s.Client.Bucket.GetEncryption(context.Background())
assert.Nil(s.T(), err, "GetEncryption Failed")
assert.Equal(s.T(), opt.Rule.SSEAlgorithm, res.Rule.SSEAlgorithm, "GetEncryption Failed")
_, err = s.Client.Bucket.DeleteEncryption(context.Background())
assert.Nil(s.T(), err, "DeleteEncryption Failed")
}
func (s *CosTestSuite) TestReferer() {
opt := &cos.BucketPutRefererOptions{
Status: "Enabled",
RefererType: "White-List",
DomainList: []string{
"*.qq.com",
"*.qcloud.com",
},
EmptyReferConfiguration: "Allow",
}
_, err := s.Client.Bucket.PutReferer(context.Background(), opt)
assert.Nil(s.T(), err, "PutReferer Failed")
res, _, err := s.Client.Bucket.GetReferer(context.Background())
assert.Nil(s.T(), err, "GetReferer Failed")
assert.Equal(s.T(), opt.Status, res.Status, "GetReferer Failed")
assert.Equal(s.T(), opt.RefererType, res.RefererType, "GetReferer Failed")
assert.Equal(s.T(), opt.DomainList, res.DomainList, "GetReferer Failed")
assert.Equal(s.T(), opt.EmptyReferConfiguration, res.EmptyReferConfiguration, "GetReferer Failed")
}
// End of api test
// All methods that begin with "Test" are run as tests within a

24
error.go

@ -16,7 +16,7 @@ type ErrorResponse struct {
Code string
Message string
Resource string
RequestID string `header:"x-cos-request-id,omitempty" url:"-" xml:"-"`
RequestID string `header:"x-cos-request-id,omitempty" url:"-" xml:"RequestId,omitempty"`
TraceID string `xml:"TraceId,omitempty"`
}
@ -47,3 +47,25 @@ func checkResponse(r *http.Response) error {
}
return errorResponse
}
func IsNotFoundError(e error) bool {
if e == nil {
return false
}
err, ok := e.(*ErrorResponse)
if !ok {
return false
}
if err.Response != nil && err.Response.StatusCode == 404 {
return true
}
return false
}
func IsCOSError(e error) (*ErrorResponse, bool) {
if e == nil {
return nil, false
}
err, ok := e.(*ErrorResponse)
return err, ok
}

9
example/batch/create_job.go

@ -2,20 +2,21 @@ package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"fmt"
"github.com/google/uuid"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
"github.com/google/uuid"
)
func main() {
test_batch_bucket := "testcd-1259654469"
target_batch_bucket := "targetcd-1259654469"
target_batch_bucket := "cosgosdkreptest-1259654469"
appid := 1259654469
uin := "100010805041"
region := "ap-chengdu"
@ -73,7 +74,7 @@ func main() {
},
Operation: &cos.BatchJobOperation{
PutObjectCopy: &cos.BatchJobOperationCopy{
TargetResource: "qcs::cos:" + region + "::" + target_batch_bucket,
TargetResource: "qcs::cos:" + region + ":uid/" + strconv.Itoa(appid) + ":" + target_batch_bucket,
},
},
Priority: 1,

105
example/batch/create_job_restore.go

@ -0,0 +1,105 @@
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"github.com/google/uuid"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func main() {
test_batch_bucket := "testcd-1259654469"
appid := 1259654469
uin := "100010805041"
region := "ap-chengdu"
// bucket url:<Bucketname-Appid>.cos.<region>.mycloud.com
bucketurl, _ := url.Parse("https://" + test_batch_bucket + ".cos." + region + ".myqcloud.com")
// batch url:<uin>.cos-control.<region>.myqcloud.ccom
batchurl, _ := url.Parse("https://" + uin + ".cos-control." + region + ".myqcloud.com")
b := &cos.BaseURL{BucketURL: bucketurl, BatchURL: batchurl}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
// 创建需要归档恢复的文件
source_name := "test/restore.txt"
sf := strings.NewReader("batch test content")
objopt := &cos.ObjectPutOptions{
nil,
&cos.ObjectPutHeaderOptions{
XCosStorageClass: "Archive",
},
}
_, err := c.Object.Put(context.Background(), source_name, sf, objopt)
if err != nil {
panic(err)
}
// 创建清单文件
manifest_name := "test/manifest.csv"
f := strings.NewReader(test_batch_bucket + "," + source_name)
resp, err := c.Object.Put(context.Background(), manifest_name, f, nil)
if err != nil {
panic(err)
}
etag := resp.Header.Get("ETag")
uuid_str := uuid.New().String()
opt := &cos.BatchCreateJobOptions{
ClientRequestToken: uuid_str,
ConfirmationRequired: "true",
Description: "test batch",
Manifest: &cos.BatchJobManifest{
Location: &cos.BatchJobManifestLocation{
ETag: etag,
ObjectArn: "qcs::cos:" + region + "::" + test_batch_bucket + "/" + manifest_name,
},
Spec: &cos.BatchJobManifestSpec{
Fields: []string{"Bucket", "Key"},
Format: "COSBatchOperations_CSV_V1",
},
},
Operation: &cos.BatchJobOperation{
RestoreObject: &cos.BatchInitiateRestoreObject{
ExpirationInDays: 3,
JobTier: "Standard",
},
},
Priority: 1,
Report: &cos.BatchJobReport{
Bucket: "qcs::cos:" + region + "::" + test_batch_bucket,
Enabled: "true",
Format: "Report_CSV_V1",
Prefix: "job-result",
ReportScope: "AllTasks",
},
RoleArn: "qcs::cam::uin/" + uin + ":roleName/COSBatch_QcsRole",
}
headers := &cos.BatchRequestHeaders{
XCosAppid: appid,
}
res, _, err := c.Batch.CreateJob(context.Background(), opt, headers)
if err != nil {
panic(err)
}
fmt.Println(res)
}

35
example/bucket/delPolicy.go

@ -0,0 +1,35 @@
package main
import (
"context"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
_, err := c.Bucket.DeletePolicy(context.Background())
if err != nil {
panic(err)
}
}

68
example/bucket/encryption.go

@ -0,0 +1,68 @@
package main
import (
"context"
"encoding/xml"
"fmt"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
fmt.Println("Resource is not existed")
} else if e, ok := cos.IsCOSError(err); ok {
fmt.Printf("Code: %v\n", e.Code)
fmt.Printf("Message: %v\n", e.Message)
fmt.Printf("Resource: %v\n", e.Resource)
fmt.Printf("RequestId: %v\n", e.RequestID)
// ERROR
} else {
fmt.Println(err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.BucketPutEncryptionOptions{
XMLName: xml.Name{Local: "ServerSideEncryptionConfiguration"},
Rule: &cos.BucketEncryptionConfiguration{
SSEAlgorithm: "AES256",
},
}
_, err := c.Bucket.PutEncryption(context.Background(), opt)
log_status(err)
res, _, err := c.Bucket.GetEncryption(context.Background())
log_status(err)
fmt.Printf("%+v\n", res)
_, err = c.Bucket.DeleteEncryption(context.Background())
log_status(err)
}

38
example/bucket/getLogging.go

@ -0,0 +1,38 @@
package main
import (
"context"
"fmt"
"net/url"
"os"
"net/http"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func main() {
u, _ := url.Parse("https://bj-1259654469.cos.ap-beijing.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
v, _, err := c.Bucket.GetLogging(context.Background())
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", v.LoggingEnabled)
}

64
example/bucket/getObjectVersion.go

@ -0,0 +1,64 @@
package main
import (
"context"
"fmt"
"os"
"net/url"
"net/http"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.BucketGetObjectVersionsOptions{
Delimiter: "/",
MaxKeys: 1,
}
v, _, err := c.Bucket.GetObjectVersions(context.Background(), opt)
log_status(err)
for _, c := range v.Version {
fmt.Printf("%v, %v, %v\n", c.Key, c.Size, c.IsLatest)
}
}

39
example/bucket/getPolicy.go

@ -0,0 +1,39 @@
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
res, _, err := c.Bucket.GetPolicy(context.Background())
if err != nil {
panic(err)
}
bs, err := json.Marshal(res)
fmt.Println(string(bs))
}

92
example/bucket/origin.go

@ -0,0 +1,92 @@
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
fmt.Println("Resource is not existed")
} else if e, ok := cos.IsCOSError(err); ok {
fmt.Printf("Code: %v\n", e.Code)
fmt.Printf("Message: %v\n", e.Message)
fmt.Printf("Resource: %v\n", e.Resource)
fmt.Printf("RequestId: %v\n", e.RequestID)
// ERROR
} else {
fmt.Println(err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.BucketPutOriginOptions{
Rule: []cos.BucketOriginRule{
{
OriginType: "Proxy",
OriginCondition: &cos.BucketOriginCondition{
HTTPStatusCode: "404",
Prefix: "",
},
OriginParameter: &cos.BucketOriginParameter{
Protocol: "FOLLOW",
FollowQueryString: true,
HttpHeader: &cos.BucketOriginHttpHeader{
NewHttpHeaders: []cos.OriginHttpHeader{
{
Key: "x-cos-ContentType",
Value: "csv",
},
},
FollowHttpHeaders: []cos.OriginHttpHeader{
{
Key: "Content-Type",
},
},
},
FollowRedirection: true,
},
OriginInfo: &cos.BucketOriginInfo{
HostInfo: "examplebucket-1250000000.cos.ap-shanghai.myqcloud.com",
},
},
},
}
_, err := c.Bucket.PutOrigin(context.Background(), opt)
log_status(err)
res, _, err := c.Bucket.GetOrigin(context.Background())
log_status(err)
fmt.Printf("%+v\n", res)
fmt.Printf("%+v\n", res.Rule)
_, err = c.Bucket.DeleteOrigin(context.Background())
log_status(err)
}

63
example/bucket/putPolicy.go

@ -0,0 +1,63 @@
package main
import (
"context"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.BucketPutPolicyOptions{
Version: "2.0",
Statement: []cos.BucketStatement{
{
Principal: map[string][]string{
"qcs": []string{
"qcs::cam::uin/100000000001:uin/100000000011", //替换成您想授予权限的账户uin
},
},
Action: []string{
"name/cos:GetObject",
},
Effect: "allow",
Resource: []string{
//这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
"qcs::cos:ap-guangzhou:uid/1259654469:test-1259654469/exampleobject",
},
Condition: map[string]map[string]interface{}{
"ip_not_equal": map[string]interface{}{
"qcs:ip": []string{
"192.168.1.1",
},
},
},
},
},
}
_, err := c.Bucket.PutPolicy(context.Background(), opt)
if err != nil {
panic(err)
}
}

67
example/bucket/referer.go

@ -0,0 +1,67 @@
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
fmt.Println("Resource is not existed")
} else if e, ok := cos.IsCOSError(err); ok {
fmt.Printf("Code: %v\n", e.Code)
fmt.Printf("Message: %v\n", e.Message)
fmt.Printf("Resource: %v\n", e.Resource)
fmt.Printf("RequestId: %v\n", e.RequestID)
// ERROR
} else {
fmt.Println(err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.BucketPutRefererOptions{
Status: "Enabled",
RefererType: "White-List",
DomainList: []string{
"*.qq.com",
"*.qcloud.com",
},
EmptyReferConfiguration: "Allow",
}
_, err := c.Bucket.PutReferer(context.Background(), opt)
log_status(err)
res, _, err := c.Bucket.GetReferer(context.Background())
log_status(err)
fmt.Printf("%+v\n", res)
}

23
example/object/MutiUpload.go → example/object/MultiUpload.go

@ -12,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("http://alanbj-1251668577.cos.ap-beijing.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -37,8 +56,6 @@ func main() {
v, _, err := c.Object.MultiUpload(
context.Background(), "test/gomulput1G", "./test1G", opt,
)
if err != nil {
panic(err)
}
log_status(err)
fmt.Println(v)
}

27
example/object/abortMultipartUpload.go

@ -12,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -30,14 +49,10 @@ func main() {
name := "test_multipart.txt"
v, _, err := c.Object.InitiateMultipartUpload(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", v.UploadID)
resp, err := c.Object.AbortMultipartUpload(context.Background(), name, v.UploadID)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", resp.Status)
}

70
example/object/ci_put.go

@ -0,0 +1,70 @@
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
// Notice when put a large file and set need the request body, might happend out of memory error.
RequestBody: false,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.ObjectPutOptions{
nil,
&cos.ObjectPutHeaderOptions{
XOptionHeader: &http.Header{},
},
}
pic := &cos.PicOperations{
IsPicInfo: 1,
Rules: []cos.PicOperationsRules{
{
FileId: "format.jpg",
Rule: "imageView2/format/png",
},
},
}
opt.XOptionHeader.Add("Pic-Operations", cos.EncodePicOperations(pic))
name := "test.jpg"
local_filename := "./test.jpg"
_, err := c.Object.PutFromFile(context.Background(), name, local_filename, opt)
log_status(err)
}

35
example/object/completeMultipartUpload.go

@ -14,11 +14,28 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func initUpload(c *cos.Client, name string) *cos.InitiateMultipartUploadResult {
v, _, err := c.Object.InitiateMultipartUpload(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%#v\n", v)
return v
}
@ -27,7 +44,7 @@ func uploadPart(c *cos.Client, name string, uploadID string, blockSize, n int) s
b := make([]byte, blockSize)
if _, err := rand.Read(b); err != nil {
panic(err)
log_status(err)
}
s := fmt.Sprintf("%X", b)
f := strings.NewReader(s)
@ -35,15 +52,13 @@ func uploadPart(c *cos.Client, name string, uploadID string, blockSize, n int) s
resp, err := c.Object.UploadPart(
context.Background(), name, uploadID, n, f, nil,
)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", resp.Status)
return resp.Header.Get("Etag")
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
@ -86,9 +101,7 @@ func main() {
v, resp, err := c.Object.CompleteMultipartUpload(
context.Background(), name, uploadID, opt,
)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", resp.Status)
fmt.Printf("%#v\n", v)
fmt.Printf("%s\n", v.Location)

36
example/object/copy.go

@ -16,8 +16,27 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
@ -37,24 +56,19 @@ func main() {
f := strings.NewReader(expected)
_, err := c.Object.Put(context.Background(), source, f, nil)
if err != nil {
panic(err)
}
log_status(err)
soruceURL := fmt.Sprintf("%s/%s", u.Host, source)
dest := fmt.Sprintf("test/objectMove_%d.go", time.Now().Nanosecond())
//opt := &cos.ObjectCopyOptions{}
res, _, err := c.Object.Copy(context.Background(), dest, soruceURL, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%+v\n\n", res)
resp, err := c.Object.Get(context.Background(), dest, nil)
if err != nil {
panic(err)
}
bs, _ := ioutil.ReadAll(resp.Body)
log_status(err)
bs, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
result := string(bs)
if result != expected {

31
example/object/copyPart.go

@ -13,11 +13,28 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func initUpload(c *cos.Client, name string) *cos.InitiateMultipartUploadResult {
v, _, err := c.Object.InitiateMultipartUpload(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%#v\n", v)
return v
}
@ -46,9 +63,7 @@ func main() {
opt := &cos.ObjectCopyPartOptions{}
res, _, err := c.Object.CopyPart(
context.Background(), name, uploadID, 1, sourceUrl, opt)
if err != nil {
panic(err)
}
log_status(err)
fmt.Println("ETag:", res.ETag)
completeOpt := &cos.CompleteMultipartUploadOptions{}
@ -59,9 +74,7 @@ func main() {
v, resp, err := c.Object.CompleteMultipartUpload(
context.Background(), name, uploadID, completeOpt,
)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", resp.Status)
fmt.Printf("%#v\n", v)
fmt.Printf("%s\n", v.Location)

26
example/object/delete.go

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"net/url"
"os"
@ -11,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -29,8 +49,6 @@ func main() {
name := "test/objectPut.go"
_, err := c.Object.Delete(context.Background(), name)
if err != nil {
panic(err)
}
_, err := c.Object.Delete(context.Background(), name, nil)
log_status(err)
}

27
example/object/deleteMultiple.go

@ -18,10 +18,29 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func genBigData(blockSize int) []byte {
b := make([]byte, blockSize)
if _, err := rand.Read(b); err != nil {
panic(err)
log_status(err)
}
return b
}
@ -46,7 +65,7 @@ func uploadMulti(c *cos.Client) []string {
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
@ -89,9 +108,7 @@ func main() {
})
v, _, err := c.Object.DeleteMulti(ctx, opt)
if err != nil {
panic(err)
}
log_status(err)
for _, x := range v.DeletedObjects {
fmt.Printf("deleted %s\n", x.Key)

42
example/object/get.go

@ -13,6 +13,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -32,31 +51,26 @@ func main() {
// Case1 Download object into ReadCloser(). the body needs to be closed
name := "test/hello.txt"
resp, err := c.Object.Get(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
bs, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Printf("%s\n", string(bs))
// Case2 Download object to local file. the body needs to be closed
fd, err := os.OpenFile("hello.txt", os.O_WRONLY|os.O_CREATE, 0660)
if err != nil {
panic(err)
}
log_status(err)
defer fd.Close()
resp, err = c.Object.Get(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
io.Copy(fd, resp.Body)
resp.Body.Close()
// Case3 Download object to local file path
_, err = c.Object.GetToFile(context.Background(), name, "hello_1.txt", nil)
if err != nil {
panic(err)
}
log_status(err)
// Case4 Download object with range header, can used to concurrent download
opt := &cos.ObjectGetOptions{
@ -64,9 +78,7 @@ func main() {
Range: "bytes=0-3",
}
resp, err = c.Object.Get(context.Background(), name, opt)
if err != nil {
panic(err)
}
log_status(err)
bs, _ = ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Printf("%s\n", string(bs))

25
example/object/getACL.go

@ -12,8 +12,27 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
@ -30,9 +49,7 @@ func main() {
name := "test/hello.txt"
v, _, err := c.Object.GetACL(context.Background(), name)
if err != nil {
panic(err)
}
log_status(err)
for _, a := range v.AccessControlList {
fmt.Printf("%s, %s, %s\n", a.Grantee.Type, a.Grantee.ID, a.Permission)
}

24
example/object/getAnonymous.go

@ -11,6 +11,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func upload(c *cos.Client, name string) {
f := strings.NewReader("test")
f = strings.NewReader("test xxx")
@ -35,10 +54,7 @@ func main() {
upload(c, name)
resp, err := c.Object.Get(context.Background(), name, nil)
if err != nil {
panic(err)
return
}
log_status(err)
bs, _ := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
fmt.Printf("%s\n", string(bs))

32
example/object/getByPresignedURL.go

@ -14,6 +14,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
ak := os.Getenv("COS_SECRETID")
sk := os.Getenv("COS_SECRETKEY")
@ -38,22 +57,17 @@ func main() {
// Normal header way to get object
resp, err := c.Object.Get(ctx, name, nil)
if err != nil {
panic(err)
}
log_status(err)
bs, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
// Get presigned
presignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodGet, name, ak, sk, time.Hour, nil)
if err != nil {
panic(err)
}
log_status(err)
// Get object by presinged url
resp2, err := http.Get(presignedURL.String())
if err != nil {
panic(err)
}
log_status(err)
bs2, _ := ioutil.ReadAll(resp2.Body)
resp2.Body.Close()
fmt.Printf("result2 is : %s\n", string(bs2))

24
example/object/head.go

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"net/url"
"os"
@ -11,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -29,7 +49,5 @@ func main() {
name := "test/hello.txt"
_, err := c.Object.Head(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
}

23
example/object/initiateMultipartUpload.go

@ -13,6 +13,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -31,8 +50,6 @@ func main() {
name := "test_multipart" + time.Now().Format(time.RFC3339)
v, _, err := c.Object.InitiateMultipartUpload(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", v.UploadID)
}

31
example/object/listParts.go

@ -14,11 +14,28 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func initUpload(c *cos.Client, name string) *cos.InitiateMultipartUploadResult {
v, _, err := c.Object.InitiateMultipartUpload(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%#v\n", v)
return v
}
@ -27,7 +44,7 @@ func uploadPart(c *cos.Client, name string, uploadID string, blockSize, n int) s
b := make([]byte, blockSize)
if _, err := rand.Read(b); err != nil {
panic(err)
log_status(err)
}
s := fmt.Sprintf("%X", b)
f := strings.NewReader(s)
@ -35,9 +52,7 @@ func uploadPart(c *cos.Client, name string, uploadID string, blockSize, n int) s
resp, err := c.Object.UploadPart(
context.Background(), name, uploadID, n, f, nil,
)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%s\n", resp.Status)
return resp.Header.Get("Etag")
}
@ -73,7 +88,7 @@ func main() {
// }
v, _, err := c.Object.ListParts(ctx, name, uploadID, nil)
if err != nil {
panic(err)
log_status(err)
return
}
for _, p := range v.Parts {

26
example/object/options.go

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"net/url"
"os"
@ -11,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -29,11 +49,9 @@ func main() {
name := "test/hello.txt"
opt := &cos.ObjectOptionsOptions{
Origin: "http://www.qq.com",
Origin: "http://www.qq.com",
AccessControlRequestMethod: "PUT",
}
_, err := c.Object.Options(context.Background(), name, opt)
if err != nil {
panic(err)
}
log_status(err)
}

44
example/object/presigned_url_with_token.go

@ -0,0 +1,44 @@
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"time"
"github.com/tencentyun/cos-go-sdk-v5"
)
type URLToken struct {
SessionToken string `url:"x-cos-security-token,omitempty" header:"-"`
}
func main() {
// 替换成您的临时密钥
tak := os.Getenv("COS_SECRETID")
tsk := os.Getenv("COS_SECRETKEY")
token := &URLToken{
SessionToken: "<token>",
}
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{})
name := "exampleobject"
ctx := context.Background()
// Get presigned
presignedURL, err := c.Object.GetPresignedURL(ctx, http.MethodGet, name, tak, tsk, time.Hour, token)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
// Get object by presinged url
_, err = http.Get(presignedURL.String())
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println(presignedURL.String())
}

35
example/object/put.go

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"net/url"
"os"
"strings"
@ -12,8 +13,27 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
@ -34,9 +54,7 @@ func main() {
f := strings.NewReader("test")
_, err := c.Object.Put(context.Background(), name, f, nil)
if err != nil {
panic(err)
}
log_status(err)
// Case2 put object with the options
name = "test/put_option.go"
@ -51,14 +69,9 @@ func main() {
},
}
_, err = c.Object.Put(context.Background(), name, f, opt)
if err != nil {
panic(err)
}
log_status(err)
// Case3 put object by local file path
_, err = c.Object.PutFromFile(context.Background(), name, "./test", nil)
if err != nil {
panic(err)
}
log_status(err)
}

28
example/object/putACL.go

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"net/url"
"os"
@ -11,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -34,9 +54,7 @@ func main() {
}
name := "test/hello.txt"
_, err := c.Object.PutACL(context.Background(), name, opt)
if err != nil {
panic(err)
}
log_status(err)
// with body
opt = &cos.ObjectPutACLOptions{
@ -58,7 +76,5 @@ func main() {
}
_, err = c.Object.PutACL(context.Background(), name, opt)
if err != nil {
panic(err)
}
log_status(err)
}

24
example/object/restore.go

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
@ -10,6 +11,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -35,7 +55,5 @@ func main() {
}
name := "archivetest"
_, err := c.Object.PostRestore(context.Background(), name, opt)
if err != nil {
panic(err)
}
log_status(err)
}

81
example/object/sse_c.go

@ -0,0 +1,81 @@
package main
import (
"context"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://testcd-1259654469.cos.ap-chengdu.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
// Notice when put a large file and set need the request body, might happend out of memory error.
RequestBody: false,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.ObjectPutOptions{
ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
ContentType: "text/html",
XCosSSECustomerAglo: "AES256",
XCosSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
},
ACLHeaderOptions: &cos.ACLHeaderOptions{},
}
name := "PutFromGoWithSSE-C"
content := "Put Object From Go With SSE-C"
f := strings.NewReader(content)
_, err := c.Object.Put(context.Background(), name, f, opt)
log_status(err)
getopt := &cos.ObjectGetOptions{
XCosSSECustomerAglo: "AES256",
XCosSSECustomerKey: "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=",
XCosSSECustomerKeyMD5: "U5L61r7jcwdNvT7frmUG8g==",
}
var resp *cos.Response
resp, err = c.Object.Get(context.Background(), name, getopt)
log_status(err)
bodyBytes, _ := ioutil.ReadAll(resp.Body)
bodyContent := string(bodyBytes)
if bodyContent != content {
log_status(errors.New("Content inconsistency"))
}
}

75
example/object/sse_cos.go

@ -0,0 +1,75 @@
package main
import (
"context"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
// Notice when put a large file and set need the request body, might happend out of memory error.
RequestBody: false,
ResponseHeader: true,
ResponseBody: true,
},
},
})
opt := &cos.ObjectPutOptions{
ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
ContentType: "text/html",
XCosServerSideEncryption: "AES256",
},
ACLHeaderOptions: &cos.ACLHeaderOptions{},
}
name := "PutFromGoWithSSE-COS"
content := "Put Object From Go With SSE-COS"
f := strings.NewReader(content)
_, err := c.Object.Put(context.Background(), name, f, opt)
log_status(err)
getopt := &cos.ObjectGetOptions{}
var resp *cos.Response
resp, err = c.Object.Get(context.Background(), name, getopt)
log_status(err)
bodyBytes, _ := ioutil.ReadAll(resp.Body)
bodyContent := string(bodyBytes)
if bodyContent != content {
log_status(errors.New("Content inconsistency"))
}
}

75
example/object/tagging.go

@ -0,0 +1,75 @@
package main
import (
"context"
"fmt"
"net/url"
"os"
"net/http"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{
BucketURL: u,
}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_SECRETID"),
SecretKey: os.Getenv("COS_SECRETKEY"),
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
name := "test"
opt := &cos.ObjectPutTaggingOptions{
TagSet: []cos.ObjectTaggingTag{
{
Key: "test_k2",
Value: "test_v2",
},
{
Key: "test_k3",
Value: "test_v3",
},
},
}
_, err := c.Object.PutTagging(context.Background(), name, opt)
log_status(err)
res, _, err := c.Object.GetTagging(context.Background(), name)
log_status(err)
fmt.Printf("%v\n", res.TagSet)
_, err = c.Object.DeleteTagging(context.Background(), name)
log_status(err)
}

23
example/object/upload.go

@ -12,6 +12,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -33,8 +52,6 @@ func main() {
v, _, err := c.Object.Upload(
context.Background(), "gomulput1G", "./test1G", nil,
)
if err != nil {
panic(err)
}
log_status(err)
fmt.Println(v)
}

29
example/object/uploadFile.go

@ -13,6 +13,25 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func main() {
u, _ := url.Parse("https://test-1253846586.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
@ -32,11 +51,13 @@ func main() {
name := "test/uploadFile.go"
f, err := os.Open(os.Args[0])
if err != nil {
panic(err)
log_status(err)
return
}
s, err := f.Stat()
if err != nil {
panic(err)
log_status(err)
return
}
fmt.Println(s.Size())
opt := &cos.ObjectPutOptions{
@ -47,7 +68,5 @@ func main() {
//opt.ContentLength = int(s.Size())
_, err = c.Object.Put(context.Background(), name, f, opt)
if err != nil {
panic(err)
}
log_status(err)
}

27
example/object/uploadPart.go

@ -14,11 +14,28 @@ import (
"github.com/tencentyun/cos-go-sdk-v5/debug"
)
func log_status(err error) {
if err == nil {
return
}
if cos.IsNotFoundError(err) {
// WARN
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)
// ERROR
} else {
fmt.Printf("ERROR: %v\n", err)
// ERROR
}
}
func initUpload(c *cos.Client, name string) *cos.InitiateMultipartUploadResult {
v, _, err := c.Object.InitiateMultipartUpload(context.Background(), name, nil)
if err != nil {
panic(err)
}
log_status(err)
fmt.Printf("%#v\n", v)
return v
}
@ -47,7 +64,5 @@ func main() {
_, err := c.Object.UploadPart(
context.Background(), name, uploadID, 1, f, nil,
)
if err != nil {
panic(err)
}
log_status(err)
}

96
example/sts/sts_v3.go

@ -0,0 +1,96 @@
package main
import (
"context"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/tencentyun/cos-go-sdk-v5/debug"
"github.com/tencentyun/qcloud-cos-sts-sdk/go"
"net/http"
"net/url"
"os"
"strings"
"time"
)
func main() {
appid := "1259654469"
bucket := "test-1259654469"
c := sts.NewClient(
os.Getenv("COS_SECRETID"),
os.Getenv("COS_SECRETKEY"),
nil,
)
opt := &sts.CredentialOptions{
DurationSeconds: int64(time.Hour.Seconds()),
Region: "ap-guangzhou",
Policy: &sts.CredentialPolicy{
Statement: []sts.CredentialPolicyStatement{
{
Action: []string{
"name/cos:PostObject",
"name/cos:PutObject",
"name/cos:GetObject",
},
Effect: "allow",
Resource: []string{
//这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
"qcs::cos:ap-guangzhou:uid/" + appid + ":" + bucket + "/exampleobject",
},
},
},
},
}
res, err := c.GetCredential(opt)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", res.Credentials)
//获取临时ak、sk、token
tAk := res.Credentials.TmpSecretID
tSk := res.Credentials.TmpSecretKey
token := res.Credentials.SessionToken
u, _ := url.Parse("https://" + bucket + ".cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
// 使用临时密钥
SecretID: tAk,
SecretKey: tSk,
SessionToken: token,
Transport: &debug.DebugRequestTransport{
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
},
},
})
name := "exampleobject"
f := strings.NewReader("test")
_, err = client.Object.Put(context.Background(), name, f, nil)
if err != nil {
panic(err)
}
name = "exampleobject"
f = strings.NewReader("test xxx")
optc := &cos.ObjectPutOptions{
ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
ContentType: "text/html",
},
ACLHeaderOptions: &cos.ACLHeaderOptions{
//XCosACL: "public-read",
XCosACL: "private",
},
}
_, err = client.Object.Put(context.Background(), name, f, optc)
if err != nil {
panic(err)
}
}

1
go.mod

@ -5,6 +5,7 @@ go 1.12
require (
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409
github.com/google/go-querystring v1.0.0
github.com/google/uuid v1.1.1
github.com/mozillazg/go-httpheader v0.2.1
github.com/stretchr/testify v1.3.0
)

2
go.sum

@ -4,6 +4,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

88
object.go

@ -272,19 +272,33 @@ func (s *ObjectService) Copy(ctx context.Context, name, sourceURL string, opt *O
return &res, resp, err
}
type ObjectDeleteOptions struct {
// SSE-C
XCosSSECustomerAglo string `header:"x-cos-server-side-encryption-customer-algorithm,omitempty" url:"-" xml:"-"`
XCosSSECustomerKey string `header:"x-cos-server-side-encryption-customer-key,omitempty" url:"-" xml:"-"`
XCosSSECustomerKeyMD5 string `header:"x-cos-server-side-encryption-customer-key-MD5,omitempty" url:"-" xml:"-"`
//兼容其他自定义头部
XOptionHeader *http.Header `header:"-,omitempty" url:"-" xml:"-"`
}
// Delete Object请求可以将一个文件(Object)删除。
//
// https://www.qcloud.com/document/product/436/7743
func (s *ObjectService) Delete(ctx context.Context, name string) (*Response, error) {
func (s *ObjectService) Delete(ctx context.Context, name string, opt ...*ObjectDeleteOptions) (*Response, error) {
var optHeader *ObjectDeleteOptions
// When use "" string might call the delete bucket interface
if len(name) == 0 {
return nil, errors.New("empty object name")
}
if len(opt) > 0 {
optHeader = opt[0]
}
sendOpt := sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: "/" + encodeURIComponent(name),
method: http.MethodDelete,
baseURL: s.client.BaseURL.BucketURL,
uri: "/" + encodeURIComponent(name),
method: http.MethodDelete,
optHeader: optHeader,
}
resp, err := s.client.send(ctx, &sendOpt)
return resp, err
@ -662,3 +676,69 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string
return v, resp, err
}
type ObjectPutTaggingOptions struct {
XMLName xml.Name `xml:"Tagging"`
TagSet []ObjectTaggingTag `xml:"TagSet>Tag,omitempty"`
}
type ObjectTaggingTag BucketTaggingTag
type ObjectGetTaggingResult ObjectPutTaggingOptions
func (s *ObjectService) PutTagging(ctx context.Context, name string, opt *ObjectPutTaggingOptions, id ...string) (*Response, error) {
var u string
if len(id) == 1 {
u = fmt.Sprintf("/%s?tagging&versionId=%s", encodeURIComponent(name), id[0])
} else if len(id) == 0 {
u = fmt.Sprintf("/%s?tagging", encodeURIComponent(name))
} else {
return nil, errors.New("wrong params")
}
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: u,
method: http.MethodPut,
body: opt,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}
func (s *ObjectService) GetTagging(ctx context.Context, name string, id ...string) (*ObjectGetTaggingResult, *Response, error) {
var u string
if len(id) == 1 {
u = fmt.Sprintf("/%s?tagging&versionId=%s", encodeURIComponent(name), id[0])
} else if len(id) == 0 {
u = fmt.Sprintf("/%s?tagging", encodeURIComponent(name))
} else {
return nil, nil, errors.New("wrong params")
}
var res ObjectGetTaggingResult
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: u,
method: http.MethodGet,
result: &res,
}
resp, err := s.client.send(ctx, sendOpt)
return &res, resp, err
}
func (s *ObjectService) DeleteTagging(ctx context.Context, name string, id ...string) (*Response, error) {
var u string
if len(id) == 1 {
u = fmt.Sprintf("/%s?tagging&versionId=%s", encodeURIComponent(name), id[0])
} else if len(id) == 0 {
u = fmt.Sprintf("/%s?tagging", encodeURIComponent(name))
} else {
return nil, errors.New("wrong params")
}
sendOpt := &sendOptions{
baseURL: s.client.BaseURL.BucketURL,
uri: u,
method: http.MethodDelete,
}
resp, err := s.client.send(ctx, sendOpt)
return resp, err
}
Loading…
Cancel
Save