func (client Client) SetBucketEncryption(bucketName string, encryptionRule ServerEncryptionRule, options ...Option) error {
	var err error
	var bs []byte
	bs, err = xml.Marshal(encryptionRule)
	if err != nil {
		return err
	}
	buffer := new(bytes.Buffer)
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers := map[string]string{}
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	params["encryption"] = nil
	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})
}
SetBucketEncryption set bucket encryption config
bucketName    the bucket name.
error    it's nil if no error, otherwise it's an error object.
package oss
import (
	"bytes"
	"encoding/xml"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"strings"
	"time"
)
type (
	Client struct {
		Config     *Config       
		Conn       *Conn         
		HTTPClient *http.Client  
	}
	ClientOption func(*Client)
)
func New(endpoint, accessKeyID, accessKeySecret string, options ...ClientOption) (*Client, error) {
	config := getDefaultOssConfig()
	config.Endpoint = endpoint
	config.AccessKeyID = accessKeyID
	config.AccessKeySecret = accessKeySecret
	url := &urlMaker{}
	err := url.Init(config.Endpoint, config.IsCname, config.IsUseProxy)
	if err != nil {
		return nil, err
	}
	conn := &Conn{config: config, url: url}
	client := &Client{
		Config: config,
		Conn:   conn,
	}
	for _, option := range options {
		option(client)
	}
	err = conn.init(config, url, client.HTTPClient)
	return client, err
}
func (client Client) Bucket(bucketName string) (*Bucket, error) {
	err := CheckBucketName(bucketName)
	if err != nil {
		return nil, err
	}
	return &Bucket{
		client,
		bucketName,
	}, nil
}
func (client Client) CreateBucket(bucketName string, options ...Option) error {
	headers := make(map[string]string)
	handleOptions(headers, options)
	buffer := new(bytes.Buffer)
	var cbConfig createBucketConfiguration
	cbConfig.StorageClass = StorageStandard
	isStorageSet, valStroage, _ := isOptionSet(options, storageClass)
	isRedundancySet, valRedundancy, _ := isOptionSet(options, redundancyType)
	if isStorageSet {
		cbConfig.StorageClass = valStroage.(StorageClassType)
	}
	if isRedundancySet {
		cbConfig.DataRedundancyType = valRedundancy.(DataRedundancyType)
	}
	bs, err := xml.Marshal(cbConfig)
	if err != nil {
		return err
	}
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	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})
}
func (client Client) ListBuckets(options ...Option) (ListBucketsResult, error) {
	var out ListBucketsResult
	params, err := getRawParams(options)
	if err != nil {
		return out, err
	}
	resp, err := client.do("GET", "", params, nil, nil, options...)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) IsBucketExist(bucketName string) (bool, error) {
	listRes, err := client.ListBuckets(Prefix(bucketName), MaxKeys(1))
	if err != nil {
		return false, err
	}
	if len(listRes.Buckets) == 1 && listRes.Buckets[0].Name == bucketName {
		return true, nil
	}
	return false, nil
}
func (client Client) DeleteBucket(bucketName string, options ...Option) error {
	params := map[string]interface{}{}
	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})
}
func (client Client) GetBucketLocation(bucketName string) (string, error) {
	params := map[string]interface{}{}
	params["location"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	var LocationConstraint string
	err = xmlUnmarshal(resp.Body, &LocationConstraint)
	return LocationConstraint, err
}
func (client Client) SetBucketACL(bucketName string, bucketACL ACLType) error {
	headers := map[string]string{HTTPHeaderOssACL: string(bucketACL)}
	params := map[string]interface{}{}
	params["acl"] = nil
	resp, err := client.do("PUT", bucketName, params, headers, nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error) {
	var out GetBucketACLResult
	params := map[string]interface{}{}
	params["acl"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule) error {
	err := verifyLifecycleRules(rules)
	if err != nil {
		return err
	}
	lifecycleCfg := LifecycleConfiguration{Rules: rules}
	bs, err := xml.Marshal(lifecycleCfg)
	if err != nil {
		return err
	}
	buffer := new(bytes.Buffer)
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers := map[string]string{}
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	params["lifecycle"] = nil
	resp, err := client.do("PUT", bucketName, params, headers, buffer)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
func (client Client) DeleteBucketLifecycle(bucketName string) error {
	params := map[string]interface{}{}
	params["lifecycle"] = nil
	resp, err := client.do("DELETE", bucketName, params, nil, nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
}
func (client Client) GetBucketLifecycle(bucketName string) (GetBucketLifecycleResult, error) {
	var out GetBucketLifecycleResult
	params := map[string]interface{}{}
	params["lifecycle"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) SetBucketReferer(bucketName string, referers []string, allowEmptyReferer bool) error {
	rxml := RefererXML{}
	rxml.AllowEmptyReferer = allowEmptyReferer
	if referers == nil {
		rxml.RefererList = append(rxml.RefererList, "")
	} else {
		for _, referer := range referers {
			rxml.RefererList = append(rxml.RefererList, referer)
		}
	}
	bs, err := xml.Marshal(rxml)
	if err != nil {
		return err
	}
	buffer := new(bytes.Buffer)
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers := map[string]string{}
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	params["referer"] = nil
	resp, err := client.do("PUT", bucketName, params, headers, buffer)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
func (client Client) GetBucketReferer(bucketName string) (GetBucketRefererResult, error) {
	var out GetBucketRefererResult
	params := map[string]interface{}{}
	params["referer"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix string,
	isEnable bool) error {
	var err error
	var bs []byte
	if isEnable {
		lxml := LoggingXML{}
		lxml.LoggingEnabled.TargetBucket = targetBucket
		lxml.LoggingEnabled.TargetPrefix = targetPrefix
		bs, err = xml.Marshal(lxml)
	} else {
		lxml := loggingXMLEmpty{}
		bs, err = xml.Marshal(lxml)
	}
	if err != nil {
		return err
	}
	buffer := new(bytes.Buffer)
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers := map[string]string{}
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	params["logging"] = nil
	resp, err := client.do("PUT", bucketName, params, headers, buffer)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
func (client Client) DeleteBucketLogging(bucketName string) error {
	params := map[string]interface{}{}
	params["logging"] = nil
	resp, err := client.do("DELETE", bucketName, params, nil, nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
}
func (client Client) GetBucketLogging(bucketName string) (GetBucketLoggingResult, error) {
	var out GetBucketLoggingResult
	params := map[string]interface{}{}
	params["logging"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument string) error {
	wxml := WebsiteXML{}
	wxml.IndexDocument.Suffix = indexDocument
	wxml.ErrorDocument.Key = errorDocument
	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)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
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, options...)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
func (client Client) DeleteBucketWebsite(bucketName string) error {
	params := map[string]interface{}{}
	params["website"] = nil
	resp, err := client.do("DELETE", bucketName, params, nil, nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
}
func (client Client) GetBucketWebsite(bucketName string) (GetBucketWebsiteResult, error) {
	var out GetBucketWebsiteResult
	params := map[string]interface{}{}
	params["website"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) error {
	corsxml := CORSXML{}
	for _, v := range corsRules {
		cr := CORSRule{}
		cr.AllowedMethod = v.AllowedMethod
		cr.AllowedOrigin = v.AllowedOrigin
		cr.AllowedHeader = v.AllowedHeader
		cr.ExposeHeader = v.ExposeHeader
		cr.MaxAgeSeconds = v.MaxAgeSeconds
		corsxml.CORSRules = append(corsxml.CORSRules, cr)
	}
	bs, err := xml.Marshal(corsxml)
	if err != nil {
		return err
	}
	buffer := new(bytes.Buffer)
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers := map[string]string{}
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	params["cors"] = nil
	resp, err := client.do("PUT", bucketName, params, headers, buffer)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusOK})
}
func (client Client) DeleteBucketCORS(bucketName string) error {
	params := map[string]interface{}{}
	params["cors"] = nil
	resp, err := client.do("DELETE", bucketName, params, nil, nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
}
func (client Client) GetBucketCORS(bucketName string) (GetBucketCORSResult, error) {
	var out GetBucketCORSResult
	params := map[string]interface{}{}
	params["cors"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}
func (client Client) GetBucketInfo(bucketName string, options ...Option) (GetBucketInfoResult, error) {
	var out GetBucketInfoResult
	params := map[string]interface{}{}
	params["bucketInfo"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil, options...)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	if err == nil {
		if out.BucketInfo.SseRule.KMSMasterKeyID == "None" {
			out.BucketInfo.SseRule.KMSMasterKeyID = ""
		}
		if out.BucketInfo.SseRule.SSEAlgorithm == "None" {
			out.BucketInfo.SseRule.SSEAlgorithm = ""
		}
	}
	return out, err
}
func (client Client) SetBucketVersioning(bucketName string, versioningConfig VersioningConfig, options ...Option) error {
	var err error
	var bs []byte
	bs, err = xml.Marshal(versioningConfig)
	if err != nil {
		return err
	}
	buffer := new(bytes.Buffer)
	buffer.Write(bs)
	contentType := http.DetectContentType(buffer.Bytes())
	headers := map[string]string{}
	headers[HTTPHeaderContentType] = contentType
	params := map[string]interface{}{}
	params["versioning"] = nil
	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})
}
func (client Client) GetBucketVersioning(bucketName string, options ...Option) (GetBucketVersioningResult, error) {
	var out GetBucketVersioningResult
	params := map[string]interface{}{}
	params["versioning"] = nil
	resp, err := client.do("GET", bucketName, params, nil, nil, options...)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &out)
	return out, err
}