func (c *Client) PutObject(bucketName, objectKey string, data interface{},
	metadata *ObjectMetadata, option *bce.SignOption) (PutObjectResponse, error) {
	checkObjectKey(objectKey)
	var reader io.Reader
	if str, ok := data.(string); ok {
		reader = strings.NewReader(str)
	} else if byteArray, ok := data.([]byte); ok {
		reader = bytes.NewReader(byteArray)
	} else if r, ok := data.(io.Reader); ok {
		reader = r
	} else {
		panic("data type should be string or []byte or io.Reader.")
	}
	req, err := bce.NewRequest("PUT", c.GetURL(bucketName, objectKey, nil), reader)
	if err != nil {
		return nil, err
	}
	option = bce.CheckSignOption(option)
	option.AddHeader("Content-Type", util.GuessMimeType(objectKey))
	if c.Checksum {
		option.AddHeader("x-bce-content-sha256", util.GetSha256(data))
	}
	if metadata != nil {
		metadata.mergeToSignOption(option)
	}
	resp, err := c.SendRequest(req, option)
	if err != nil {
		return nil, err
	}
	putObjectResponse := NewPutObjectResponse(resp.Header)
	return putObjectResponse, nil
}
PutObject creates a BOS Object.

For details, please refer https://cloud.baidu.com/doc/BOS/API.html#PutObject.E6.8E.A5.E5.8F.A3
package bos
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"net/http"
	"os"
	"strconv"
	"strings"
	"sync"
	"github.com/baidu/baiducloud-sdk-go/bce"
	"github.com/baidu/baiducloud-sdk-go/util"
)
var Endpoint = map[string]string{
	"bj": "bj.bcebos.com",
	"gz": "gz.bcebos.com",
	"hk": "hk.bcebos.com",
	"su": "su.bcebos.com",
	"bd": "bd.bcebos.com",
}
type Client struct {
	*bce.Client
}
func NewClient(config *bce.Config) *Client {
	bceClient := bce.NewClient(config)
	return &Client{bceClient}
}
func checkBucketName(bucketName string) {
	if bucketName == "" {
		panic("bucket name should not be empty.")
	}
	if strings.Index(bucketName, "/") == 0 {
		panic("bucket name should not be start with '/'")
	}
}
func checkObjectKey(objectKey string) {
	if objectKey == "" {
		panic("object key should not be empty.")
	}
	if strings.Index(objectKey, "/") == 0 {
		panic("object key should not be start with '/'")
	}
}
func (c *Client) GetURL(bucketName, objectKey string, params map[string]string) string {
	host := c.Endpoint
	if host == "" {
		host = Endpoint[c.GetRegion()]
	}
	if bucketName != "" {
		host = bucketName + "." + host
	}
	uriPath := objectKey
	return c.Client.GetURL(host, uriPath, params)
}
func (c *Client) GetBucketLocation(bucketName string, option *bce.SignOption) (*Location, error) {
	params := map[string]string{"location": ""}
	req, err := bce.NewRequest("GET", c.GetURL(bucketName, "", params), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.SendRequest(req, option)
	if err != nil {
		return nil, err
	}
	bodyContent, err := resp.GetBodyContent()
	if err != nil {
		return nil, err
	}
	var location *Location
	err = json.Unmarshal(bodyContent, &location)
	if err != nil {
		return nil, err
	}
	return location, nil
}
func (c *Client) ListBuckets(option *bce.SignOption) (*BucketSummary, error) {
	req, err := bce.NewRequest("GET", c.GetURL("", "", nil), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.SendRequest(req, option)
	if err != nil {
		return nil, err
	}
	bodyContent, err := resp.GetBodyContent()
	if err != nil {
		return nil, err
	}
	var bucketSummary *BucketSummary
	err = json.Unmarshal(bodyContent, &bucketSummary)
	if err != nil {
		return nil, err
	}
	return bucketSummary, nil
}
func (c *Client) CreateBucket(bucketName string, option *bce.SignOption) error {
	req, err := bce.NewRequest("PUT", c.GetURL(bucketName, "", nil), nil)
	if err != nil {
		return err
	}
	_, err = c.SendRequest(req, option)
	return err
}
func (c *Client) DoesBucketExist(bucketName string, option *bce.SignOption) (bool, error) {
	req, err := bce.NewRequest("HEAD", c.GetURL(bucketName, "", nil), nil)
	if err != nil {
		return false, err
	}
	resp, err := c.SendRequest(req, option)
	if resp != nil {
		switch {
		case resp.StatusCode < http.StatusBadRequest || resp.StatusCode == http.StatusForbidden:
			return true, nil
		case resp.StatusCode == http.StatusNotFound:
			return false, nil
		}
	}
	return false, err
}
func (c *Client) DeleteBucket(bucketName string, option *bce.SignOption) error {
	req, err := bce.NewRequest("DELETE", c.GetURL(bucketName, "", nil), nil)
	if err != nil {
		return err
	}
	_, err = c.SendRequest(req, option)
	return err
}
func (c *Client) SetBucketPrivate(bucketName string, option *bce.SignOption) error {
	return c.setBucketAclFromString(bucketName, CannedAccessControlList["Private"], option)
}
func (c *Client) SetBucketPublicRead(bucketName string, option *bce.SignOption) error {
	return c.setBucketAclFromString(bucketName, CannedAccessControlList["PublicRead"], option)
}
func (c *Client) SetBucketPublicReadWrite(bucketName string, option *bce.SignOption) error {
	return c.setBucketAclFromString(bucketName, CannedAccessControlList["PublicReadWrite"], option)
}
func (c *Client) GetBucketAcl(bucketName string, option *bce.SignOption) (*BucketAcl, error) {
	params := map[string]string{"acl": ""}
	req, err := bce.NewRequest("GET", c.GetURL(bucketName, "", params), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.SendRequest(req, option)
	if err != nil {
		return nil, err
	}
	bodyContent, err := resp.GetBodyContent()
	if err != nil {
		return nil, err
	}
	var bucketAcl *BucketAcl
	err = json.Unmarshal(bodyContent, &bucketAcl)
	if err != nil {
		return nil, err
	}
	return bucketAcl, nil
}
func (c *Client) SetBucketAcl(bucketName string, bucketAcl BucketAcl, option *bce.SignOption) error {
	byteArray, err := util.ToJson(bucketAcl, "accessControlList")
	if err != nil {
		return err
	}
	params := map[string]string{"acl": ""}
	req, err := bce.NewRequest("PUT", c.GetURL(bucketName, "", params), bytes.NewReader(byteArray))
	if err != nil {
		return err
	}
	_, err = c.SendRequest(req, option)
	return err
}