Bladeren bron

add SetBucketWebsiteDetail api && BucketPolicy api

alzhang 6 jaren geleden
bovenliggende
commit
24e954aff4
8 gewijzigde bestanden met toevoegingen van 729 en 24 verwijderingen
  1. 3 5
      oss/bucket.go
  2. 4 6
      oss/bucket_test.go
  3. 136 0
      oss/client.go
  4. 359 11
      oss/client_test.go
  5. 60 2
      oss/type.go
  6. 2 0
      sample.go
  7. 61 0
      sample/bucket_policy.go
  8. 104 0
      sample/bucket_website.go

+ 3 - 5
oss/bucket.go

@@ -1121,17 +1121,15 @@ func (bucket Bucket) DeleteObjectTagging(objectKey string, options ...Option) er
 	return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
 }
 
-func (bucket Bucket) OptionsMethod(objectKey string, options ...Option) (int, http.Header, error) {
-	var statusCode int
+func (bucket Bucket) OptionsMethod(objectKey string, options ...Option) (http.Header, error) {
 	var out http.Header
 	resp, err := bucket.do("OPTIONS", objectKey, nil, options, nil, nil)
 	if err != nil {
-		return statusCode, out, err
+		return out, err
 	}
 	defer resp.Body.Close()
-	statusCode = resp.StatusCode
 	out = resp.Headers
-	return statusCode, out, nil
+	return out, nil
 }
 
 // Private

+ 4 - 6
oss/bucket_test.go

@@ -4431,9 +4431,8 @@ func (s *OssBucketSuite) TestOptionsMethod(c *C) {
 	options = append(options, originOption)
 	options = append(options, acMethodOption)
 	options = append(options, acHeadersOption)
-	statusCode, _, err := bucket.OptionsMethod("", options...)
+	_, err = bucket.OptionsMethod("", options...)
 	c.Assert(err, IsNil)
-	c.Assert(statusCode, Equals, 200)
 
 	// options failure
 	options = []Option{}
@@ -4443,7 +4442,7 @@ func (s *OssBucketSuite) TestOptionsMethod(c *C) {
 	options = append(options, originOption)
 	options = append(options, acMethodOption)
 	options = append(options, acHeadersOption)
-	statusCode, _, err = bucket.OptionsMethod("", options...)
+	_, err = bucket.OptionsMethod("", options...)
 	c.Assert(err, NotNil)
 
 	// put object
@@ -4460,9 +4459,8 @@ func (s *OssBucketSuite) TestOptionsMethod(c *C) {
 	options = append(options, originOption)
 	options = append(options, acMethodOption)
 	options = append(options, acHeadersOption)
-	statusCode, _, err = bucket.OptionsMethod("", options...)
+	_, err = bucket.OptionsMethod("", options...)
 	c.Assert(err, IsNil)
-	c.Assert(statusCode, Equals, 200)
 
 	// options failure
 	options = []Option{}
@@ -4472,7 +4470,7 @@ func (s *OssBucketSuite) TestOptionsMethod(c *C) {
 	options = append(options, originOption)
 	options = append(options, acMethodOption)
 	options = append(options, acHeadersOption)
-	statusCode, _, err = bucket.OptionsMethod("", options...)
+	_, err = bucket.OptionsMethod("", options...)
 	c.Assert(err, NotNil)
 
 	bucket.DeleteObject(objectName)

+ 136 - 0
oss/client.go

@@ -7,6 +7,7 @@ import (
 	"encoding/xml"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"log"
 	"net/http"
 	"strings"
@@ -532,6 +533,46 @@ func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument s
 	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
 }
 
+// SetBucketWebsiteDetail sets the bucket's static website's detail
+//
+// OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
+// For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
+//
+// bucketName the bucket name to enable static web site.
+//
+// wxml the website's detail
+//
+// error    it's nil if no error, otherwise it's an error object.
+//
+func (client Client) SetBucketWebsiteDetail(bucketName string, wxml WebsiteXML, options ...Option) error {
+	bs, err := xml.Marshal(wxml)
+	if err != nil {
+		return err
+	}
+	buffer := new(bytes.Buffer)
+	buffer.Write(bs)
+
+	contentType := http.DetectContentType(buffer.Bytes())
+	headers := make(map[string]string)
+	headers[HTTPHeaderContentType] = contentType
+
+	params := map[string]interface{}{}
+	params["website"] = nil
+	resp, err := client.do("PUT", bucketName, params, headers, buffer)
+
+	// get response header
+	respHeader, _ := findOption(options, responseHeader, nil)
+	if respHeader != nil {
+		pRespHeader := respHeader.(*http.Header)
+		*pRespHeader = resp.Headers
+	}
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
 // DeleteBucketWebsite deletes the bucket's static web site settings.
 //
 // bucketName    the bucket name.
@@ -933,6 +974,101 @@ func (client Client) GetBucketStat(bucketName string) (GetBucketStatResult, erro
 	return out, err
 }
 
+// GetBucketPolicy API operation for Object Storage Service.
+//
+// Get the policy from the bucket.
+//
+// bucketName 	 the bucket name.
+//
+// string		 return the bucket's policy, and it's only valid when error is nil.
+//
+// error   		 it's nil if no error, otherwise it's an error object.
+//
+func (client Client) GetBucketPolicy(bucketName string, options ...Option) (string, error) {
+	params := map[string]interface{}{}
+	params["policy"] = nil
+
+	resp, err := client.do("GET", bucketName, params, nil, nil)
+
+	// get response header
+	respHeader, _ := findOption(options, responseHeader, nil)
+	if respHeader != nil {
+		pRespHeader := respHeader.(*http.Header)
+		*pRespHeader = resp.Headers
+	}
+
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+
+	out := string(body)
+	return out, err
+}
+
+// SetBucketPolicy API operation for Object Storage Service.
+//
+// Set the policy from the bucket.
+//
+// bucketName the bucket name.
+//
+// policy the bucket policy.
+//
+// error    it's nil if no error, otherwise it's an error object.
+//
+func (client Client) SetBucketPolicy(bucketName string, policy string, options ...Option) error {
+	params := map[string]interface{}{}
+	params["policy"] = nil
+
+	buffer := strings.NewReader(policy)
+
+	resp, err := client.do("PUT", bucketName, params, nil, buffer)
+
+	// get response header
+	respHeader, _ := findOption(options, responseHeader, nil)
+	if respHeader != nil {
+		pRespHeader := respHeader.(*http.Header)
+		*pRespHeader = resp.Headers
+	}
+
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+
+	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// DeleteBucketPolicy API operation for Object Storage Service.
+//
+// Deletes the policy from the bucket.
+//
+// bucketName the bucket name.
+//
+// error    it's nil if no error, otherwise it's an error object.
+//
+func (client Client) DeleteBucketPolicy(bucketName string, options ...Option) error {
+	params := map[string]interface{}{}
+	params["policy"] = nil
+	resp, err := client.do("DELETE", bucketName, params, nil, nil)
+
+	// get response header
+	respHeader, _ := findOption(options, responseHeader, nil)
+	if respHeader != nil {
+		pRespHeader := respHeader.(*http.Header)
+		*pRespHeader = resp.Headers
+	}
+
+	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

+ 359 - 11
oss/client_test.go

@@ -11,6 +11,7 @@ import (
 	"net/http"
 	"os"
 	"runtime"
+	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -152,6 +153,24 @@ func forceDeleteBucket(client *Client, bucketName string, c *C) {
 		}
 	}
 
+	// delete live channel
+	strMarker := ""
+	for {
+		result, err := bucket.ListLiveChannel(Marker(strMarker))
+		c.Assert(err, IsNil)
+
+		for _, channel := range result.LiveChannel {
+			err := bucket.DeleteLiveChannel(channel.Name)
+			c.Assert(err, IsNil)
+		}
+
+		if result.IsTruncated {
+			strMarker = result.NextMarker
+		} else {
+			break
+		}
+	}
+
 	// Delete Bucket
 	err = client.DeleteBucket(bucketName)
 	c.Assert(err, IsNil)
@@ -414,13 +433,12 @@ func (s *OssClientSuite) TestListBucket(c *C) {
 	err = client.CreateBucket(bucketNameLbThree)
 	c.Assert(err, IsNil)
 
-    // ListBuckets, specified prefix
-    var respHeader http.Header
-    lbr, err := client.ListBuckets(Prefix(prefix), MaxKeys(2),GetResponseHeader(&respHeader))
-    c.Assert(GetRequestId(respHeader) != "", Equals, true)
+	// ListBuckets, specified prefix
+	var respHeader http.Header
+	lbr, err := client.ListBuckets(Prefix(prefix), MaxKeys(2), GetResponseHeader(&respHeader))
+	c.Assert(GetRequestId(respHeader) != "", Equals, true)
 	c.Assert(err, IsNil)
-    c.Assert(len(lbr.Buckets), Equals, 2)
-    
+	c.Assert(len(lbr.Buckets), Equals, 2)
 
 	// ListBuckets, specified max keys
 	lbr, err = client.ListBuckets(MaxKeys(2))
@@ -1321,7 +1339,235 @@ func (s *OssClientSuite) TestSetBucketWebsiteNegative(c *C) {
 	c.Assert(err, IsNil)
 }
 
-// TestSetBucketWebsite
+// TestSetBucketWebsiteDetail
+func (s *OssClientSuite) TestSetBucketWebsiteDetail(c *C) {
+	var bucketNameTest = bucketNamePrefix + randLowStr(6)
+	var indexWebsite = "myindex.html"
+	var errorWebsite = "myerror.html"
+
+	client, err := New(endpoint, accessID, accessKey)
+	c.Assert(err, IsNil)
+
+	err = client.CreateBucket(bucketNameTest)
+	c.Assert(err, IsNil)
+	time.Sleep(timeoutInOperation)
+
+	btrue := true
+	bfalse := false
+	// Define one routing rule
+	ruleOk := RoutingRule{
+		RuleNumber: 1,
+		Condition: Condition{
+			KeyPrefixEquals:             "",
+			HTTPErrorCodeReturnedEquals: 404,
+		},
+		Redirect: Redirect{
+			RedirectType: "Mirror",
+			// PassQueryString: &btrue, 		// set default value
+			MirrorURL: "http://www.test.com/",
+			// MirrorPassQueryString:&btrue, 	// set default value
+			// MirrorFollowRedirect:&bfalse, 	// set default value
+			// MirrorCheckMd5:&bfalse, 			// set default value
+			MirrorHeaders: MirrorHeaders{
+				// PassAll:&bfalse, 			// set default value
+				Pass:   []string{"myheader-key1", "myheader-key2"},
+				Remove: []string{"myheader-key3", "myheader-key4"},
+				Set: []MirrorHeaderSet{
+					MirrorHeaderSet{
+						Key:   "myheader-key5",
+						Value: "myheader-value5",
+					},
+				},
+			},
+		},
+	}
+
+	// Define array routing rule
+	ruleArrOk := []RoutingRule{
+		RoutingRule{
+			RuleNumber: 2,
+			Condition: Condition{
+				KeyPrefixEquals:             "abc/",
+				HTTPErrorCodeReturnedEquals: 404,
+				IncludeHeader: []IncludeHeader{
+					IncludeHeader{
+						Key:    "host",
+						Equals: "test.oss-cn-beijing-internal.aliyuncs.com",
+					},
+				},
+			},
+			Redirect: Redirect{
+				RedirectType:     "AliCDN",
+				Protocol:         "http",
+				HostName:         "www.test.com",
+				PassQueryString:  &bfalse,
+				ReplaceKeyWith:   "prefix/${key}.suffix",
+				HttpRedirectCode: 301,
+			},
+		},
+		RoutingRule{
+			RuleNumber: 3,
+			Condition: Condition{
+				KeyPrefixEquals:             "",
+				HTTPErrorCodeReturnedEquals: 404,
+			},
+			Redirect: Redirect{
+				RedirectType:          "Mirror",
+				PassQueryString:       &btrue,
+				MirrorURL:             "http://www.test.com/",
+				MirrorPassQueryString: &btrue,
+				MirrorFollowRedirect:  &bfalse,
+				MirrorCheckMd5:        &bfalse,
+				MirrorHeaders: MirrorHeaders{
+					PassAll: &btrue,
+					Pass:    []string{"myheader-key1", "myheader-key2"},
+					Remove:  []string{"myheader-key3", "myheader-key4"},
+					Set: []MirrorHeaderSet{
+						MirrorHeaderSet{
+							Key:   "myheader-key5",
+							Value: "myheader-value5",
+						},
+					},
+				},
+			},
+		},
+	}
+
+	// Set one routing rule
+	wxmlOne := WebsiteXML{}
+	wxmlOne.RoutingRules = append(wxmlOne.RoutingRules, ruleOk)
+	var responseHeader http.Header
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxmlOne, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+	requestId := GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	res, err := client.GetBucketWebsite(bucketNameTest)
+	c.Assert(err, IsNil)
+	c.Assert(res.RoutingRules[0].Redirect.RedirectType, Equals, "Mirror")
+	c.Assert(*res.RoutingRules[0].Redirect.PassQueryString, Equals, false)
+	c.Assert(*res.RoutingRules[0].Redirect.MirrorPassQueryString, Equals, false)
+	c.Assert(*res.RoutingRules[0].Redirect.MirrorFollowRedirect, Equals, true)
+	c.Assert(*res.RoutingRules[0].Redirect.MirrorCheckMd5, Equals, false)
+	c.Assert(*res.RoutingRules[0].Redirect.MirrorHeaders.PassAll, Equals, false)
+
+	// Set one routing rule and IndexDocument, IndexDocument
+	wxml := WebsiteXML{
+		IndexDocument: IndexDocument{Suffix: indexWebsite},
+		ErrorDocument: ErrorDocument{Key: errorWebsite},
+	}
+	wxml.RoutingRules = append(wxml.RoutingRules, ruleOk)
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxml, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	res, err = client.GetBucketWebsite(bucketNameTest)
+	c.Assert(err, IsNil)
+	c.Assert(res.IndexDocument.Suffix, Equals, indexWebsite)
+	c.Assert(res.ErrorDocument.Key, Equals, errorWebsite)
+	c.Assert(res.RoutingRules[0].Redirect.RedirectType, Equals, "Mirror")
+
+	// Set array routing rule
+	wxml.RoutingRules = append(wxml.RoutingRules, ruleArrOk...)
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxml, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	res, err = client.GetBucketWebsite(bucketNameTest)
+	c.Assert(err, IsNil)
+	c.Assert(res.IndexDocument.Suffix, Equals, indexWebsite)
+	c.Assert(res.ErrorDocument.Key, Equals, errorWebsite)
+	c.Assert(len(res.RoutingRules), Equals, 3)
+	c.Assert(res.RoutingRules[1].Redirect.RedirectType, Equals, "AliCDN")
+	c.Assert(*res.RoutingRules[2].Redirect.MirrorPassQueryString, Equals, true)
+	c.Assert(*res.RoutingRules[2].Redirect.MirrorFollowRedirect, Equals, false)
+
+	// Define one error routing rule
+	ruleErr := RoutingRule{
+		RuleNumber: 1,
+		Redirect: Redirect{
+			RedirectType:    "Mirror",
+			PassQueryString: &btrue,
+		},
+	}
+	// Define array error routing rule
+	rulesErrArr := []RoutingRule{
+		RoutingRule{
+			RuleNumber: 1,
+			Redirect: Redirect{
+				RedirectType:    "Mirror",
+				PassQueryString: &btrue,
+			},
+		},
+		RoutingRule{
+			RuleNumber: 2,
+			Redirect: Redirect{
+				RedirectType:    "Mirror",
+				PassQueryString: &btrue,
+			},
+		},
+	}
+
+	ruleIntErr := RoutingRule{
+		// RuleNumber:0,						// set NULL value
+		Condition: Condition{
+			KeyPrefixEquals:             "",
+			HTTPErrorCodeReturnedEquals: 404,
+		},
+		Redirect: Redirect{
+			RedirectType: "Mirror",
+			// PassQueryString: &btrue, 		// set default value
+			MirrorURL: "http://www.test.com/",
+			// MirrorPassQueryString:&btrue, 	// set default value
+			// MirrorFollowRedirect:&bfalse, 	// set default value
+			// MirrorCheckMd5:&bfalse, 			// set default value
+			MirrorHeaders: MirrorHeaders{
+				// PassAll:&bfalse, 			// set default value
+				Pass:   []string{"myheader-key1", "myheader-key2"},
+				Remove: []string{"myheader-key3", "myheader-key4"},
+				Set: []MirrorHeaderSet{
+					MirrorHeaderSet{
+						Key:   "myheader-key5",
+						Value: "myheader-value5",
+					},
+				},
+			},
+		},
+	}
+
+	// Set one int type error rule
+	wxmlIntErr := WebsiteXML{}
+	wxmlIntErr.RoutingRules = append(wxmlIntErr.RoutingRules, ruleIntErr)
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxmlIntErr)
+	c.Assert(err, NotNil)
+
+	// Set one error rule
+	wxmlErr := WebsiteXML{}
+	wxmlErr.RoutingRules = append(wxmlErr.RoutingRules, ruleErr)
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxmlErr)
+	c.Assert(err, NotNil)
+
+	// Set one error rule and one correct rule
+	wxmlErr.RoutingRules = append(wxmlErr.RoutingRules, ruleOk)
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxmlErr)
+	c.Assert(err, NotNil)
+
+	wxmlErrRuleArr := WebsiteXML{}
+	wxmlErrRuleArr.RoutingRules = append(wxmlErrRuleArr.RoutingRules, rulesErrArr...)
+	// Set array error routing rule
+	err = client.SetBucketWebsiteDetail(bucketNameTest, wxmlErrRuleArr)
+	c.Assert(err, NotNil)
+
+	err = client.DeleteBucketWebsite(bucketNameTest)
+	c.Assert(err, IsNil)
+
+	err = client.DeleteBucket(bucketNameTest)
+	c.Assert(err, IsNil)
+}
+
+// TestSetBucketCORS
 func (s *OssClientSuite) TestSetBucketCORS(c *C) {
 	var bucketNameTest = bucketNamePrefix + randLowStr(6)
 	var rule1 = CORSRule{
@@ -1866,13 +2112,16 @@ func (s *OssClientSuite) TestSetLimitUploadSpeed(c *C) {
 	if len(pSlice) >= 2 {
 		if pSlice[0] > "go1" {
 			c.Assert(err, IsNil)
-		} else if pSlice[0] == "go1" && pSlice[1] >= "7" {
-			c.Assert(err, IsNil)
+		} else if pSlice[0] == "go1" {
+			subVersion, _ := strconv.Atoi(pSlice[1])
+			if subVersion >= 7 {
+				c.Assert(err, IsNil)
+			} else {
+				c.Assert(err, NotNil)
+			}
 		} else {
 			c.Assert(err, NotNil)
 		}
-	} else {
-		c.Assert(err, NotNil)
 	}
 }
 
@@ -2191,3 +2440,102 @@ func (s *OssBucketSuite) TestGetBucketVersioning(c *C) {
 
 	forceDeleteBucket(client, bucketName, c)
 }
+
+func (s *OssClientSuite) TestBucketPolicy(c *C){
+	client, err := New(endpoint, accessID, accessKey)
+	c.Assert(err, IsNil)
+
+	bucketName := bucketNamePrefix + randLowStr(5)
+	err = client.CreateBucket(bucketName)
+	c.Assert(err, IsNil)
+	
+	var responseHeader http.Header
+	ret, err := client.GetBucketPolicy(bucketName, GetResponseHeader(&responseHeader))
+	c.Assert(err, NotNil)
+	requestId := GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	policyInfo := `
+	{
+		"Version":"1",
+		"Statement":[
+			{
+				"Action":[
+					"oss:GetObject",
+					"oss:PutObject"
+				],
+				"Effect":"Deny",
+				"Principal":"[123456790]",
+				"Resource":["acs:oss:*:1234567890:*/*"]
+			}
+		]
+	}`
+
+	err = client.SetBucketPolicy(bucketName, policyInfo, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	ret, err = client.GetBucketPolicy(bucketName, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+	testLogger.Println("policy:", ret)
+	c.Assert(ret, Equals, policyInfo)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	err = client.DeleteBucketPolicy(bucketName, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+	client.DeleteBucket(bucketName)
+}
+
+func (s *OssClientSuite) TestBucketPolicyNegative(c *C) {
+	client, err := New(endpoint, accessID, accessKey)
+	c.Assert(err, IsNil)
+
+	bucketName := bucketNamePrefix + randLowStr(5)
+	err = client.CreateBucket(bucketName)
+	c.Assert(err, IsNil)
+
+	var responseHeader http.Header
+	_, err = client.GetBucketPolicy(bucketName, GetResponseHeader(&responseHeader))
+	c.Assert(err, NotNil)
+	requestId := GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	// Setting the Version is 2, this is error policy
+	errPolicy := `
+	{
+		"Version":"2",
+		"Statement":[
+			{
+				"Action":[
+					"oss:GetObject",
+					"oss:PutObject"
+				],
+				"Effect":"Deny",
+				"Principal":"[123456790]",
+				"Resource":["acs:oss:*:1234567890:*/*"]
+			}
+		]
+	}`
+	err = client.SetBucketPolicy(bucketName, errPolicy, GetResponseHeader(&responseHeader))
+	c.Assert(err, NotNil)
+	testLogger.Println("err:",err)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	err = client.DeleteBucketPolicy(bucketName, GetResponseHeader(&responseHeader))
+	c.Assert(err, IsNil)
+
+	bucketNameEmpty := bucketNamePrefix + randLowStr(5)
+	client.DeleteBucket(bucketNameEmpty)
+	
+	err = client.DeleteBucketPolicy(bucketNameEmpty, GetResponseHeader(&responseHeader))
+	c.Assert(err, NotNil)
+	requestId = GetRequestId(responseHeader)
+	c.Assert(len(requestId) > 0, Equals, true)
+
+	client.DeleteBucket(bucketName)
+}

+ 60 - 2
oss/type.go

@@ -181,8 +181,9 @@ type GetBucketLoggingResult LoggingXML
 // WebsiteXML defines Website configuration
 type WebsiteXML struct {
 	XMLName       xml.Name      `xml:"WebsiteConfiguration"`
-	IndexDocument IndexDocument `xml:"IndexDocument"` // The index page
-	ErrorDocument ErrorDocument `xml:"ErrorDocument"` // The error page
+	IndexDocument IndexDocument `xml:"IndexDocument,omitempty"`            // The index page
+	ErrorDocument ErrorDocument `xml:"ErrorDocument,omitempty"`            // The error page
+	RoutingRules  []RoutingRule `xml:"RoutingRules>RoutingRule,omitempty"` // The routing Rule list
 }
 
 // IndexDocument defines the index page info
@@ -197,6 +198,63 @@ type ErrorDocument struct {
 	Key     string   `xml:"Key"` // 404 error file name
 }
 
+// RoutingRule defines the routing rules
+type RoutingRule struct {
+	XMLName    xml.Name  `xml:"RoutingRule"`
+	RuleNumber int       `xml:"RuleNumber,omitempty"` // The routing number
+	Condition  Condition `xml:"Condition,omitempty"`  // The routing condition
+	Redirect   Redirect  `xml:"Redirect,omitempty"`   // The routing redirect
+
+}
+
+// Condition defines codition in the RoutingRule
+type Condition struct {
+	XMLName                     xml.Name        `xml:"Condition"`
+	KeyPrefixEquals             string          `xml:"KeyPrefixEquals,omitempty"`             // Matching objcet prefix
+	HTTPErrorCodeReturnedEquals int             `xml:"HttpErrorCodeReturnedEquals,omitempty"` // The rule is for Accessing to the specified object
+	IncludeHeader               []IncludeHeader `xml:"IncludeHeader"`                         // The rule is for request which include header
+}
+
+// IncludeHeader defines includeHeader in the RoutingRule's Condition
+type IncludeHeader struct {
+	XMLName xml.Name `xml:"IncludeHeader"`
+	Key     string   `xml:"Key,omitempty"`    // The Include header key
+	Equals  string   `xml:"Equals,omitempty"` // The Include header value
+}
+
+// Redirect defines redirect in the RoutingRule
+type Redirect struct {
+	XMLName               xml.Name      `xml:"Redirect"`
+	RedirectType          string        `xml:"RedirectType,omitempty"`         // The redirect type, it have Mirror,External,Internal,AliCDN
+	PassQueryString       *bool         `xml:"PassQueryString"`                // Whether to send the specified request's parameters, true or false
+	MirrorURL             string        `xml:"MirrorURL,omitempty"`            // Mirror of the website address back to the source.
+	MirrorPassQueryString *bool         `xml:"MirrorPassQueryString"`          // To Mirror of the website Whether to send the specified request's parameters, true or false
+	MirrorFollowRedirect  *bool         `xml:"MirrorFollowRedirect"`           // Redirect the location, if the mirror return 3XX
+	MirrorCheckMd5        *bool         `xml:"MirrorCheckMd5"`                 // Check the mirror is MD5.
+	MirrorHeaders         MirrorHeaders `xml:"MirrorHeaders,omitempty"`        // Mirror headers
+	Protocol              string        `xml:"Protocol,omitempty"`             // The redirect Protocol
+	HostName              string        `xml:"HostName,omitempty"`             // The redirect HostName
+	ReplaceKeyPrefixWith  string        `xml:"ReplaceKeyPrefixWith,omitempty"` // object name'Prefix replace the value
+	HttpRedirectCode      int           `xml:"HttpRedirectCode,omitempty"`     // THe redirect http code
+	ReplaceKeyWith        string        `xml:"ReplaceKeyWith,omitempty"`       // object name replace the value
+}
+
+// MirrorHeaders defines MirrorHeaders in the Redirect
+type MirrorHeaders struct {
+	XMLName xml.Name          `xml:"MirrorHeaders"`
+	PassAll *bool             `xml:"PassAll"` // Penetrating all of headers to source website.
+	Pass    []string          `xml:"Pass"`    // Penetrating some of headers to source website.
+	Remove  []string          `xml:"Remove"`  // Prohibit passthrough some of headers to source website
+	Set     []MirrorHeaderSet `xml:"Set"`     // Setting some of headers send to source website
+}
+
+// MirrorHeaderSet defines Set for Redirect's MirrorHeaders
+type MirrorHeaderSet struct {
+	XMLName xml.Name `xml:"Set"`
+	Key     string   `xml:"Key,omitempty"`   // The mirror header key
+	Value   string   `xml:"Value,omitempty"` // The mirror header value
+}
+
 // GetBucketWebsiteResult defines the result from GetBucketWebsite request.
 type GetBucketWebsiteResult WebsiteXML
 

+ 2 - 0
sample.go

@@ -19,7 +19,9 @@ var sampleMap = map[string]interface{}{
 	"BucketLifecycleSample":  sample.BucketLifecycleSample,
 	"BucketRefererSample":    sample.BucketRefererSample,
 	"BucketLoggingSample":    sample.BucketLoggingSample,
+	"BucketWebsiteSample":	  sample.BucketWebsiteSample,
 	"BucketCORSSample":       sample.BucketCORSSample,
+	"BucketPolicySample":	  sample.BucketPolicySample,
 	"ObjectACLSample":        sample.ObjectACLSample,
 	"ObjectMetaSample":       sample.ObjectMetaSample,
 	"ListObjectsSample":      sample.ListObjectsSample,

+ 61 - 0
sample/bucket_policy.go

@@ -0,0 +1,61 @@
+package sample
+
+import (
+	"fmt"
+
+	"github.com/aliyun/aliyun-oss-go-sdk/oss"
+)
+
+// BucketPolicySample shows how to set, get and delete the bucket policy configuration
+func BucketPolicySample() {
+	// 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 policyInfo string
+	policyInfo = `
+	{
+		"Version":"1",
+		"Statement":[
+			{
+				"Action":[
+					"oss:GetObject",
+					"oss:PutObject"
+				],
+				"Effect":"Deny",
+				"Principal":"[123456790]",
+				"Resource":["acs:oss:*:1234567890:*/*"]
+			}
+		]
+	}`
+
+	// Set policy
+	err = client.SetBucketPolicy(bucketName, policyInfo)
+	if err != nil {
+		HandleError(err)
+	}
+
+	// Get Bucket policy
+	ret, err := client.GetBucketPolicy(bucketName)
+	if err != nil {
+		HandleError(err)
+	}
+	fmt.Println("Bucket policy:", ret)
+
+	// Delete Bucket policy
+	err = client.DeleteBucketPolicy(bucketName)
+	if err != nil {
+		HandleError(err)
+	}
+
+	fmt.Println("BucketPolicySample completed")
+}

+ 104 - 0
sample/bucket_website.go

@@ -0,0 +1,104 @@
+package sample
+
+import (
+	"fmt"
+
+	"github.com/aliyun/aliyun-oss-go-sdk/oss"
+)
+
+// BucketWebsiteSample shows how to set, get and delete the bucket website.
+func BucketWebsiteSample() {
+	// 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)
+	}
+
+	//Define bucket website indexWebsite or errorWebsite
+	var indexWebsite = "myindex.html"
+	var errorWebsite = "myerror.html"
+
+	// Set bucket website indexWebsite or errorWebsite
+	err = client.SetBucketWebsite(bucketName, indexWebsite, errorWebsite)
+	if err != nil {
+		HandleError(err)
+	}
+
+	bEnable := true
+	bDisable := false
+
+	// Define one website detail
+	ruleOk := oss.RoutingRule{
+		RuleNumber: 1,
+		Condition: oss.Condition{
+			KeyPrefixEquals:             "abc",
+			HTTPErrorCodeReturnedEquals: 404,
+			IncludeHeader: []oss.IncludeHeader{
+				oss.IncludeHeader{
+					Key:    "host",
+					Equals: "test.oss-cn-beijing-internal.aliyuncs.com",
+				},
+			},
+		},
+		Redirect: oss.Redirect{
+			RedirectType:          "Mirror",
+			PassQueryString:       &bDisable,
+			MirrorURL:             "http://www.test.com/",
+			MirrorPassQueryString: &bEnable,
+			MirrorFollowRedirect:  &bEnable,
+			MirrorCheckMd5:        &bDisable,
+			MirrorHeaders: oss.MirrorHeaders{
+				PassAll: &bEnable,
+				Pass:    []string{"key1", "key2"},
+				Remove:  []string{"remove1", "remove2"},
+				Set: []oss.MirrorHeaderSet{
+					oss.MirrorHeaderSet{
+						Key:   "setKey1",
+						Value: "setValue1",
+					},
+				},
+			},
+		},
+	}
+	wxmlDetail := oss.WebsiteXML{}
+	wxmlDetail.RoutingRules = append(wxmlDetail.RoutingRules, ruleOk)
+
+	// Get website
+	res, err := client.GetBucketWebsite(bucketName)
+	if err != nil {
+		HandleError(err)
+	}
+	fmt.Println("Website IndexDocument:", res.IndexDocument.Suffix)
+
+	// Set bucket website detail
+	err = client.SetBucketWebsiteDetail(bucketName, wxmlDetail)
+	if err != nil {
+		HandleError(err)
+	}
+	// Get website Detail
+	res, err = client.GetBucketWebsite(bucketName)
+	if err != nil {
+		HandleError(err)
+	}
+	fmt.Println("Website Redirect type:", res.RoutingRules[0].Redirect.RedirectType)
+
+	// Delete Website
+	err = client.DeleteBucketWebsite(bucketName)
+	if err != nil {
+		HandleError(err)
+	}
+
+	// Delete bucket
+	err = client.DeleteBucket(bucketName)
+	if err != nil {
+		HandleError(err)
+	}
+
+	fmt.Println("BucketWebsiteSample completed")
+}