jojoliang
4 years ago
10 changed files with 1164 additions and 22 deletions
-
7batch.go
-
9bucket_origin.go
-
180bucket_origin_test.go
-
121bucket_policy_test.go
-
40ci.go
-
497ci_test.go
-
33error_test.go
-
58example/CI/compression/ci_compression.go
-
68example/CI/compression/guetzli.go
-
173object_test.go
@ -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) |
||||
|
} |
||||
|
} |
@ -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) |
||||
|
} |
||||
|
} |
@ -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) |
||||
|
} |
||||
|
} |
@ -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) |
||||
|
} |
@ -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) |
||||
|
} |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue