add ci guetzli && test
This commit is contained in:
7
batch.go
7
batch.go
@@ -113,13 +113,6 @@ type BatchCreateJobResult struct {
|
|||||||
JobId string `xml:"JobId,omitempty"`
|
JobId string `xml:"JobId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func processETag(opt *BatchCreateJobOptions) *BatchCreateJobOptions {
|
|
||||||
if opt != nil && opt.Manifest != nil && opt.Manifest.Location != nil {
|
|
||||||
opt.Manifest.Location.ETag = "<ETag>" + opt.Manifest.Location.ETag + "</ETag>"
|
|
||||||
}
|
|
||||||
return opt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *BatchService) CreateJob(ctx context.Context, opt *BatchCreateJobOptions, headers *BatchRequestHeaders) (*BatchCreateJobResult, *Response, error) {
|
func (s *BatchService) CreateJob(ctx context.Context, opt *BatchCreateJobOptions, headers *BatchRequestHeaders) (*BatchCreateJobResult, *Response, error) {
|
||||||
var res BatchCreateJobResult
|
var res BatchCreateJobResult
|
||||||
sendOpt := sendOptions{
|
sendOpt := sendOptions{
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ type BucketPutOriginOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BucketOriginRule struct {
|
type BucketOriginRule struct {
|
||||||
OriginType string `xml:"OriginType"`
|
RulePriority int `xml:"RulePriority,omitempty"`
|
||||||
OriginCondition *BucketOriginCondition `xml:"OriginCondition"`
|
OriginType string `xml:"OriginType,omitempty"`
|
||||||
OriginParameter *BucketOriginParameter `xml:"OriginParameter"`
|
OriginCondition *BucketOriginCondition `xml:"OriginCondition,omitempty"`
|
||||||
OriginInfo *BucketOriginInfo `xml:"OriginInfo"`
|
OriginParameter *BucketOriginParameter `xml:"OriginParameter,omitempty"`
|
||||||
|
OriginInfo *BucketOriginInfo `xml:"OriginInfo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BucketOriginCondition struct {
|
type BucketOriginCondition struct {
|
||||||
|
|||||||
180
bucket_origin_test.go
Normal file
180
bucket_origin_test.go
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
package cos
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBucketService_GetOrigin(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
vs := values{
|
||||||
|
"origin": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
fmt.Fprint(w, `<OriginConfiguration>
|
||||||
|
<OriginRule>
|
||||||
|
<RulePriority>1</RulePriority>
|
||||||
|
<OriginType>Mirror</OriginType>
|
||||||
|
<OriginCondition>
|
||||||
|
<HTTPStatusCode>404</HTTPStatusCode>
|
||||||
|
<Prefix></Prefix>
|
||||||
|
</OriginCondition>
|
||||||
|
<OriginParameter>
|
||||||
|
<Protocol>HTTP</Protocol>
|
||||||
|
<FollowQueryString>true</FollowQueryString>
|
||||||
|
<HttpHeader>
|
||||||
|
<NewHttpHeaders>
|
||||||
|
<Header>
|
||||||
|
<Key>x-cos</Key>
|
||||||
|
<Value>exampleHeader</Value>
|
||||||
|
</Header>
|
||||||
|
</NewHttpHeaders>
|
||||||
|
<FollowHttpHeaders>
|
||||||
|
<Header>
|
||||||
|
<Key>exampleHeaderKey</Key>
|
||||||
|
</Header>
|
||||||
|
</FollowHttpHeaders>
|
||||||
|
</HttpHeader>
|
||||||
|
<FollowRedirection>true</FollowRedirection>
|
||||||
|
<HttpRedirectCode>302</HttpRedirectCode>
|
||||||
|
</OriginParameter>
|
||||||
|
<OriginInfo>
|
||||||
|
<HostInfo>
|
||||||
|
<HostName>examplebucket-1250000000.cos.ap-shanghai.myqcloud.com</HostName>
|
||||||
|
</HostInfo>
|
||||||
|
</OriginInfo>
|
||||||
|
</OriginRule>
|
||||||
|
</OriginConfiguration>
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
res, _, err := client.Bucket.GetOrigin(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Bucket.GetOrigin returned error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &BucketGetOriginResult{
|
||||||
|
XMLName: xml.Name{Local: "OriginConfiguration"},
|
||||||
|
Rule: []BucketOriginRule{
|
||||||
|
{
|
||||||
|
OriginType: "Mirror",
|
||||||
|
RulePriority: 1,
|
||||||
|
OriginCondition: &BucketOriginCondition{
|
||||||
|
HTTPStatusCode: "404",
|
||||||
|
},
|
||||||
|
OriginParameter: &BucketOriginParameter{
|
||||||
|
Protocol: "HTTP",
|
||||||
|
FollowQueryString: true,
|
||||||
|
HttpHeader: &BucketOriginHttpHeader{
|
||||||
|
FollowHttpHeaders: []OriginHttpHeader{
|
||||||
|
{
|
||||||
|
Key: "exampleHeaderKey",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewHttpHeaders: []OriginHttpHeader{
|
||||||
|
{
|
||||||
|
Key: "x-cos",
|
||||||
|
Value: "exampleHeader",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FollowRedirection: true,
|
||||||
|
HttpRedirectCode: "302",
|
||||||
|
},
|
||||||
|
OriginInfo: &BucketOriginInfo{
|
||||||
|
HostInfo: "examplebucket-1250000000.cos.ap-shanghai.myqcloud.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("Bucket.GetOrigin returned %+v, want %+v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_PutOrigin(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
opt := &BucketPutOriginOptions{
|
||||||
|
XMLName: xml.Name{Local: "OriginConfiguration"},
|
||||||
|
Rule: []BucketOriginRule{
|
||||||
|
{
|
||||||
|
OriginType: "Mirror",
|
||||||
|
RulePriority: 1,
|
||||||
|
OriginCondition: &BucketOriginCondition{
|
||||||
|
HTTPStatusCode: "404",
|
||||||
|
},
|
||||||
|
OriginParameter: &BucketOriginParameter{
|
||||||
|
Protocol: "HTTP",
|
||||||
|
FollowQueryString: true,
|
||||||
|
HttpHeader: &BucketOriginHttpHeader{
|
||||||
|
FollowHttpHeaders: []OriginHttpHeader{
|
||||||
|
{
|
||||||
|
Key: "exampleHeaderKey",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewHttpHeaders: []OriginHttpHeader{
|
||||||
|
{
|
||||||
|
Key: "x-cos",
|
||||||
|
Value: "exampleHeader",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FollowRedirection: true,
|
||||||
|
HttpRedirectCode: "302",
|
||||||
|
},
|
||||||
|
OriginInfo: &BucketOriginInfo{
|
||||||
|
HostInfo: "examplebucket-1250000000.cos.ap-shanghai.myqcloud.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
vs := values{
|
||||||
|
"origin": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
|
||||||
|
body := new(BucketPutOriginOptions)
|
||||||
|
xml.NewDecoder(r.Body).Decode(body)
|
||||||
|
want := opt
|
||||||
|
want.XMLName = xml.Name{Local: "OriginConfiguration"}
|
||||||
|
if !reflect.DeepEqual(body, want) {
|
||||||
|
t.Errorf("Bucket.PutOrigin request\n body: %+v\n, want %+v\n", body, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Bucket.PutOrigin(context.Background(), opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Bucket.PutOrigin returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_DeleteOrigin(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, http.MethodDelete)
|
||||||
|
vs := values{
|
||||||
|
"origin": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
_, err := client.Bucket.DeleteOrigin(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Bucket.DeleteOrigin returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
121
bucket_policy_test.go
Normal file
121
bucket_policy_test.go
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package cos
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBucketService_GetPolicy(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
vs := values{
|
||||||
|
"policy": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Principal": {
|
||||||
|
"qcs": [
|
||||||
|
"qcs::cam::uin/100000000001:uin/100000000011"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Effect": "allow",
|
||||||
|
"Action": [
|
||||||
|
"name/cos:GetBucket"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"qcs::cos:ap-guangzhou:uid/1250000000:examplebucket-1250000000/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "2.0"
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
res, _, err := client.Bucket.GetPolicy(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Bucket.GetPolicy returned error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &BucketGetPolicyResult{
|
||||||
|
Statement: []BucketStatement{
|
||||||
|
{
|
||||||
|
Principal: map[string][]string{
|
||||||
|
"qcs": []string{"qcs::cam::uin/100000000001:uin/100000000011"},
|
||||||
|
},
|
||||||
|
Effect: "allow",
|
||||||
|
Action: []string{"name/cos:GetBucket"},
|
||||||
|
Resource: []string{"qcs::cos:ap-guangzhou:uid/1250000000:examplebucket-1250000000/*"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Version: "2.0",
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("Bucket.GetPolicy returned %+v, want %+v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_PutPolicy(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
opt := &BucketPutPolicyOptions{
|
||||||
|
Statement: []BucketStatement{
|
||||||
|
{
|
||||||
|
Principal: map[string][]string{
|
||||||
|
"qcs": []string{"qcs::cam::uin/100000000001:uin/100000000011"},
|
||||||
|
},
|
||||||
|
Effect: "allow",
|
||||||
|
Action: []string{"name/cos:GetBucket"},
|
||||||
|
Resource: []string{"qcs::cos:ap-guangzhou:uid/1250000000:examplebucket-1250000000/*"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Version: "2.0",
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
vs := values{
|
||||||
|
"policy": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
|
||||||
|
body := new(BucketPutPolicyOptions)
|
||||||
|
json.NewDecoder(r.Body).Decode(body)
|
||||||
|
want := opt
|
||||||
|
if !reflect.DeepEqual(body, want) {
|
||||||
|
t.Errorf("Bucket.PutPolicy request\n body: %+v\n, want %+v\n", body, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Bucket.PutPolicy(context.Background(), opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Bucket.PutPolicy returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_DeletePolicy(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, http.MethodDelete)
|
||||||
|
vs := values{
|
||||||
|
"policy": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
_, err := client.Bucket.DeletePolicy(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Bucket.DeletePolicy returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
40
ci.go
40
ci.go
@@ -446,3 +446,43 @@ func (s *CIService) GenerateQRcodeToFile(ctx context.Context, filePath string, o
|
|||||||
|
|
||||||
return res, resp, err
|
return res, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 开通 Guetzli 压缩 https://cloud.tencent.com/document/product/460/30112
|
||||||
|
func (s *CIService) PutGuetzli(ctx context.Context) (*Response, error) {
|
||||||
|
sendOpt := &sendOptions{
|
||||||
|
baseURL: s.client.BaseURL.CIURL,
|
||||||
|
uri: "/?guetzli",
|
||||||
|
method: http.MethodPut,
|
||||||
|
}
|
||||||
|
resp, err := s.client.send(ctx, sendOpt)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetGuetzliResult struct {
|
||||||
|
XMLName xml.Name `xml:"GuetzliStatus"`
|
||||||
|
GuetzliStatus string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询 Guetzli 状态 https://cloud.tencent.com/document/product/460/30111
|
||||||
|
func (s *CIService) GetGuetzli(ctx context.Context) (*GetGuetzliResult, *Response, error) {
|
||||||
|
var res GetGuetzliResult
|
||||||
|
sendOpt := &sendOptions{
|
||||||
|
baseURL: s.client.BaseURL.CIURL,
|
||||||
|
uri: "/?guetzli",
|
||||||
|
method: http.MethodGet,
|
||||||
|
result: &res,
|
||||||
|
}
|
||||||
|
resp, err := s.client.send(ctx, sendOpt)
|
||||||
|
return &res, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭 Guetzli 压缩 https://cloud.tencent.com/document/product/460/30113
|
||||||
|
func (s *CIService) DeleteGuetzli(ctx context.Context) (*Response, error) {
|
||||||
|
sendOpt := &sendOptions{
|
||||||
|
baseURL: s.client.BaseURL.CIURL,
|
||||||
|
uri: "/?guetzli",
|
||||||
|
method: http.MethodDelete,
|
||||||
|
}
|
||||||
|
resp, err := s.client.send(ctx, sendOpt)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|||||||
497
ci_test.go
Normal file
497
ci_test.go
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
package cos
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc64"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCIService_EncodePicOperations(t *testing.T) {
|
||||||
|
opt := &PicOperations{
|
||||||
|
IsPicInfo: 1,
|
||||||
|
Rules: []PicOperationsRules{
|
||||||
|
{
|
||||||
|
FileId: "example.jpg",
|
||||||
|
Rule: "imageView2/format/png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
res := EncodePicOperations(opt)
|
||||||
|
jsonStr := `{"is_pic_info":1,"rules":[{"fileid":"example.jpg","rule":"imageView2/format/png"}]}`
|
||||||
|
if jsonStr != res {
|
||||||
|
t.Fatalf("EncodePicOperations Failed, returned:%v, want:%v", res, jsonStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCIService_ImageProcess(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
name := "test.jpg"
|
||||||
|
|
||||||
|
opt := &ImageProcessOptions{
|
||||||
|
IsPicInfo: 1,
|
||||||
|
Rules: []PicOperationsRules{
|
||||||
|
{
|
||||||
|
FileId: "format.jpg",
|
||||||
|
Rule: "imageView2/format/png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "POST")
|
||||||
|
vs := values{
|
||||||
|
"image_process": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
header := r.Header.Get("Pic-Operations")
|
||||||
|
body := new(ImageProcessOptions)
|
||||||
|
err := json.Unmarshal([]byte(header), body)
|
||||||
|
want := opt
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("CI.ImageProcess Failed: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, body) {
|
||||||
|
t.Errorf("CI.ImageProcess Failed, wanted:%v, body:%v", want, body)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, `<UploadResult>
|
||||||
|
<OriginalInfo>
|
||||||
|
<Key>test.jpg</Key>
|
||||||
|
<Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg</Location>
|
||||||
|
<ETag>"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85"</ETag>
|
||||||
|
<ImageInfo>
|
||||||
|
<Format>PNG</Format>
|
||||||
|
<Width>103</Width>
|
||||||
|
<Height>99</Height>
|
||||||
|
<Quality>100</Quality>
|
||||||
|
<Ave>0xa08162</Ave>
|
||||||
|
<Orientation>0</Orientation>
|
||||||
|
</ImageInfo>
|
||||||
|
</OriginalInfo>
|
||||||
|
<ProcessResults>
|
||||||
|
<Object>
|
||||||
|
<Key>format.jpg</Key>
|
||||||
|
<Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg</Location>
|
||||||
|
<Format>PNG</Format>
|
||||||
|
<Width>103</Width>
|
||||||
|
<Height>99</Height>
|
||||||
|
<Size>21351</Size>
|
||||||
|
<Quality>100</Quality>
|
||||||
|
<ETag>"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85"</ETag>
|
||||||
|
</Object>
|
||||||
|
</ProcessResults>
|
||||||
|
</UploadResult>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
want := &ImageProcessResult{
|
||||||
|
XMLName: xml.Name{Local: "UploadResult"},
|
||||||
|
OriginalInfo: &PicOriginalInfo{
|
||||||
|
Key: "test.jpg",
|
||||||
|
Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg",
|
||||||
|
ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
|
||||||
|
ImageInfo: &PicImageInfo{
|
||||||
|
Format: "PNG",
|
||||||
|
Width: 103,
|
||||||
|
Height: 99,
|
||||||
|
Quality: 100,
|
||||||
|
Ave: "0xa08162",
|
||||||
|
Orientation: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ProcessResults: &PicProcessObject{
|
||||||
|
Key: "format.jpg",
|
||||||
|
Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg",
|
||||||
|
Format: "PNG",
|
||||||
|
Width: 103,
|
||||||
|
Height: 99,
|
||||||
|
Size: 21351,
|
||||||
|
Quality: 100,
|
||||||
|
ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, _, err := client.CI.ImageProcess(context.Background(), name, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.ImageProcess returned error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("CI.ImageProcess failed, return:%v, want:%v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCIService_ImageRecognition(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
name := "test.jpg"
|
||||||
|
|
||||||
|
detectType := "porn,terrorist,politics"
|
||||||
|
mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
vs := values{
|
||||||
|
"ci-process": "sensitive-content-recognition",
|
||||||
|
"detect-type": "porn,terrorist,politics",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
fmt.Fprint(w, `<RecognitionResult>
|
||||||
|
<PornInfo>
|
||||||
|
<Code>0</Code>
|
||||||
|
<Msg>OK</Msg>
|
||||||
|
<HitFlag>0</HitFlag>
|
||||||
|
<Score>0</Score>
|
||||||
|
<Label/>
|
||||||
|
</PornInfo>
|
||||||
|
<TerroristInfo>
|
||||||
|
<Code>0</Code>
|
||||||
|
<Msg>OK</Msg>
|
||||||
|
<HitFlag>0</HitFlag>
|
||||||
|
<Score>0</Score>
|
||||||
|
<Label/>
|
||||||
|
</TerroristInfo>
|
||||||
|
<PoliticsInfo>
|
||||||
|
<Code>0</Code>
|
||||||
|
<Msg>OK</Msg>
|
||||||
|
<HitFlag>0</HitFlag>
|
||||||
|
<Score>0</Score>
|
||||||
|
<Label/>
|
||||||
|
</PoliticsInfo>
|
||||||
|
</RecognitionResult>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
want := &ImageRecognitionResult{
|
||||||
|
XMLName: xml.Name{Local: "RecognitionResult"},
|
||||||
|
PornInfo: &RecognitionInfo{
|
||||||
|
Code: 0,
|
||||||
|
Msg: "OK",
|
||||||
|
HitFlag: 0,
|
||||||
|
Score: 0,
|
||||||
|
},
|
||||||
|
TerroristInfo: &RecognitionInfo{
|
||||||
|
Code: 0,
|
||||||
|
Msg: "OK",
|
||||||
|
HitFlag: 0,
|
||||||
|
Score: 0,
|
||||||
|
},
|
||||||
|
PoliticsInfo: &RecognitionInfo{
|
||||||
|
Code: 0,
|
||||||
|
Msg: "OK",
|
||||||
|
HitFlag: 0,
|
||||||
|
Score: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, _, err := client.CI.ImageRecognition(context.Background(), name, detectType)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.ImageRecognitionreturned error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("CI.ImageRecognition failed, return:%v, want:%v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCIService_Put(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
name := "test.jpg"
|
||||||
|
data := make([]byte, 1024*1024*3)
|
||||||
|
rand.Read(data)
|
||||||
|
|
||||||
|
pic := &ImageProcessOptions{
|
||||||
|
IsPicInfo: 1,
|
||||||
|
Rules: []PicOperationsRules{
|
||||||
|
{
|
||||||
|
FileId: "format.jpg",
|
||||||
|
Rule: "imageView2/format/png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
header := r.Header.Get("Pic-Operations")
|
||||||
|
body := new(ImageProcessOptions)
|
||||||
|
err := json.Unmarshal([]byte(header), body)
|
||||||
|
want := pic
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("CI.Put Failed: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, body) {
|
||||||
|
t.Errorf("CI.Put Failed, wanted:%v, body:%v", want, body)
|
||||||
|
}
|
||||||
|
tb := crc64.MakeTable(crc64.ECMA)
|
||||||
|
ht := crc64.New(tb)
|
||||||
|
tr := TeeReader(r.Body, ht, 0, nil)
|
||||||
|
bs, err := ioutil.ReadAll(tr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("CI.Put ReadAll Failed: %v", err)
|
||||||
|
}
|
||||||
|
if bytes.Compare(bs, data) != 0 {
|
||||||
|
t.Errorf("CI.Put Failed, data isn't consistent")
|
||||||
|
}
|
||||||
|
crc := tr.Crc64()
|
||||||
|
w.Header().Add("x-cos-hash-crc64ecma", strconv.FormatUint(crc, 10))
|
||||||
|
fmt.Fprint(w, `<UploadResult>
|
||||||
|
<OriginalInfo>
|
||||||
|
<Key>test.jpg</Key>
|
||||||
|
<Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg</Location>
|
||||||
|
<ETag>"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85"</ETag>
|
||||||
|
<ImageInfo>
|
||||||
|
<Format>PNG</Format>
|
||||||
|
<Width>103</Width>
|
||||||
|
<Height>99</Height>
|
||||||
|
<Quality>100</Quality>
|
||||||
|
<Ave>0xa08162</Ave>
|
||||||
|
<Orientation>0</Orientation>
|
||||||
|
</ImageInfo>
|
||||||
|
</OriginalInfo>
|
||||||
|
<ProcessResults>
|
||||||
|
<Object>
|
||||||
|
<Key>format.jpg</Key>
|
||||||
|
<Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg</Location>
|
||||||
|
<Format>PNG</Format>
|
||||||
|
<Width>103</Width>
|
||||||
|
<Height>99</Height>
|
||||||
|
<Size>21351</Size>
|
||||||
|
<Quality>100</Quality>
|
||||||
|
<ETag>"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85"</ETag>
|
||||||
|
</Object>
|
||||||
|
</ProcessResults>
|
||||||
|
</UploadResult>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
want := &ImageProcessResult{
|
||||||
|
XMLName: xml.Name{Local: "UploadResult"},
|
||||||
|
OriginalInfo: &PicOriginalInfo{
|
||||||
|
Key: "test.jpg",
|
||||||
|
Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg",
|
||||||
|
ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
|
||||||
|
ImageInfo: &PicImageInfo{
|
||||||
|
Format: "PNG",
|
||||||
|
Width: 103,
|
||||||
|
Height: 99,
|
||||||
|
Quality: 100,
|
||||||
|
Ave: "0xa08162",
|
||||||
|
Orientation: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ProcessResults: &PicProcessObject{
|
||||||
|
Key: "format.jpg",
|
||||||
|
Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg",
|
||||||
|
Format: "PNG",
|
||||||
|
Width: 103,
|
||||||
|
Height: 99,
|
||||||
|
Size: 21351,
|
||||||
|
Quality: 100,
|
||||||
|
ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f := bytes.NewReader(data)
|
||||||
|
opt := &ObjectPutOptions{
|
||||||
|
nil,
|
||||||
|
&ObjectPutHeaderOptions{
|
||||||
|
XOptionHeader: &http.Header{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
opt.XOptionHeader.Add("Pic-Operations", EncodePicOperations(pic))
|
||||||
|
res, _, err := client.CI.Put(context.Background(), name, f, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.Put returned error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("CI.ImageProcess failed, return:%v, want:%v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCIService_PutFromFile(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
name := "test.jpg"
|
||||||
|
filePath := "test.file" + time.Now().Format(time.RFC3339)
|
||||||
|
newfile, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("creat tmp file failed")
|
||||||
|
}
|
||||||
|
defer os.Remove(filePath)
|
||||||
|
data := make([]byte, 1024*1024*3)
|
||||||
|
rand.Read(data)
|
||||||
|
newfile.Write(data)
|
||||||
|
newfile.Close()
|
||||||
|
|
||||||
|
pic := &ImageProcessOptions{
|
||||||
|
IsPicInfo: 1,
|
||||||
|
Rules: []PicOperationsRules{
|
||||||
|
{
|
||||||
|
FileId: "format.jpg",
|
||||||
|
Rule: "imageView2/format/png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
header := r.Header.Get("Pic-Operations")
|
||||||
|
body := new(ImageProcessOptions)
|
||||||
|
err := json.Unmarshal([]byte(header), body)
|
||||||
|
want := pic
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("CI.Put Failed: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(want, body) {
|
||||||
|
t.Errorf("CI.Put Failed, wanted:%v, body:%v", want, body)
|
||||||
|
}
|
||||||
|
tb := crc64.MakeTable(crc64.ECMA)
|
||||||
|
ht := crc64.New(tb)
|
||||||
|
tr := TeeReader(r.Body, ht, 0, nil)
|
||||||
|
bs, err := ioutil.ReadAll(tr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("CI.Put ReadAll Failed: %v", err)
|
||||||
|
}
|
||||||
|
if bytes.Compare(bs, data) != 0 {
|
||||||
|
t.Errorf("CI.Put Failed, data isn't consistent")
|
||||||
|
}
|
||||||
|
crc := tr.Crc64()
|
||||||
|
w.Header().Add("x-cos-hash-crc64ecma", strconv.FormatUint(crc, 10))
|
||||||
|
fmt.Fprint(w, `<UploadResult>
|
||||||
|
<OriginalInfo>
|
||||||
|
<Key>test.jpg</Key>
|
||||||
|
<Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg</Location>
|
||||||
|
<ETag>"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85"</ETag>
|
||||||
|
<ImageInfo>
|
||||||
|
<Format>PNG</Format>
|
||||||
|
<Width>103</Width>
|
||||||
|
<Height>99</Height>
|
||||||
|
<Quality>100</Quality>
|
||||||
|
<Ave>0xa08162</Ave>
|
||||||
|
<Orientation>0</Orientation>
|
||||||
|
</ImageInfo>
|
||||||
|
</OriginalInfo>
|
||||||
|
<ProcessResults>
|
||||||
|
<Object>
|
||||||
|
<Key>format.jpg</Key>
|
||||||
|
<Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg</Location>
|
||||||
|
<Format>PNG</Format>
|
||||||
|
<Width>103</Width>
|
||||||
|
<Height>99</Height>
|
||||||
|
<Size>21351</Size>
|
||||||
|
<Quality>100</Quality>
|
||||||
|
<ETag>"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85"</ETag>
|
||||||
|
</Object>
|
||||||
|
</ProcessResults>
|
||||||
|
</UploadResult>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
want := &ImageProcessResult{
|
||||||
|
XMLName: xml.Name{Local: "UploadResult"},
|
||||||
|
OriginalInfo: &PicOriginalInfo{
|
||||||
|
Key: "test.jpg",
|
||||||
|
Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg",
|
||||||
|
ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
|
||||||
|
ImageInfo: &PicImageInfo{
|
||||||
|
Format: "PNG",
|
||||||
|
Width: 103,
|
||||||
|
Height: 99,
|
||||||
|
Quality: 100,
|
||||||
|
Ave: "0xa08162",
|
||||||
|
Orientation: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ProcessResults: &PicProcessObject{
|
||||||
|
Key: "format.jpg",
|
||||||
|
Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg",
|
||||||
|
Format: "PNG",
|
||||||
|
Width: 103,
|
||||||
|
Height: 99,
|
||||||
|
Size: 21351,
|
||||||
|
Quality: 100,
|
||||||
|
ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
opt := &ObjectPutOptions{
|
||||||
|
nil,
|
||||||
|
&ObjectPutHeaderOptions{
|
||||||
|
XOptionHeader: &http.Header{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
opt.XOptionHeader.Add("Pic-Operations", EncodePicOperations(pic))
|
||||||
|
res, _, err := client.CI.PutFromFile(context.Background(), name, filePath, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.Put returned error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("CI.ImageProcess failed, return:%v, want:%v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_GetGuetzli(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
vs := values{
|
||||||
|
"guetzli": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
fmt.Fprint(w, `<GuetzliStatus>on</GuetzliStatus>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
res, _, err := client.CI.GetGuetzli(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.GetGuetzli returned error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &GetGuetzliResult{
|
||||||
|
XMLName: xml.Name{Local: "GuetzliStatus"},
|
||||||
|
GuetzliStatus: "on",
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("CI.GetGuetzli %+v, want %+v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_PutGuetzli(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
vs := values{
|
||||||
|
"guetzli": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.CI.PutGuetzli(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.PutGuetzli returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBucketService_DeleteGuetzli(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "DELETE")
|
||||||
|
vs := values{
|
||||||
|
"guetzli": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.CI.DeleteGuetzli(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CI.PutGuetzli returned error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,3 +87,36 @@ func Test_checkResponse_with_error(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_IsNotFoundError(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/test_404", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?>
|
||||||
|
<Error>
|
||||||
|
<Code>NoSuchKey</Code>
|
||||||
|
<Message>The specified key does not exist.</Message>
|
||||||
|
<Resource>examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/test_404</Resource>
|
||||||
|
<RequestId>NjA3OGY4NGFfNjJkMmMwYl8***</RequestId>
|
||||||
|
<TraceId>OGVmYzZiMmQzYjA2OWNh***</TraceId>
|
||||||
|
</Error>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", client.BaseURL.ServiceURL.String()+"/test_404", nil)
|
||||||
|
resp, _ := client.client.Do(req)
|
||||||
|
err := checkResponse(resp)
|
||||||
|
|
||||||
|
e, ok := IsCOSError(err)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("IsCOSError Return Failed")
|
||||||
|
}
|
||||||
|
ok = IsNotFoundError(e)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("IsNotFoundError Return Failed")
|
||||||
|
}
|
||||||
|
if e.Code != "NoSuchKey" {
|
||||||
|
t.Errorf("Expected NoSuchKey error, got %+v", e.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
58
example/CI/compression/ci_compression.go
Normal file
58
example/CI/compression/ci_compression.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
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: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
name := "test.png"
|
||||||
|
filepath := "test1.jpg"
|
||||||
|
_, err := c.CI.GetToFile(context.Background(), name, filepath, "imageMogr2/format/tpg", nil)
|
||||||
|
log_status(err)
|
||||||
|
|
||||||
|
filepath = "test2.jpg"
|
||||||
|
_, err = c.CI.GetToFile(context.Background(), name, filepath, "imageMogr2/format/heif", nil)
|
||||||
|
log_status(err)
|
||||||
|
}
|
||||||
68
example/CI/compression/guetzli.go
Normal file
68
example/CI/compression/guetzli.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"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")
|
||||||
|
cu, _ := url.Parse("http://test-1259654469.pic.ap-guangzhou.myqcloud.com")
|
||||||
|
b := &cos.BaseURL{BucketURL: u, CIURL: cu}
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := c.CI.PutGuetzli(context.Background())
|
||||||
|
log_status(err)
|
||||||
|
res, _, err := c.CI.GetGuetzli(context.Background())
|
||||||
|
log_status(err)
|
||||||
|
if res != nil && res.GuetzliStatus != "on" {
|
||||||
|
fmt.Printf("Error Status: %v\n", res.GuetzliStatus)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
_, err = c.CI.DeleteGuetzli(context.Background())
|
||||||
|
log_status(err)
|
||||||
|
res, _, err = c.CI.GetGuetzli(context.Background())
|
||||||
|
log_status(err)
|
||||||
|
if res != nil && res.GuetzliStatus != "off" {
|
||||||
|
fmt.Printf("Error Status: %v\n", res.GuetzliStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
173
object_test.go
173
object_test.go
@@ -25,6 +25,51 @@ func TestObjectService_Get(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
name := "test/hello.txt"
|
name := "test/hello.txt"
|
||||||
|
contentLength := 1024 * 1024 * 10
|
||||||
|
data := make([]byte, contentLength)
|
||||||
|
|
||||||
|
mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
vs := values{
|
||||||
|
"response-content-type": "text/html",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
strRange := r.Header.Get("Range")
|
||||||
|
slice1 := strings.Split(strRange, "=")
|
||||||
|
slice2 := strings.Split(slice1[1], "-")
|
||||||
|
start, _ := strconv.ParseInt(slice2[0], 10, 64)
|
||||||
|
end, _ := strconv.ParseInt(slice2[1], 10, 64)
|
||||||
|
io.Copy(w, bytes.NewBuffer(data[start:end+1]))
|
||||||
|
})
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
math_rand.Seed(time.Now().UnixNano())
|
||||||
|
rangeStart := math_rand.Intn(contentLength)
|
||||||
|
rangeEnd := rangeStart + math_rand.Intn(contentLength-rangeStart)
|
||||||
|
if rangeEnd == rangeStart || rangeStart >= contentLength-1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
opt := &ObjectGetOptions{
|
||||||
|
ResponseContentType: "text/html",
|
||||||
|
Range: fmt.Sprintf("bytes=%v-%v", rangeStart, rangeEnd),
|
||||||
|
}
|
||||||
|
resp, err := client.Object.Get(context.Background(), name, opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Object.Get returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
if bytes.Compare(b, data[rangeStart:rangeEnd+1]) != 0 {
|
||||||
|
t.Errorf("Object.Get Failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestObjectService_GetToFile(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
name := "test/hello.txt"
|
||||||
|
data := make([]byte, 1024*1024*10)
|
||||||
|
rand.Read(data)
|
||||||
|
|
||||||
mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
|
||||||
testMethod(t, r, "GET")
|
testMethod(t, r, "GET")
|
||||||
@@ -33,26 +78,26 @@ func TestObjectService_Get(t *testing.T) {
|
|||||||
}
|
}
|
||||||
testFormValues(t, r, vs)
|
testFormValues(t, r, vs)
|
||||||
testHeader(t, r, "Range", "bytes=0-3")
|
testHeader(t, r, "Range", "bytes=0-3")
|
||||||
fmt.Fprint(w, `hello`)
|
io.Copy(w, bytes.NewReader(data))
|
||||||
})
|
})
|
||||||
|
|
||||||
opt := &ObjectGetOptions{
|
opt := &ObjectGetOptions{
|
||||||
ResponseContentType: "text/html",
|
ResponseContentType: "text/html",
|
||||||
Range: "bytes=0-3",
|
Range: "bytes=0-3",
|
||||||
}
|
}
|
||||||
|
filePath := "test.file" + time.Now().Format(time.RFC3339)
|
||||||
resp, err := client.Object.Get(context.Background(), name, opt)
|
_, err := client.Object.GetToFile(context.Background(), name, filePath, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Object.Get returned error: %v", err)
|
t.Fatalf("Object.Get returned error: %v", err)
|
||||||
}
|
}
|
||||||
|
defer os.Remove(filePath)
|
||||||
b, _ := ioutil.ReadAll(resp.Body)
|
fd, err := os.Open(filePath)
|
||||||
ref := string(b)
|
if err != nil {
|
||||||
want := "hello"
|
}
|
||||||
if !reflect.DeepEqual(ref, want) {
|
defer fd.Close()
|
||||||
t.Errorf("Object.Get returned %+v, want %+v", ref, want)
|
bs, _ := ioutil.ReadAll(fd)
|
||||||
|
if bytes.Compare(bs, data) != 0 {
|
||||||
|
t.Errorf("Object.GetToFile data isn't consistent")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectService_Put(t *testing.T) {
|
func TestObjectService_Put(t *testing.T) {
|
||||||
@@ -132,6 +177,7 @@ func TestObjectService_PutFromFile(t *testing.T) {
|
|||||||
opt := &ObjectPutOptions{
|
opt := &ObjectPutOptions{
|
||||||
ObjectPutHeaderOptions: &ObjectPutHeaderOptions{
|
ObjectPutHeaderOptions: &ObjectPutHeaderOptions{
|
||||||
ContentType: "text/html",
|
ContentType: "text/html",
|
||||||
|
Listener: &DefaultProgressListener{},
|
||||||
},
|
},
|
||||||
ACLHeaderOptions: &ACLHeaderOptions{
|
ACLHeaderOptions: &ACLHeaderOptions{
|
||||||
XCosACL: "private",
|
XCosACL: "private",
|
||||||
@@ -590,3 +636,108 @@ func TestObjectService_Download(t *testing.T) {
|
|||||||
t.Fatalf("Object.Upload returned error: %v", err)
|
t.Fatalf("Object.Upload returned error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestObjectService_GetTagging(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, "GET")
|
||||||
|
vs := values{
|
||||||
|
"tagging": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
fmt.Fprint(w, `<Tagging>
|
||||||
|
<TagSet>
|
||||||
|
<Tag>
|
||||||
|
<Key>test_k2</Key>
|
||||||
|
<Value>test_v2</Value>
|
||||||
|
</Tag>
|
||||||
|
<Tag>
|
||||||
|
<Key>test_k3</Key>
|
||||||
|
<Value>test_vv</Value>
|
||||||
|
</Tag>
|
||||||
|
</TagSet>
|
||||||
|
</Tagging>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
res, _, err := client.Object.GetTagging(context.Background(), "test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Object.GetTagging returned error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := &ObjectGetTaggingResult{
|
||||||
|
XMLName: xml.Name{Local: "Tagging"},
|
||||||
|
TagSet: []ObjectTaggingTag{
|
||||||
|
{"test_k2", "test_v2"},
|
||||||
|
{"test_k3", "test_vv"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(res, want) {
|
||||||
|
t.Errorf("Object.GetTagging returned %+v, want %+v", res, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestObjectService_PutTagging(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
opt := &ObjectPutTaggingOptions{
|
||||||
|
TagSet: []ObjectTaggingTag{
|
||||||
|
{
|
||||||
|
Key: "test_k2",
|
||||||
|
Value: "test_v2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "test_k3",
|
||||||
|
Value: "test_v3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
v := new(ObjectPutTaggingOptions)
|
||||||
|
xml.NewDecoder(r.Body).Decode(v)
|
||||||
|
|
||||||
|
testMethod(t, r, "PUT")
|
||||||
|
vs := values{
|
||||||
|
"tagging": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
|
||||||
|
want := opt
|
||||||
|
want.XMLName = xml.Name{Local: "Tagging"}
|
||||||
|
if !reflect.DeepEqual(v, want) {
|
||||||
|
t.Errorf("Object.PutTagging request body: %+v, want %+v", v, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Object.PutTagging(context.Background(), "test", opt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Object.PutTagging returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestObjectService_DeleteTagging(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
testMethod(t, r, http.MethodDelete)
|
||||||
|
vs := values{
|
||||||
|
"tagging": "",
|
||||||
|
}
|
||||||
|
testFormValues(t, r, vs)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Object.DeleteTagging(context.Background(), "test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Object.DeleteTagging returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user