Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions oss/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,85 @@ func (client Client) DescribeRegionsXml(options ...Option) (string, error) {
return out, err
}

// PutBucketCallbackPolicyXml set bucket's callback policy
// bucketName the bucket name.
// xmlData the call back policy of bucket in xml format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) PutBucketCallbackPolicyXml(bucketName, xmlData string, options ...Option) error {
buffer := new(bytes.Buffer)
buffer.Write([]byte(xmlData))
headers := map[string]string{}
headers[HTTPHeaderContentType] = "application/xml"
params := map[string]interface{}{}
params["policy"] = nil
params["comp"] = "callback"
resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
if err != nil {
return err
}
defer resp.Body.Close()
return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}

// GetBucketCallbackPolicy get bucket's callback policy
// bucketName the bucket name.
// error it's nil if no error, otherwise it's an error object.
func (client Client) GetBucketCallbackPolicy(bucketName string, options ...Option) (GetBucketCallbackPolicyResult, error) {
var out GetBucketCallbackPolicyResult
body, err := client.GetBucketCallbackPolicyXml(bucketName, options...)
if err != nil {
return out, err
}
err = xmlUnmarshal(strings.NewReader(body), &out)
return out, err
}

// GetBucketCallbackPolicyXml get bucket's callback policy
// bucketName the bucket name.
// string the call back policy of bucket in xml format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) GetBucketCallbackPolicyXml(bucketName string, options ...Option) (string, error) {
params := map[string]interface{}{}
params["policy"] = nil
params["comp"] = "callback"
resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
out := string(body)
return out, err
}

// PutBucketCallbackPolicy set bucket's callback policy
// bucketName the bucket name.
// callbackPolicy PutBucketCallbackPolicy the call back policy of bucket in struct format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) PutBucketCallbackPolicy(bucketName string, callbackPolicy PutBucketCallbackPolicy, options ...Option) error {
bs, err := xml.Marshal(callbackPolicy)
if err != nil {
return err
}
err = client.PutBucketCallbackPolicyXml(bucketName, string(bs), options...)
return err
}

// DeleteBucketCallbackPolicy delete bucket's callback policy
// bucketName the bucket name.
// error it's nil if no error, otherwise it's an error object.
func (client Client) DeleteBucketCallbackPolicy(bucketName string, options ...Option) error {
params := map[string]interface{}{}
params["policy"] = nil
params["comp"] = "callback"
resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
}
defer resp.Body.Close()
return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
}

// LimitUploadSpeed set upload bandwidth limit speed,default is 0,unlimited
// upSpeed KB/s, 0 is unlimited,default is 0
// error it's nil if success, otherwise failure
Expand Down
79 changes: 79 additions & 0 deletions oss/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package oss

import (
"bytes"
"encoding/base64"
"encoding/json"
"encoding/xml"
"fmt"
Expand Down Expand Up @@ -5881,3 +5883,80 @@ func (s *OssClientSuite) TestBucketResponseHeader(c *C) {
c.Assert(err, IsNil)
client.DeleteBucket(bucketName)
}

// TestBucketCallbackPolicy
func (s *OssClientSuite) TestBucketCallbackPolicy(c *C) {
var bucketNameTest = bucketNamePrefix + "-acc-" + RandLowStr(6)
client, err := New(endpoint, accessID, accessKey)
c.Assert(err, IsNil)

err = client.CreateBucket(bucketNameTest)
c.Assert(err, IsNil)
time.Sleep(3 * time.Second)

// Put Bucket Callback Policy
var callbackPolicy PutBucketCallbackPolicy
callbackVal := base64.StdEncoding.EncodeToString([]byte(`{"callbackUrl":"http://www.aliyuncs.com", "callbackBody":"bucket=${bucket}&object=${object}"}`))

callbackVal2 := base64.StdEncoding.EncodeToString([]byte(`{"callbackUrl":"http://www.aliyun.com", "callbackBody":"bucket=${bucket}&object=${object}"}`))

callbackVar2 := base64.StdEncoding.EncodeToString([]byte(`{"x:a":"a", "x:b":"b"}`))
callbackPolicy = PutBucketCallbackPolicy{
PolicyItem: []PolicyItem{
{
PolicyName: "first",
Callback: callbackVal,
CallbackVar: "",
},
{
PolicyName: "second",
Callback: callbackVal2,
CallbackVar: callbackVar2,
},
},
}

err = client.PutBucketCallbackPolicy(bucketNameTest, callbackPolicy)
c.Assert(err, IsNil)

time.Sleep(time.Second * 3)

// get bucket callback policy
res, err := client.GetBucketCallbackPolicy(bucketNameTest)
c.Assert(err, IsNil)
c.Assert(len(res.PolicyItem), Equals, 2)

bucket, err := client.Bucket(bucketNameTest)

name := base64.StdEncoding.EncodeToString([]byte(`{"callbackPolicy":"first"}`))
err = bucket.PutObject("object.txt", strings.NewReader("hi oss"), Callback(name))
c.Assert(err, NotNil)
c.Assert(err.(UnexpectedStatusCodeError).Got(), Equals, 203)

name = base64.StdEncoding.EncodeToString([]byte(`{"callbackPolicy":"not_exist_name"}`))
err = bucket.PutObject("object.txt", strings.NewReader("hi oss"), Callback(name))
c.Assert(err, NotNil)

name = base64.StdEncoding.EncodeToString([]byte(`{"callbackPolicy":"not_exist_name"}`))
callbackMap := map[string]string{}
callbackMap["callbackUrl"] = "http://oss-demo.aliyuncs.com:23451"
callbackMap["callbackHost"] = "oss-cn-hangzhou.aliyuncs.com"
callbackMap["callbackBody"] = "filename=${object}&size=${size}&mimeType=${mimeType}"
callbackMap["callbackBodyType"] = "application/x-www-form-urlencoded"
callbackMap["callbackPolicy"] = "first"
callbackBuffer := bytes.NewBuffer([]byte{})
callbackEncoder := json.NewEncoder(callbackBuffer)
//do not encode '&' to "\u0026"
callbackEncoder.SetEscapeHTML(false)
err = callbackEncoder.Encode(callbackMap)
c.Assert(err, IsNil)
callbackVal3 := base64.StdEncoding.EncodeToString(callbackBuffer.Bytes())
err = bucket.PutObject("object.txt", strings.NewReader("hi oss"), Callback(callbackVal3))
c.Assert(err, NotNil)

// delete bucket style
err = client.DeleteBucketCallbackPolicy(bucketNameTest)
c.Assert(err, IsNil)

ForceDeleteBucket(client, bucketNameTest, c)
}
18 changes: 18 additions & 0 deletions oss/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -1693,3 +1693,21 @@ type ResponseHeaderRuleFilters struct {
type ResponseHeaderRuleHeaders struct {
Header []string `xml:"Header,omitempty"`
}

// GetBucketCallbackPolicyResult define the callback policy for the bucket
type GetBucketCallbackPolicyResult BucketCallbackPolicyXml

// PutBucketCallbackPolicy define the callback policy for the bucket
type PutBucketCallbackPolicy BucketCallbackPolicyXml

// BucketCallbackPolicyXml define the callback policy of the bucket
type BucketCallbackPolicyXml struct {
XMLName xml.Name `xml:"BucketCallbackPolicy"`
PolicyItem []PolicyItem `xml:"PolicyItem"`
}

type PolicyItem struct {
PolicyName string `xml:"PolicyName"`
Callback string `xml:"Callback"`
CallbackVar string `xml:"CallbackVar"`
}
55 changes: 55 additions & 0 deletions oss/type_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package oss

import (
"encoding/base64"
"encoding/xml"
"log"
"net/url"
Expand Down Expand Up @@ -2038,3 +2039,57 @@ func (s *OssTypeSuite) TestPutBucketCORS(c *C) {
c.Assert(err, IsNil)
c.Assert(string(bs), Equals, "<CORSConfiguration><CORSRule><AllowedOrigin>*</AllowedOrigin><AllowedMethod>PUT</AllowedMethod><AllowedMethod>GET</AllowedMethod><AllowedMethod>POST</AllowedMethod><MaxAgeSeconds>100</MaxAgeSeconds></CORSRule><CORSRule><AllowedOrigin>http://www.a.com</AllowedOrigin><AllowedOrigin>http://www.b.com</AllowedOrigin><AllowedMethod>GET</AllowedMethod><AllowedHeader>Authorization</AllowedHeader><ExposeHeader>x-oss-test</ExposeHeader><ExposeHeader>x-oss-test1</ExposeHeader><MaxAgeSeconds>100</MaxAgeSeconds></CORSRule><ResponseVary>true</ResponseVary></CORSConfiguration>")
}

func (s *OssTypeSuite) TestGetBucketCallbackPolicyResult(c *C) {
xmlData := `<?xml version="1.0" encoding="UTF-8"?>
<BucketCallbackPolicy>
<PolicyItem>
<PolicyName>first</PolicyName>
<Callback>e1wiY2FsR7YnU=</Callback>
<CallbackVar>Q2FsbGmJcIn0=</CallbackVar>
</PolicyItem>
<PolicyItem>
<PolicyName>second</PolicyName>
<Callback>e1wiY2Fsb9keVwiOlwiYnVja2V0PSR7YnU=</Callback>
<CallbackVar>Q2FsFcIiwgXCJ4OmJcIjpcImJcIn0=</CallbackVar>
</PolicyItem>
</BucketCallbackPolicy>`
var repResult GetBucketCallbackPolicyResult
err := xmlUnmarshal(strings.NewReader(xmlData), &repResult)
c.Assert(err, IsNil)
c.Assert(repResult.PolicyItem[0].PolicyName, Equals, "first")
c.Assert(repResult.PolicyItem[0].Callback, Equals, "e1wiY2FsR7YnU=")
c.Assert(repResult.PolicyItem[0].CallbackVar, Equals, "Q2FsbGmJcIn0=")

c.Assert(repResult.PolicyItem[1].PolicyName, Equals, "second")
c.Assert(repResult.PolicyItem[1].Callback, Equals, "e1wiY2Fsb9keVwiOlwiYnVja2V0PSR7YnU=")
c.Assert(repResult.PolicyItem[1].CallbackVar, Equals, "Q2FsFcIiwgXCJ4OmJcIjpcImJcIn0=")
}

func (s *OssTypeSuite) TestPutBucketCallbackPolicy(c *C) {
xmlData := `<BucketCallbackPolicy><PolicyItem><PolicyName>first</PolicyName><Callback>eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuYWxpeXVuY3MuY29tIiwgImNhbGxiYWNrQm9keSI6ImJ1Y2tldD0ke2J1Y2tldH0mb2JqZWN0PSR7b2JqZWN0fSJ9</Callback><CallbackVar></CallbackVar></PolicyItem><PolicyItem><PolicyName>second</PolicyName><Callback>eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuYWxpeXVuLmNvbSIsICJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0ifQ==</Callback><CallbackVar>eyJ4OmEiOiJhIiwgIng6YiI6ImIifQ==</CallbackVar></PolicyItem></BucketCallbackPolicy>`
var callbackPolicy PutBucketCallbackPolicy
callbackVal := base64.StdEncoding.EncodeToString([]byte(`{"callbackUrl":"http://www.aliyuncs.com", "callbackBody":"bucket=${bucket}&object=${object}"}`))

callbackVal2 := base64.StdEncoding.EncodeToString([]byte(`{"callbackUrl":"http://www.aliyun.com", "callbackBody":"bucket=${bucket}&object=${object}"}`))

callbackVar2 := base64.StdEncoding.EncodeToString([]byte(`{"x:a":"a", "x:b":"b"}`))
callbackPolicy = PutBucketCallbackPolicy{
PolicyItem: []PolicyItem{
{
PolicyName: "first",
Callback: callbackVal,
CallbackVar: "",
},
{
PolicyName: "second",
Callback: callbackVal2,
CallbackVar: callbackVar2,
},
},
}
bs, err := xml.Marshal(callbackPolicy)
c.Assert(err, IsNil)
testLogger.Println(string(bs))
c.Assert(string(bs), Equals, xmlData)
}
1 change: 1 addition & 0 deletions sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var sampleMap = map[string]interface{}{
"BucketStyleSample": sample.BucketStyleSample,
"BucketReplicationSample": sample.BucketReplicationSample,
"BucketResponseHeaderSample": sample.BucketResponseHeaderSample,
"BucketCallbackPolicySample": sample.BucketCallbackPolicySample,
"ObjectACLSample": sample.ObjectACLSample,
"ObjectMetaSample": sample.ObjectMetaSample,
"ListObjectsSample": sample.ListObjectsSample,
Expand Down
100 changes: 100 additions & 0 deletions sample/bucket_callbackpolicy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package sample

import (
"encoding/base64"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"os"
"strings"
)

// BucketCallbackPolicySample shows how to set, get and delete the bucket callback policy configuration
func BucketCallbackPolicySample() {
// New client
client, err := oss.New(endpoint, accessID, accessKey)
if err != nil {
HandleError(err)
}

// Create the bucket with default parameters
err = client.CreateBucket(bucketName)
if err != nil {
HandleError(err)
}

// the policy string
var callbackPolicy oss.PutBucketCallbackPolicy
callbackVal := base64.StdEncoding.EncodeToString([]byte(`{"callbackUrl":"http://www.aliyuncs.com", "callbackBody":"bucket=${bucket}&object=${object}"}`))

callbackVal2 := base64.StdEncoding.EncodeToString([]byte(`{"callbackUrl":"http://www.aliyun.com", "callbackBody":"bucket=${bucket}&object=${object}"}`))

callbackVar2 := base64.StdEncoding.EncodeToString([]byte(`{"x:a":"a", "x:b":"b"}`))
callbackPolicy = oss.PutBucketCallbackPolicy{
PolicyItem: []oss.PolicyItem{
{
PolicyName: "first",
Callback: callbackVal,
CallbackVar: "",
},
{
PolicyName: "second",
Callback: callbackVal2,
CallbackVar: callbackVar2,
},
},
}

// Set callback policy
err = client.PutBucketCallbackPolicy(bucketName, callbackPolicy)
if err != nil {
HandleError(err)
}

fmt.Println("Put Bucket Callback Policy Success!")

// Get Bucket policy
result, err := client.GetBucketCallbackPolicy(bucketName)
if err != nil {
HandleError(err)
}
for _, policy := range result.PolicyItem {
fmt.Printf("Callback Policy Name:%s\n", policy.PolicyName)

callback, _ := base64.StdEncoding.DecodeString(policy.Callback)
fmt.Printf("Callback Policy Callback:%s\n", callback)
if policy.CallbackVar != "" {
callbackVar, _ := base64.StdEncoding.DecodeString(policy.CallbackVar)
fmt.Printf("Callback Policy Callback Var:%s\n", callbackVar)
}
}
fmt.Println("Get Bucket Callback Policy Success!")

// Delete Bucket policy
err = client.DeleteBucketCallbackPolicy(bucketName)
if err != nil {
HandleError(err)
}
fmt.Println("Delete Bucket Callback Policy Success!")

// put object by use callback policy
bucket, err := client.Bucket(bucketName)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
name := base64.StdEncoding.EncodeToString([]byte(`{"callbackPolicy":"first"}`))
err = bucket.PutObject("example-object.txt", strings.NewReader("Hello OSS"), oss.Callback(name))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("Use Callback Policy Success!")

// Delete bucket
err = client.DeleteBucket(bucketName)
if err != nil {
HandleError(err)
}

fmt.Println("BucketCallbackPolicySample completed")
}