github.com/aliyun/aliyun-oss-go-sdk@v3.0.2+incompatible/oss/bucket_test.go (about)

     1  package oss
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/hmac"
     7  	"crypto/sha1"
     8  	"crypto/tls"
     9  	"encoding/base64"
    10  	"encoding/json"
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  	"io/ioutil"
    15  	"math/rand"
    16  	"net/http"
    17  	"net/url"
    18  	"os"
    19  	"path/filepath"
    20  	"strconv"
    21  	"strings"
    22  	"time"
    23  
    24  	. "gopkg.in/check.v1"
    25  )
    26  
    27  type OssBucketSuite struct {
    28  	cloudBoxControlClient *Client
    29  	client                *Client
    30  	bucket                *Bucket
    31  	archiveBucket         *Bucket
    32  }
    33  
    34  var _ = Suite(&OssBucketSuite{})
    35  
    36  var (
    37  	pastDate   = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    38  	futureDate = time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
    39  )
    40  
    41  // SetUpSuite runs once when the suite starts running.
    42  func (s *OssBucketSuite) SetUpSuite(c *C) {
    43  	time.Sleep(timeoutInOperation)
    44  	if cloudboxControlEndpoint == "" {
    45  		client, err := New(endpoint, accessID, accessKey)
    46  		c.Assert(err, IsNil)
    47  		s.client = client
    48  
    49  		s.client.CreateBucket(bucketName)
    50  
    51  		err = s.client.CreateBucket(archiveBucketName, StorageClass(StorageArchive))
    52  		c.Assert(err, IsNil)
    53  
    54  		bucket, err := s.client.Bucket(bucketName)
    55  		c.Assert(err, IsNil)
    56  		s.bucket = bucket
    57  
    58  		archiveBucket, err := s.client.Bucket(archiveBucketName)
    59  		c.Assert(err, IsNil)
    60  		s.archiveBucket = archiveBucket
    61  
    62  		testLogger.Println("test bucket started")
    63  	} else {
    64  		client, err := New(endpoint, accessID, accessKey)
    65  		s.client = client
    66  		c.Assert(err, IsNil)
    67  
    68  		controlClient, err := New(cloudboxControlEndpoint, accessID, accessKey)
    69  		c.Assert(err, IsNil)
    70  		s.cloudBoxControlClient = controlClient
    71  
    72  		controlClient.CreateBucket(bucketName)
    73  		//err = controlClient.CreateBucket(archiveBucketName, StorageClass(StorageArchive))
    74  		//c.Assert(err, IsNil)
    75  
    76  		bucket, err := s.client.Bucket(bucketName)
    77  		c.Assert(err, IsNil)
    78  		s.bucket = bucket
    79  
    80  		//archiveBucket, err := s.client.Bucket(archiveBucketName)
    81  		//c.Assert(err, IsNil)
    82  		//s.archiveBucket = archiveBucket
    83  
    84  		testLogger.Println("test bucket started")
    85  	}
    86  	time.Sleep(timeoutInOperation)
    87  }
    88  
    89  // TearDownSuite runs before each test or benchmark starts running.
    90  func (s *OssBucketSuite) TearDownSuite(c *C) {
    91  	time.Sleep(timeoutInOperation)
    92  	for _, bucket := range []*Bucket{s.bucket, s.archiveBucket} {
    93  		// Delete multipart
    94  		keyMarker := KeyMarker("")
    95  		uploadIDMarker := UploadIDMarker("")
    96  		for {
    97  			lmu, err := bucket.ListMultipartUploads(keyMarker, uploadIDMarker)
    98  			c.Assert(err, IsNil)
    99  			for _, upload := range lmu.Uploads {
   100  				imur := InitiateMultipartUploadResult{Bucket: bucketName, Key: upload.Key, UploadID: upload.UploadID}
   101  				err = bucket.AbortMultipartUpload(imur)
   102  				c.Assert(err, IsNil)
   103  			}
   104  			keyMarker = KeyMarker(lmu.NextKeyMarker)
   105  			uploadIDMarker = UploadIDMarker(lmu.NextUploadIDMarker)
   106  			if !lmu.IsTruncated {
   107  				break
   108  			}
   109  		}
   110  
   111  		// Delete objects
   112  		marker := Marker("")
   113  		for {
   114  			lor, err := bucket.ListObjects(marker)
   115  			c.Assert(err, IsNil)
   116  			for _, object := range lor.Objects {
   117  				err = bucket.DeleteObject(object.Key)
   118  				c.Assert(err, IsNil)
   119  			}
   120  			marker = Marker(lor.NextMarker)
   121  			if !lor.IsTruncated {
   122  				break
   123  			}
   124  		}
   125  
   126  		// Delete bucket
   127  		if s.cloudBoxControlClient != nil {
   128  			err := s.cloudBoxControlClient.DeleteBucket(bucket.BucketName)
   129  			c.Assert(err, IsNil)
   130  		} else {
   131  			err := s.client.DeleteBucket(bucket.BucketName)
   132  			c.Assert(err, IsNil)
   133  		}
   134  	}
   135  	time.Sleep(timeoutInOperation)
   136  	testLogger.Println("test bucket completed")
   137  }
   138  
   139  // SetUpTest runs after each test or benchmark runs.
   140  func (s *OssBucketSuite) SetUpTest(c *C) {
   141  	err := removeTempFiles("../oss", ".jpg")
   142  	c.Assert(err, IsNil)
   143  }
   144  
   145  // TearDownTest runs once after all tests or benchmarks have finished running.
   146  func (s *OssBucketSuite) TearDownTest(c *C) {
   147  	err := removeTempFiles("../oss", ".jpg")
   148  	c.Assert(err, IsNil)
   149  
   150  	err = removeTempFiles("../oss", ".txt")
   151  	c.Assert(err, IsNil)
   152  
   153  	err = removeTempFiles("../oss", ".temp")
   154  	c.Assert(err, IsNil)
   155  
   156  	err = removeTempFiles("../oss", ".txt1")
   157  	c.Assert(err, IsNil)
   158  
   159  	err = removeTempFiles("../oss", ".txt2")
   160  	c.Assert(err, IsNil)
   161  }
   162  
   163  // TestPutObject
   164  func (s *OssBucketSuite) TestPutObjectOnly(c *C) {
   165  	objectName := objectNamePrefix + RandStr(8)
   166  	objectValue := "大江东去,浪淘尽,千古风流人物。 故垒西边,人道是、三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。" +
   167  		"遥想公谨当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间、樯橹灰飞烟灭。故国神游,多情应笑我,早生华发,人生如梦,一尊还酹江月。"
   168  
   169  	// Put string
   170  	var respHeader http.Header
   171  	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue), GetResponseHeader(&respHeader))
   172  	c.Assert(err, IsNil)
   173  
   174  	// Check
   175  	body, err := s.bucket.GetObject(objectName)
   176  	c.Assert(err, IsNil)
   177  	str, err := readBody(body)
   178  	c.Assert(err, IsNil)
   179  	c.Assert(str, Equals, objectValue)
   180  
   181  	acl, err := s.bucket.GetObjectACL(objectName)
   182  	c.Assert(err, IsNil)
   183  	testLogger.Println("aclRes:", acl)
   184  	c.Assert(acl.ACL, Equals, "default")
   185  
   186  	err = s.bucket.DeleteObject(objectName)
   187  	c.Assert(err, IsNil)
   188  
   189  	// Put bytes
   190  	err = s.bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
   191  	c.Assert(err, IsNil)
   192  
   193  	// Check
   194  	body, err = s.bucket.GetObject(objectName)
   195  	c.Assert(err, IsNil)
   196  	str, err = readBody(body)
   197  	c.Assert(err, IsNil)
   198  	c.Assert(str, Equals, objectValue)
   199  
   200  	err = s.bucket.DeleteObject(objectName)
   201  	c.Assert(err, IsNil)
   202  
   203  	// Put file
   204  	err = CreateFileAndWrite(objectName+".txt", []byte(objectValue))
   205  	c.Assert(err, IsNil)
   206  	fd, err := os.Open(objectName + ".txt")
   207  	c.Assert(err, IsNil)
   208  
   209  	err = s.bucket.PutObject(objectName, fd)
   210  	c.Assert(err, IsNil)
   211  	os.Remove(objectName + ".txt")
   212  
   213  	// Check
   214  	body, err = s.bucket.GetObject(objectName)
   215  	c.Assert(err, IsNil)
   216  	str, err = readBody(body)
   217  	c.Assert(err, IsNil)
   218  	c.Assert(str, Equals, objectValue)
   219  
   220  	err = s.bucket.DeleteObject(objectName)
   221  	c.Assert(err, IsNil)
   222  
   223  	// Put with properties
   224  	objectName = objectNamePrefix + RandStr(8)
   225  	options := []Option{
   226  		Expires(futureDate),
   227  		ObjectACL(ACLPublicRead),
   228  		Meta("myprop", "mypropval"),
   229  	}
   230  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue), options...)
   231  	c.Assert(err, IsNil)
   232  
   233  	// Check
   234  	body, err = s.bucket.GetObject(objectName)
   235  	c.Assert(err, IsNil)
   236  	str, err = readBody(body)
   237  	c.Assert(err, IsNil)
   238  	c.Assert(str, Equals, objectValue)
   239  
   240  	acl, err = s.bucket.GetObjectACL(objectName)
   241  	c.Assert(err, IsNil)
   242  	testLogger.Println("GetObjectACL:", acl)
   243  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
   244  
   245  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
   246  	c.Assert(err, IsNil)
   247  	testLogger.Println("GetObjectDetailedMeta:", meta)
   248  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
   249  
   250  	err = s.bucket.DeleteObject(objectName)
   251  	c.Assert(err, IsNil)
   252  }
   253  
   254  func (s *OssBucketSuite) SignURLTestFunc(c *C, authVersion AuthVersionType, extraHeaders []string) {
   255  	objectName := objectNamePrefix + RandStr(8)
   256  	objectValue := RandStr(20)
   257  
   258  	filePath := RandLowStr(10)
   259  	content := "复写object"
   260  	CreateFile(filePath, content, c)
   261  
   262  	notExistfilePath := RandLowStr(10)
   263  	os.Remove(notExistfilePath)
   264  
   265  	oldType := s.bucket.Client.Config.AuthVersion
   266  	oldHeaders := s.bucket.Client.Config.AdditionalHeaders
   267  
   268  	s.bucket.Client.Config.AuthVersion = authVersion
   269  	s.bucket.Client.Config.AdditionalHeaders = extraHeaders
   270  
   271  	// Sign URL for put
   272  	str, err := s.bucket.SignURL(objectName, HTTPPut, 60)
   273  	c.Assert(err, IsNil)
   274  
   275  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   276  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   277  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   278  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   279  	} else if s.bucket.Client.Config.AuthVersion == AuthV2 {
   280  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   281  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   282  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   283  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   284  	}
   285  
   286  	// Error put object with URL
   287  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue), ContentType("image/tiff"))
   288  	c.Assert(err, NotNil)
   289  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   290  
   291  	err = s.bucket.PutObjectFromFileWithURL(str, filePath, ContentType("image/tiff"))
   292  	c.Assert(err, NotNil)
   293  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   294  
   295  	// Put object with URL
   296  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   297  	c.Assert(err, IsNil)
   298  
   299  	acl, err := s.bucket.GetObjectACL(objectName)
   300  	c.Assert(err, IsNil)
   301  	c.Assert(acl.ACL, Equals, "default")
   302  
   303  	// Get object meta
   304  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
   305  	c.Assert(err, IsNil)
   306  	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "application/octet-stream")
   307  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "")
   308  
   309  	// Sign URL for function GetObjectWithURL
   310  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
   311  	c.Assert(err, IsNil)
   312  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   313  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   314  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   315  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   316  	} else {
   317  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   318  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   319  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   320  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   321  	}
   322  
   323  	// Get object with URL
   324  	body, err := s.bucket.GetObjectWithURL(str)
   325  	c.Assert(err, IsNil)
   326  	str, err = readBody(body)
   327  	c.Assert(err, IsNil)
   328  	c.Assert(str, Equals, objectValue)
   329  
   330  	// Sign URL for function PutObjectWithURL
   331  	options := []Option{
   332  		ObjectACL(ACLPublicRead),
   333  		Meta("myprop", "mypropval"),
   334  		ContentType("image/tiff"),
   335  		ResponseContentEncoding("deflate"),
   336  	}
   337  	str, err = s.bucket.SignURL(objectName, HTTPPut, 60, options...)
   338  	c.Assert(err, IsNil)
   339  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   340  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   341  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   342  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   343  	} else {
   344  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   345  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   346  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   347  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   348  	}
   349  
   350  	// Put object with URL from file
   351  	// Without option, error
   352  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   353  	c.Assert(err, NotNil)
   354  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   355  
   356  	err = s.bucket.PutObjectFromFileWithURL(str, filePath)
   357  	c.Assert(err, NotNil)
   358  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   359  
   360  	// With option, error file
   361  	err = s.bucket.PutObjectFromFileWithURL(str, notExistfilePath, options...)
   362  	c.Assert(err, NotNil)
   363  
   364  	// With option
   365  	err = s.bucket.PutObjectFromFileWithURL(str, filePath, options...)
   366  	c.Assert(err, IsNil)
   367  
   368  	// Get object meta
   369  	meta, err = s.bucket.GetObjectDetailedMeta(objectName)
   370  	c.Assert(err, IsNil)
   371  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
   372  	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "image/tiff")
   373  
   374  	acl, err = s.bucket.GetObjectACL(objectName)
   375  	c.Assert(err, IsNil)
   376  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
   377  
   378  	// Sign URL for function GetObjectToFileWithURL
   379  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
   380  	c.Assert(err, IsNil)
   381  
   382  	// Get object to file with URL
   383  	newFile := RandStr(10)
   384  	err = s.bucket.GetObjectToFileWithURL(str, newFile)
   385  	c.Assert(err, IsNil)
   386  	eq, err := compareFiles(filePath, newFile)
   387  	c.Assert(err, IsNil)
   388  	c.Assert(eq, Equals, true)
   389  	os.Remove(newFile)
   390  
   391  	// Get object to file error
   392  	err = s.bucket.GetObjectToFileWithURL(str, newFile, options...)
   393  	c.Assert(err, NotNil)
   394  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   395  	_, err = os.Stat(newFile)
   396  	c.Assert(err, NotNil)
   397  
   398  	// Get object error
   399  	body, err = s.bucket.GetObjectWithURL(str, options...)
   400  	c.Assert(err, NotNil)
   401  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   402  	c.Assert(body, IsNil)
   403  
   404  	// Sign URL for function GetObjectToFileWithURL
   405  	options = []Option{
   406  		Expires(futureDate),
   407  		ObjectACL(ACLPublicRead),
   408  		Meta("myprop", "mypropval"),
   409  		ContentType("image/tiff"),
   410  		ResponseContentEncoding("deflate"),
   411  	}
   412  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60, options...)
   413  	c.Assert(err, IsNil)
   414  
   415  	// Get object to file with URL and options
   416  	err = s.bucket.GetObjectToFileWithURL(str, newFile, options...)
   417  	c.Assert(err, IsNil)
   418  	eq, err = compareFiles(filePath, newFile)
   419  	c.Assert(err, IsNil)
   420  	c.Assert(eq, Equals, true)
   421  	os.Remove(newFile)
   422  
   423  	// Get object to file error
   424  	err = s.bucket.GetObjectToFileWithURL(str, newFile)
   425  	c.Assert(err, NotNil)
   426  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   427  	_, err = os.Stat(newFile)
   428  	c.Assert(err, NotNil)
   429  
   430  	// Get object error
   431  	body, err = s.bucket.GetObjectWithURL(str)
   432  	c.Assert(err, NotNil)
   433  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   434  	c.Assert(body, IsNil)
   435  
   436  	err = s.bucket.PutObjectFromFile(objectName, "../sample/The Go Programming Language.html")
   437  	c.Assert(err, IsNil)
   438  	str, err = s.bucket.SignURL(objectName, HTTPGet, 3600, AcceptEncoding("gzip"))
   439  	c.Assert(err, IsNil)
   440  	s.bucket.GetObjectToFileWithURL(str, newFile)
   441  	c.Assert(err, IsNil)
   442  
   443  	os.Remove(filePath)
   444  	os.Remove(newFile)
   445  
   446  	// Sign URL error
   447  	str, err = s.bucket.SignURL(objectName, HTTPGet, -1)
   448  	c.Assert(err, NotNil)
   449  
   450  	err = s.bucket.DeleteObject(objectName)
   451  	c.Assert(err, IsNil)
   452  
   453  	// Invalid URL parse
   454  	str = RandStr(20)
   455  
   456  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   457  	c.Assert(err, NotNil)
   458  
   459  	err = s.bucket.GetObjectToFileWithURL(str, newFile)
   460  	c.Assert(err, NotNil)
   461  
   462  	s.bucket.Client.Config.AuthVersion = oldType
   463  	s.bucket.Client.Config.AdditionalHeaders = oldHeaders
   464  }
   465  
   466  func (s *OssBucketSuite) TestSignURLWithSignV4(c *C) {
   467  	client, err := New(endpoint, accessID, accessKey, Region(envRegion), AuthVersion(AuthV4))
   468  	c.Assert(err, IsNil)
   469  	bucketName := bucketNamePrefix + RandLowStr(10)
   470  	err = client.CreateBucket(bucketName)
   471  	c.Assert(err, IsNil)
   472  	bucket, err := client.Bucket(bucketName)
   473  	c.Assert(err, IsNil)
   474  
   475  	objectName := objectNamePrefix + RandStr(8)
   476  	objectValue := RandStr(20)
   477  	filePath := RandLowStr(10)
   478  	content := "复写object"
   479  	CreateFile(filePath, content, c)
   480  	notExistfilePath := RandLowStr(10)
   481  	os.Remove(notExistfilePath)
   482  
   483  	// Sign URL for put
   484  	str, err := bucket.SignURL(objectName, HTTPPut, 60)
   485  	c.Assert(err, IsNil)
   486  	c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS4-HMAC-SHA256"), Equals, true)
   487  	c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   488  	c.Assert(strings.Contains(str, HTTPParamDate+"="), Equals, true)
   489  	c.Assert(strings.Contains(str, HTTPParamCredential+"="), Equals, true)
   490  	c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   491  	// Error put object with URL
   492  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue), ContentType("image/tiff"))
   493  	c.Assert(err, NotNil)
   494  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   495  	err = bucket.PutObjectFromFileWithURL(str, filePath, ContentType("image/tiff"))
   496  	c.Assert(err, NotNil)
   497  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   498  	// Put object with URL
   499  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   500  	c.Assert(err, IsNil)
   501  	acl, err := bucket.GetObjectACL(objectName)
   502  	c.Assert(err, IsNil)
   503  	c.Assert(acl.ACL, Equals, "default")
   504  	// Get object meta
   505  	meta, err := bucket.GetObjectDetailedMeta(objectName)
   506  	c.Assert(err, IsNil)
   507  	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "application/octet-stream")
   508  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "")
   509  	// Sign URL for function GetObjectWithURL
   510  	str, err = bucket.SignURL(objectName, HTTPGet, 60)
   511  	c.Assert(err, IsNil)
   512  	c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS4-HMAC-SHA256"), Equals, true)
   513  	c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   514  	c.Assert(strings.Contains(str, HTTPParamDate+"="), Equals, true)
   515  	c.Assert(strings.Contains(str, HTTPParamCredential+"="), Equals, true)
   516  	c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   517  	// Get object with URL
   518  	body, err := bucket.GetObjectWithURL(str)
   519  	c.Assert(err, IsNil)
   520  	str, err = readBody(body)
   521  	c.Assert(err, IsNil)
   522  	c.Assert(str, Equals, objectValue)
   523  	// Sign URL for function PutObjectWithURL
   524  	options := []Option{
   525  		ObjectACL(ACLPublicRead),
   526  		Meta("myprop", "mypropval"),
   527  		ContentType("image/tiff"),
   528  		ResponseContentEncoding("deflate"),
   529  	}
   530  	str, err = bucket.SignURL(objectName, HTTPPut, 600, options...)
   531  	c.Assert(err, IsNil)
   532  	c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS4-HMAC-SHA256"), Equals, true)
   533  	c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   534  	c.Assert(strings.Contains(str, HTTPParamDate+"="), Equals, true)
   535  	c.Assert(strings.Contains(str, HTTPParamCredential+"="), Equals, true)
   536  	c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   537  	// Put object with URL from file
   538  	// Without option, error
   539  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   540  	c.Assert(err, NotNil)
   541  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   542  
   543  	err = bucket.PutObjectFromFileWithURL(str, filePath)
   544  	c.Assert(err, NotNil)
   545  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   546  
   547  	// With option, error file
   548  	err = bucket.PutObjectFromFileWithURL(str, notExistfilePath, options...)
   549  	c.Assert(err, NotNil)
   550  
   551  	// With option
   552  	err = bucket.PutObjectFromFileWithURL(str, filePath, options...)
   553  	c.Assert(err, IsNil)
   554  
   555  	// Get object meta
   556  	meta, err = bucket.GetObjectDetailedMeta(objectName)
   557  	c.Assert(err, IsNil)
   558  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
   559  	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "image/tiff")
   560  
   561  	acl, err = bucket.GetObjectACL(objectName)
   562  	c.Assert(err, IsNil)
   563  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
   564  
   565  	// Sign URL for function GetObjectToFileWithURL
   566  	str, err = bucket.SignURL(objectName, HTTPGet, 60)
   567  	c.Assert(err, IsNil)
   568  
   569  	// Get object to file with URL
   570  	newFile := RandStr(10)
   571  	err = bucket.GetObjectToFileWithURL(str, newFile)
   572  	c.Assert(err, IsNil)
   573  	eq, err := compareFiles(filePath, newFile)
   574  	c.Assert(err, IsNil)
   575  	c.Assert(eq, Equals, true)
   576  	os.Remove(newFile)
   577  
   578  	// Get object to file error
   579  	err = bucket.GetObjectToFileWithURL(str, newFile, options...)
   580  	c.Assert(err, NotNil)
   581  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   582  	_, err = os.Stat(newFile)
   583  	c.Assert(err, NotNil)
   584  
   585  	// Get object error
   586  	body, err = bucket.GetObjectWithURL(str, options...)
   587  	c.Assert(err, NotNil)
   588  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   589  	c.Assert(body, IsNil)
   590  
   591  	// Sign URL for function GetObjectToFileWithURL
   592  	options = []Option{
   593  		Expires(futureDate),
   594  		ObjectACL(ACLPublicRead),
   595  		Meta("myprop", "mypropval"),
   596  		ContentType("image/tiff"),
   597  		ResponseContentEncoding("deflate"),
   598  	}
   599  	str, err = bucket.SignURL(objectName, HTTPGet, 60, options...)
   600  	c.Assert(err, IsNil)
   601  
   602  	// Get object to file with URL and options
   603  	err = bucket.GetObjectToFileWithURL(str, newFile, options...)
   604  	c.Assert(err, IsNil)
   605  	eq, err = compareFiles(filePath, newFile)
   606  	c.Assert(err, IsNil)
   607  	c.Assert(eq, Equals, true)
   608  	os.Remove(newFile)
   609  
   610  	// Get object to file error
   611  	err = bucket.GetObjectToFileWithURL(str, newFile)
   612  	c.Assert(err, NotNil)
   613  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   614  	_, err = os.Stat(newFile)
   615  	c.Assert(err, NotNil)
   616  
   617  	// Get object error
   618  	body, err = bucket.GetObjectWithURL(str)
   619  	c.Assert(err, NotNil)
   620  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   621  	c.Assert(body, IsNil)
   622  
   623  	err = bucket.PutObjectFromFile(objectName, "../sample/The Go Programming Language.html")
   624  	c.Assert(err, IsNil)
   625  	str, err = bucket.SignURL(objectName, HTTPGet, 3600, AcceptEncoding("gzip"))
   626  	c.Assert(err, IsNil)
   627  	bucket.GetObjectToFileWithURL(str, newFile)
   628  	c.Assert(err, IsNil)
   629  
   630  	os.Remove(filePath)
   631  	os.Remove(newFile)
   632  
   633  	// Sign URL error
   634  	str, err = bucket.SignURL(objectName, HTTPGet, -1)
   635  	c.Assert(err, NotNil)
   636  
   637  	err = bucket.DeleteObject(objectName)
   638  	c.Assert(err, IsNil)
   639  
   640  	// Invalid URL parse
   641  	str = RandStr(20)
   642  
   643  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   644  	c.Assert(err, NotNil)
   645  
   646  	err = bucket.GetObjectToFileWithURL(str, newFile)
   647  	c.Assert(err, NotNil)
   648  	ForceDeleteBucket(client, bucketName, c)
   649  }
   650  
   651  func (s *OssBucketSuite) TestSignURLWithSignV4WithToken(c *C) {
   652  	resp, err := stsAssumeRole(stsaccessID, stsaccessKey, stsARN, "oss_test_sess", 1800)
   653  	c.Assert(err, IsNil)
   654  	fmt.Print(resp)
   655  
   656  	client, err := New(endpoint, resp.Credentials.AccessKeyId, resp.Credentials.AccessKeySecret,
   657  		SecurityToken(resp.Credentials.SecurityToken), Region(envRegion), AuthVersion(AuthV4))
   658  	c.Assert(err, IsNil)
   659  
   660  	c.Assert(err, IsNil)
   661  	bucketName := bucketNamePrefix + RandLowStr(10)
   662  	err = client.CreateBucket(bucketName)
   663  	c.Assert(err, IsNil)
   664  	bucket, err := client.Bucket(bucketName)
   665  	c.Assert(err, IsNil)
   666  
   667  	objectName := objectNamePrefix + RandStr(8)
   668  	objectValue := RandStr(20)
   669  	filePath := RandLowStr(10)
   670  	content := "复写object"
   671  	CreateFile(filePath, content, c)
   672  	notExistfilePath := RandLowStr(10)
   673  	os.Remove(notExistfilePath)
   674  
   675  	// Sign URL for put
   676  	str, err := bucket.SignURL(objectName, HTTPPut, 60)
   677  	c.Assert(err, IsNil)
   678  	c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS4-HMAC-SHA256"), Equals, true)
   679  	c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   680  	c.Assert(strings.Contains(str, HTTPParamDate+"="), Equals, true)
   681  	c.Assert(strings.Contains(str, HTTPParamCredential+"="), Equals, true)
   682  	c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   683  	// Error put object with URL
   684  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue), ContentType("image/tiff"))
   685  	c.Assert(err, NotNil)
   686  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   687  	err = bucket.PutObjectFromFileWithURL(str, filePath, ContentType("image/tiff"))
   688  	c.Assert(err, NotNil)
   689  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   690  	// Put object with URL
   691  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   692  	c.Assert(err, IsNil)
   693  	acl, err := bucket.GetObjectACL(objectName)
   694  	c.Assert(err, IsNil)
   695  	c.Assert(acl.ACL, Equals, "default")
   696  	// Get object meta
   697  	meta, err := bucket.GetObjectDetailedMeta(objectName)
   698  	c.Assert(err, IsNil)
   699  	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "application/octet-stream")
   700  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "")
   701  	// Sign URL for function GetObjectWithURL
   702  	str, err = bucket.SignURL(objectName, HTTPGet, 60)
   703  	c.Assert(err, IsNil)
   704  	c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS4-HMAC-SHA256"), Equals, true)
   705  	c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   706  	c.Assert(strings.Contains(str, HTTPParamDate+"="), Equals, true)
   707  	c.Assert(strings.Contains(str, HTTPParamCredential+"="), Equals, true)
   708  	c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   709  	// Get object with URL
   710  	body, err := bucket.GetObjectWithURL(str)
   711  	c.Assert(err, IsNil)
   712  	str, err = readBody(body)
   713  	c.Assert(err, IsNil)
   714  	c.Assert(str, Equals, objectValue)
   715  	// Sign URL for function PutObjectWithURL
   716  	options := []Option{
   717  		ObjectACL(ACLPublicRead),
   718  		Meta("myprop", "mypropval"),
   719  		ContentType("image/tiff"),
   720  		ResponseContentEncoding("deflate"),
   721  	}
   722  	str, err = bucket.SignURL(objectName, HTTPPut, 60, options...)
   723  	c.Assert(err, IsNil)
   724  	c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS4-HMAC-SHA256"), Equals, true)
   725  	c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   726  	c.Assert(strings.Contains(str, HTTPParamDate+"="), Equals, true)
   727  	c.Assert(strings.Contains(str, HTTPParamCredential+"="), Equals, true)
   728  	c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   729  	// Put object with URL from file
   730  	// Without option, error
   731  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   732  	c.Assert(err, NotNil)
   733  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   734  
   735  	err = bucket.PutObjectFromFileWithURL(str, filePath)
   736  	c.Assert(err, NotNil)
   737  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   738  
   739  	// With option, error file
   740  	err = bucket.PutObjectFromFileWithURL(str, notExistfilePath, options...)
   741  	c.Assert(err, NotNil)
   742  
   743  	// With option
   744  	err = bucket.PutObjectFromFileWithURL(str, filePath, options...)
   745  	c.Assert(err, IsNil)
   746  
   747  	// Get object meta
   748  	meta, err = bucket.GetObjectDetailedMeta(objectName)
   749  	c.Assert(err, IsNil)
   750  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
   751  	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "image/tiff")
   752  
   753  	acl, err = bucket.GetObjectACL(objectName)
   754  	c.Assert(err, IsNil)
   755  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
   756  
   757  	// Sign URL for function GetObjectToFileWithURL
   758  	str, err = bucket.SignURL(objectName, HTTPGet, 60)
   759  	c.Assert(err, IsNil)
   760  
   761  	// Get object to file with URL
   762  	newFile := RandStr(10)
   763  	err = bucket.GetObjectToFileWithURL(str, newFile)
   764  	c.Assert(err, IsNil)
   765  	eq, err := compareFiles(filePath, newFile)
   766  	c.Assert(err, IsNil)
   767  	c.Assert(eq, Equals, true)
   768  	os.Remove(newFile)
   769  
   770  	// Get object to file error
   771  	err = bucket.GetObjectToFileWithURL(str, newFile, options...)
   772  	c.Assert(err, NotNil)
   773  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   774  	_, err = os.Stat(newFile)
   775  	c.Assert(err, NotNil)
   776  
   777  	// Get object error
   778  	body, err = bucket.GetObjectWithURL(str, options...)
   779  	c.Assert(err, NotNil)
   780  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   781  	c.Assert(body, IsNil)
   782  
   783  	// Sign URL for function GetObjectToFileWithURL
   784  	options = []Option{
   785  		Expires(futureDate),
   786  		ObjectACL(ACLPublicRead),
   787  		Meta("myprop", "mypropval"),
   788  		ContentType("image/tiff"),
   789  		ResponseContentEncoding("deflate"),
   790  	}
   791  	str, err = bucket.SignURL(objectName, HTTPGet, 60, options...)
   792  	c.Assert(err, IsNil)
   793  
   794  	// Get object to file with URL and options
   795  	err = bucket.GetObjectToFileWithURL(str, newFile, options...)
   796  	c.Assert(err, IsNil)
   797  	eq, err = compareFiles(filePath, newFile)
   798  	c.Assert(err, IsNil)
   799  	c.Assert(eq, Equals, true)
   800  	os.Remove(newFile)
   801  
   802  	// Get object to file error
   803  	err = bucket.GetObjectToFileWithURL(str, newFile)
   804  	c.Assert(err, NotNil)
   805  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   806  	_, err = os.Stat(newFile)
   807  	c.Assert(err, NotNil)
   808  
   809  	// Get object error
   810  	body, err = bucket.GetObjectWithURL(str)
   811  	c.Assert(err, NotNil)
   812  	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
   813  	c.Assert(body, IsNil)
   814  
   815  	err = bucket.PutObjectFromFile(objectName, "../sample/The Go Programming Language.html")
   816  	c.Assert(err, IsNil)
   817  	str, err = bucket.SignURL(objectName, HTTPGet, 3600, AcceptEncoding("gzip"))
   818  	c.Assert(err, IsNil)
   819  	bucket.GetObjectToFileWithURL(str, newFile)
   820  	c.Assert(err, IsNil)
   821  
   822  	os.Remove(filePath)
   823  	os.Remove(newFile)
   824  
   825  	// Sign URL error
   826  	str, err = bucket.SignURL(objectName, HTTPGet, -1)
   827  	c.Assert(err, NotNil)
   828  
   829  	err = bucket.DeleteObject(objectName)
   830  	c.Assert(err, IsNil)
   831  
   832  	// Invalid URL parse
   833  	str = RandStr(20)
   834  
   835  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   836  	c.Assert(err, NotNil)
   837  
   838  	err = bucket.GetObjectToFileWithURL(str, newFile)
   839  	c.Assert(err, NotNil)
   840  
   841  	ForceDeleteBucket(client, bucketName, c)
   842  }
   843  
   844  func (s *OssBucketSuite) TestSignURL(c *C) {
   845  	s.SignURLTestFunc(c, AuthV1, []string{})
   846  	s.SignURLTestFunc(c, AuthV2, []string{})
   847  	s.SignURLTestFunc(c, AuthV2, []string{"host", "range", "user-agent"})
   848  }
   849  
   850  func (s *OssBucketSuite) SignURLWithEscapedKeyTestFunc(c *C, authVersion AuthVersionType, extraHeaders []string) {
   851  	// Key with '/'
   852  	objectName := "zyimg/86/e8/653b5dc97bb0022051a84c632bc4"
   853  	objectValue := "弃我去者,昨日之日不可留;乱我心者,今日之日多烦忧。长风万里送秋雁,对此可以酣高楼。蓬莱文章建安骨,中间小谢又清发。" +
   854  		"俱怀逸兴壮思飞,欲上青天揽明月。抽刀断水水更流,举杯销愁愁更愁。人生在世不称意,明朝散发弄扁舟。"
   855  
   856  	oldType := s.bucket.Client.Config.AuthVersion
   857  	oldHeaders := s.bucket.Client.Config.AdditionalHeaders
   858  
   859  	s.bucket.Client.Config.AuthVersion = authVersion
   860  	s.bucket.Client.Config.AdditionalHeaders = extraHeaders
   861  
   862  	// Sign URL for function PutObjectWithURL
   863  	str, err := s.bucket.SignURL(objectName, HTTPPut, 60)
   864  	c.Assert(err, IsNil)
   865  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   866  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   867  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   868  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   869  	} else {
   870  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   871  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   872  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   873  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   874  	}
   875  
   876  	// Put object with URL
   877  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   878  	c.Assert(err, IsNil)
   879  
   880  	// Sign URL for function GetObjectWithURL
   881  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
   882  	c.Assert(err, IsNil)
   883  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   884  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   885  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   886  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   887  	} else {
   888  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   889  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   890  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   891  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   892  	}
   893  
   894  	// Get object with URL
   895  	body, err := s.bucket.GetObjectWithURL(str)
   896  	c.Assert(err, IsNil)
   897  	str, err = readBody(body)
   898  	c.Assert(err, IsNil)
   899  	c.Assert(str, Equals, objectValue)
   900  
   901  	// Key with escaped chars
   902  	objectName = "<>[]()`?.,!@#$%^&'/*-_=+~:;"
   903  
   904  	// Sign URL for funciton PutObjectWithURL
   905  	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
   906  	c.Assert(err, IsNil)
   907  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   908  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   909  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   910  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   911  	} else {
   912  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   913  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   914  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   915  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   916  	}
   917  
   918  	// Put object with URL
   919  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   920  	c.Assert(err, IsNil)
   921  
   922  	// Sign URL for function GetObjectWithURL
   923  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
   924  	c.Assert(err, IsNil)
   925  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   926  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   927  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   928  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   929  	} else {
   930  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   931  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   932  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   933  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   934  	}
   935  
   936  	// Get object with URL
   937  	body, err = s.bucket.GetObjectWithURL(str)
   938  	c.Assert(err, IsNil)
   939  	str, err = readBody(body)
   940  	c.Assert(err, IsNil)
   941  	c.Assert(str, Equals, objectValue)
   942  
   943  	// Key with Chinese chars
   944  	objectName = "风吹柳花满店香,吴姬压酒劝客尝。金陵子弟来相送,欲行不行各尽觞。请君试问东流水,别意与之谁短长。"
   945  
   946  	// Sign URL for function PutObjectWithURL
   947  	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
   948  	c.Assert(err, IsNil)
   949  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   950  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   951  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   952  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   953  	} else {
   954  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   955  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   956  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   957  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   958  	}
   959  
   960  	// Put object with URL
   961  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   962  	c.Assert(err, IsNil)
   963  
   964  	// Sign URL for get function GetObjectWithURL
   965  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
   966  	c.Assert(err, IsNil)
   967  	if s.bucket.Client.Config.AuthVersion == AuthV1 {
   968  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
   969  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
   970  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
   971  	} else {
   972  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
   973  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
   974  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
   975  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
   976  	}
   977  
   978  	// Get object with URL
   979  	body, err = s.bucket.GetObjectWithURL(str)
   980  	c.Assert(err, IsNil)
   981  	str, err = readBody(body)
   982  	c.Assert(err, IsNil)
   983  	c.Assert(str, Equals, objectValue)
   984  
   985  	// Key
   986  	objectName = "test/此情无计可消除/才下眉头/却上 心头/。,;:‘’“”?()『』【】《》!@#¥%……&×/test+ =-_*&^%$#@!`~[]{}()<>|\\/?.,;.txt"
   987  
   988  	// Sign URL for function PutObjectWithURL
   989  	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
   990  	c.Assert(err, IsNil)
   991  
   992  	// Put object with URL
   993  	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
   994  	c.Assert(err, IsNil)
   995  
   996  	// Sign URL for function GetObjectWithURL
   997  	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
   998  	c.Assert(err, IsNil)
   999  
  1000  	// Get object with URL
  1001  	body, err = s.bucket.GetObjectWithURL(str)
  1002  	c.Assert(err, IsNil)
  1003  	str, err = readBody(body)
  1004  	c.Assert(err, IsNil)
  1005  	c.Assert(str, Equals, objectValue)
  1006  
  1007  	// Put object
  1008  	err = s.bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
  1009  	c.Assert(err, IsNil)
  1010  
  1011  	// Get object
  1012  	body, err = s.bucket.GetObject(objectName)
  1013  	c.Assert(err, IsNil)
  1014  	str, err = readBody(body)
  1015  	c.Assert(err, IsNil)
  1016  	c.Assert(str, Equals, objectValue)
  1017  
  1018  	// Delete object
  1019  	err = s.bucket.DeleteObject(objectName)
  1020  	c.Assert(err, IsNil)
  1021  
  1022  	s.bucket.Client.Config.AuthVersion = oldType
  1023  	s.bucket.Client.Config.AdditionalHeaders = oldHeaders
  1024  }
  1025  
  1026  func (s *OssBucketSuite) TestSignURLWithEscapedKey(c *C) {
  1027  	s.SignURLWithEscapedKeyTestFunc(c, AuthV1, []string{})
  1028  	s.SignURLWithEscapedKeyTestFunc(c, AuthV2, []string{})
  1029  	s.SignURLWithEscapedKeyTestFunc(c, AuthV2, []string{"host", "range", "user-agent"})
  1030  }
  1031  
  1032  func (s *OssBucketSuite) TestSignURLWithEmptyObjectName(c *C) {
  1033  	client, err := New(endpoint, accessID, accessKey)
  1034  	c.Assert(err, IsNil)
  1035  
  1036  	bucketName := bucketNamePrefix + RandLowStr(6)
  1037  	err = client.CreateBucket(bucketName)
  1038  	c.Assert(err, IsNil)
  1039  
  1040  	bucket, err := client.Bucket(bucketName)
  1041  	c.Assert(err, IsNil)
  1042  	_, err = bucket.SignURL("", "GET", 3600)
  1043  	c.Assert(err, NotNil)
  1044  	ForceDeleteBucket(client, bucketName, c)
  1045  }
  1046  
  1047  func (s *OssBucketSuite) SignURLWithEscapedKeyAndPorxyTestFunc(c *C, authVersion AuthVersionType, extraHeaders []string) {
  1048  	// Key with '/'
  1049  	objectName := "zyimg/86/e8/653b5dc97bb0022051a84c632bc4"
  1050  	objectValue := "弃我去者,昨日之日不可留;乱我心者,今日之日多烦忧。长风万里送秋雁,对此可以酣高楼。蓬莱文章建安骨,中间小谢又清发。" +
  1051  		"俱怀逸兴壮思飞,欲上青天揽明月。抽刀断水水更流,举杯销愁愁更愁。人生在世不称意,明朝散发弄扁舟。"
  1052  
  1053  	options := []ClientOption{
  1054  		AuthProxy(proxyHost, proxyUser, proxyPasswd),
  1055  		AuthVersion(authVersion),
  1056  		AdditionalHeaders(extraHeaders),
  1057  	}
  1058  
  1059  	client, err := New(endpoint, accessID, accessKey, options...)
  1060  	bucket, err := client.Bucket(bucketName)
  1061  
  1062  	// Sign URL for put
  1063  	str, err := bucket.SignURL(objectName, HTTPPut, 60)
  1064  	c.Assert(err, IsNil)
  1065  	if bucket.Client.Config.AuthVersion == AuthV1 {
  1066  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
  1067  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
  1068  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
  1069  	} else {
  1070  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
  1071  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
  1072  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
  1073  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
  1074  	}
  1075  
  1076  	// Put object with URL
  1077  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
  1078  	c.Assert(err, IsNil)
  1079  
  1080  	// Sign URL for function GetObjectWithURL
  1081  	str, err = bucket.SignURL(objectName, HTTPGet, 60)
  1082  	c.Assert(err, IsNil)
  1083  	if bucket.Client.Config.AuthVersion == AuthV1 {
  1084  		c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
  1085  		c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
  1086  		c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
  1087  	} else {
  1088  		c.Assert(strings.Contains(str, HTTPParamSignatureVersion+"=OSS2"), Equals, true)
  1089  		c.Assert(strings.Contains(str, HTTPParamExpiresV2+"="), Equals, true)
  1090  		c.Assert(strings.Contains(str, HTTPParamAccessKeyIDV2+"="), Equals, true)
  1091  		c.Assert(strings.Contains(str, HTTPParamSignatureV2+"="), Equals, true)
  1092  	}
  1093  
  1094  	// Get object with URL
  1095  	body, err := bucket.GetObjectWithURL(str)
  1096  	c.Assert(err, IsNil)
  1097  	str, err = readBody(body)
  1098  	c.Assert(err, IsNil)
  1099  	c.Assert(str, Equals, objectValue)
  1100  
  1101  	// Key with Chinese chars
  1102  	objectName = "test/此情无计可消除/才下眉头/却上 心头/。,;:‘’“”?()『』【】《》!@#¥%……&×/test+ =-_*&^%$#@!`~[]{}()<>|\\/?.,;.txt"
  1103  
  1104  	// Sign URL for function PutObjectWithURL
  1105  	str, err = bucket.SignURL(objectName, HTTPPut, 60)
  1106  	c.Assert(err, IsNil)
  1107  
  1108  	// Put object with URL
  1109  	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
  1110  	c.Assert(err, IsNil)
  1111  
  1112  	// Sign URL for function GetObjectWithURL
  1113  	str, err = bucket.SignURL(objectName, HTTPGet, 60)
  1114  	c.Assert(err, IsNil)
  1115  
  1116  	// Get object with URL
  1117  	body, err = bucket.GetObjectWithURL(str)
  1118  	c.Assert(err, IsNil)
  1119  	str, err = readBody(body)
  1120  	c.Assert(err, IsNil)
  1121  	c.Assert(str, Equals, objectValue)
  1122  
  1123  	// Put object
  1124  	err = bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
  1125  	c.Assert(err, IsNil)
  1126  
  1127  	// Get object
  1128  	body, err = bucket.GetObject(objectName)
  1129  	c.Assert(err, IsNil)
  1130  	str, err = readBody(body)
  1131  	c.Assert(err, IsNil)
  1132  	c.Assert(str, Equals, objectValue)
  1133  
  1134  	// Delete object
  1135  	err = bucket.DeleteObject(objectName)
  1136  	c.Assert(err, IsNil)
  1137  }
  1138  
  1139  func (s *OssBucketSuite) TestSignURLWithEscapedKeyAndPorxy(c *C) {
  1140  	s.SignURLWithEscapedKeyAndPorxyTestFunc(c, AuthV1, []string{})
  1141  	s.SignURLWithEscapedKeyAndPorxyTestFunc(c, AuthV2, []string{})
  1142  	s.SignURLWithEscapedKeyAndPorxyTestFunc(c, AuthV2, []string{"host", "range", "user-agent"})
  1143  }
  1144  
  1145  func (s *OssBucketSuite) TestQueryStringAuthV2(c *C) {
  1146  	client, err := New(endpoint, accessID, accessKey)
  1147  	c.Assert(err, IsNil)
  1148  
  1149  	// set oss v2 signatrue
  1150  	client.Config.AuthVersion = AuthV2
  1151  	bucketName := bucketNamePrefix + RandLowStr(6)
  1152  	err = client.CreateBucket(bucketName)
  1153  	c.Assert(err, IsNil)
  1154  
  1155  	bucket, err := client.Bucket(bucketName)
  1156  
  1157  	// build QueryString
  1158  	QueryKey1 := "abc"
  1159  	QueryKey2 := "|abc"
  1160  	c.Assert(strings.Compare(QueryKey1, QueryKey2) < 0, Equals, true)
  1161  	c.Assert(strings.Compare(url.QueryEscape(QueryKey1), url.QueryEscape(QueryKey2)) > 0, Equals, true)
  1162  
  1163  	options := []Option{}
  1164  	params := map[string]interface{}{}
  1165  	params[QueryKey1] = "queryValue1"
  1166  	params[QueryKey2] = "queryValue2"
  1167  	objectKey := objectNamePrefix + RandStr(8)
  1168  	resp, _ := bucket.do("HEAD", objectKey, params, options, nil, nil)
  1169  
  1170  	// object not exist,no signature error
  1171  	c.Assert(resp.StatusCode, Equals, 404)
  1172  	ForceDeleteBucket(client, bucketName, c)
  1173  }
  1174  func (s *OssBucketSuite) TestQueryStringAuthV4(c *C) {
  1175  	// set oss v4 signatrue
  1176  	options := []ClientOption{
  1177  		Region(envRegion),
  1178  		AuthVersion(AuthV4),
  1179  	}
  1180  
  1181  	client, err := New(endpoint, accessID, accessKey, options...)
  1182  	c.Assert(err, IsNil)
  1183  
  1184  	bucketName := bucketNamePrefix + RandLowStr(6)
  1185  	err = client.CreateBucket(bucketName)
  1186  	c.Assert(err, IsNil)
  1187  
  1188  	bucket, _ := client.Bucket(bucketName)
  1189  
  1190  	// build QueryString
  1191  	QueryKey1 := "abc"
  1192  	QueryKey2 := "|abc"
  1193  	c.Assert(strings.Compare(QueryKey1, QueryKey2) < 0, Equals, true)
  1194  	c.Assert(strings.Compare(url.QueryEscape(QueryKey1), url.QueryEscape(QueryKey2)) > 0, Equals, true)
  1195  
  1196  	bucketOptions := []Option{}
  1197  	params := map[string]interface{}{}
  1198  	params[QueryKey1] = "queryValue1"
  1199  	params[QueryKey2] = "queryValue2"
  1200  	objectKey := objectNamePrefix + RandStr(8)
  1201  	resp, _ := bucket.do("HEAD", objectKey, params, bucketOptions, nil, nil)
  1202  
  1203  	// object not exist,no signature error
  1204  	c.Assert(resp.StatusCode, Equals, 404)
  1205  	ForceDeleteBucket(client, bucketName, c)
  1206  }
  1207  
  1208  func (s *OssBucketSuite) TestQueryStringAuthV4_AdditionalHeader(c *C) {
  1209  	// set oss v4 signatrue
  1210  	options := []ClientOption{
  1211  		Region(envRegion),
  1212  		AuthVersion(AuthV4),
  1213  		AdditionalHeaders([]string{"Date"}),
  1214  	}
  1215  
  1216  	client, err := New(endpoint, accessID, accessKey, options...)
  1217  	c.Assert(err, IsNil)
  1218  
  1219  	bucketName := bucketNamePrefix + RandLowStr(6)
  1220  	err = client.CreateBucket(bucketName)
  1221  	c.Assert(err, IsNil)
  1222  
  1223  	bucket, _ := client.Bucket(bucketName)
  1224  	object := RandLowStr(6) + "+=/123/abc?key=value"
  1225  
  1226  	err = bucket.PutObject(object, strings.NewReader(""))
  1227  	c.Assert(err, IsNil)
  1228  	ForceDeleteBucket(client, bucketName, c)
  1229  }
  1230  
  1231  // TestPutObjectType
  1232  func (s *OssBucketSuite) TestPutObjectType(c *C) {
  1233  	objectName := objectNamePrefix + RandStr(8)
  1234  	objectValue := "乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。"
  1235  
  1236  	// Put
  1237  	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  1238  	c.Assert(err, IsNil)
  1239  
  1240  	// Check
  1241  	body, err := s.bucket.GetObject(objectName)
  1242  	c.Assert(err, IsNil)
  1243  	str, err := readBody(body)
  1244  	c.Assert(err, IsNil)
  1245  	c.Assert(str, Equals, objectValue)
  1246  
  1247  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  1248  	c.Assert(err, IsNil)
  1249  	c.Assert(meta.Get("Content-Type"), Equals, "application/octet-stream")
  1250  
  1251  	err = s.bucket.DeleteObject(objectName)
  1252  	c.Assert(err, IsNil)
  1253  
  1254  	// Put
  1255  	err = s.bucket.PutObject(objectName+".txt", strings.NewReader(objectValue))
  1256  	c.Assert(err, IsNil)
  1257  
  1258  	meta, err = s.bucket.GetObjectDetailedMeta(objectName + ".txt")
  1259  	c.Assert(err, IsNil)
  1260  	c.Assert(strings.Contains(meta.Get("Content-Type"), "text/plain"), Equals, true)
  1261  
  1262  	err = s.bucket.DeleteObject(objectName + ".txt")
  1263  	c.Assert(err, IsNil)
  1264  
  1265  	// Put
  1266  	err = s.bucket.PutObject(objectName+".apk", strings.NewReader(objectValue))
  1267  	c.Assert(err, IsNil)
  1268  
  1269  	meta, err = s.bucket.GetObjectDetailedMeta(objectName + ".apk")
  1270  	c.Assert(err, IsNil)
  1271  	c.Assert(meta.Get("Content-Type"), Equals, "application/vnd.android.package-archive")
  1272  
  1273  	err = s.bucket.DeleteObject(objectName + ".txt")
  1274  	c.Assert(err, IsNil)
  1275  }
  1276  
  1277  // TestPutObject
  1278  func (s *OssBucketSuite) TestPutObjectKeyChars(c *C) {
  1279  	objectName := objectNamePrefix + RandStr(8)
  1280  	objectValue := "白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"
  1281  
  1282  	// Put
  1283  	objectKey := objectName + "十步杀一人,千里不留行。事了拂衣去,深藏身与名"
  1284  	err := s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
  1285  	c.Assert(err, IsNil)
  1286  
  1287  	// Check
  1288  	body, err := s.bucket.GetObject(objectKey)
  1289  	c.Assert(err, IsNil)
  1290  	str, err := readBody(body)
  1291  	c.Assert(err, IsNil)
  1292  	c.Assert(str, Equals, objectValue)
  1293  
  1294  	err = s.bucket.DeleteObject(objectKey)
  1295  	c.Assert(err, IsNil)
  1296  
  1297  	// Put
  1298  	objectKey = objectName + "ごきげん如何ですかおれの顔をよく拝んでおけ"
  1299  	err = s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
  1300  	c.Assert(err, IsNil)
  1301  
  1302  	// Check
  1303  	body, err = s.bucket.GetObject(objectKey)
  1304  	c.Assert(err, IsNil)
  1305  	str, err = readBody(body)
  1306  	c.Assert(err, IsNil)
  1307  	c.Assert(str, Equals, objectValue)
  1308  
  1309  	err = s.bucket.DeleteObject(objectKey)
  1310  	c.Assert(err, IsNil)
  1311  
  1312  	// Put
  1313  	objectKey = objectName + "~!@#$%^&*()_-+=|\\[]{}<>,./?"
  1314  	err = s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
  1315  	c.Assert(err, IsNil)
  1316  
  1317  	// Check
  1318  	body, err = s.bucket.GetObject(objectKey)
  1319  	c.Assert(err, IsNil)
  1320  	str, err = readBody(body)
  1321  	c.Assert(err, IsNil)
  1322  	c.Assert(str, Equals, objectValue)
  1323  
  1324  	err = s.bucket.DeleteObject(objectKey)
  1325  	c.Assert(err, IsNil)
  1326  
  1327  	// Put
  1328  	objectKey = "go/中国 日本 +-#&=*"
  1329  	err = s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
  1330  	c.Assert(err, IsNil)
  1331  
  1332  	// Check
  1333  	body, err = s.bucket.GetObject(objectKey)
  1334  	c.Assert(err, IsNil)
  1335  	str, err = readBody(body)
  1336  	c.Assert(err, IsNil)
  1337  	c.Assert(str, Equals, objectValue)
  1338  
  1339  	err = s.bucket.DeleteObject(objectKey)
  1340  	c.Assert(err, IsNil)
  1341  }
  1342  
  1343  // TestPutObjectNegative
  1344  func (s *OssBucketSuite) TestPutObjectNegative(c *C) {
  1345  	objectName := objectNamePrefix + RandStr(8)
  1346  	objectValue := "大江东去,浪淘尽,千古风流人物。 "
  1347  
  1348  	// Put
  1349  	objectName = objectNamePrefix + RandStr(8)
  1350  	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue),
  1351  		Meta("meta-my", "myprop"))
  1352  	c.Assert(err, IsNil)
  1353  
  1354  	// Check meta
  1355  	body, err := s.bucket.GetObject(objectName)
  1356  	c.Assert(err, IsNil)
  1357  	str, err := readBody(body)
  1358  	c.Assert(err, IsNil)
  1359  	c.Assert(str, Equals, objectValue)
  1360  
  1361  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  1362  	c.Assert(err, IsNil)
  1363  	c.Assert(meta.Get("X-Oss-Meta-My"), Not(Equals), "myprop")
  1364  	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "")
  1365  
  1366  	err = s.bucket.DeleteObject(objectName)
  1367  	c.Assert(err, IsNil)
  1368  
  1369  	// Invalid option
  1370  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue),
  1371  		IfModifiedSince(pastDate))
  1372  	c.Assert(err, NotNil)
  1373  
  1374  	err = s.bucket.PutObjectFromFile(objectName, "bucket.go", IfModifiedSince(pastDate))
  1375  	c.Assert(err, NotNil)
  1376  
  1377  	err = s.bucket.PutObjectFromFile(objectName, "/tmp/xxx")
  1378  	c.Assert(err, NotNil)
  1379  }
  1380  
  1381  // TestPutObjectFromFile
  1382  func (s *OssBucketSuite) TestPutObjectFromFile(c *C) {
  1383  	objectName := objectNamePrefix + RandStr(8)
  1384  	localFile := "../sample/BingWallpaper-2015-11-07.jpg"
  1385  	newFile := "newpic11.jpg"
  1386  
  1387  	// Put
  1388  	err := s.bucket.PutObjectFromFile(objectName, localFile)
  1389  	c.Assert(err, IsNil)
  1390  
  1391  	// Check
  1392  	err = s.bucket.GetObjectToFile(objectName, newFile)
  1393  	c.Assert(err, IsNil)
  1394  	eq, err := compareFiles(localFile, newFile)
  1395  	c.Assert(err, IsNil)
  1396  	c.Assert(eq, Equals, true)
  1397  
  1398  	acl, err := s.bucket.GetObjectACL(objectName)
  1399  	c.Assert(err, IsNil)
  1400  	testLogger.Println("aclRes:", acl)
  1401  	c.Assert(acl.ACL, Equals, "default")
  1402  
  1403  	err = s.bucket.DeleteObject(objectName)
  1404  	c.Assert(err, IsNil)
  1405  
  1406  	// Put with properties
  1407  	options := []Option{
  1408  		Expires(futureDate),
  1409  		ObjectACL(ACLPublicRead),
  1410  		Meta("myprop", "mypropval"),
  1411  	}
  1412  	os.Remove(newFile)
  1413  	err = s.bucket.PutObjectFromFile(objectName, localFile, options...)
  1414  	c.Assert(err, IsNil)
  1415  
  1416  	// Check
  1417  	err = s.bucket.GetObjectToFile(objectName, newFile)
  1418  	c.Assert(err, IsNil)
  1419  	eq, err = compareFiles(localFile, newFile)
  1420  	c.Assert(err, IsNil)
  1421  	c.Assert(eq, Equals, true)
  1422  
  1423  	acl, err = s.bucket.GetObjectACL(objectName)
  1424  	c.Assert(err, IsNil)
  1425  	testLogger.Println("GetObjectACL:", acl)
  1426  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
  1427  
  1428  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  1429  	c.Assert(err, IsNil)
  1430  	testLogger.Println("GetObjectDetailedMeta:", meta)
  1431  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  1432  
  1433  	err = s.bucket.DeleteObject(objectName)
  1434  	c.Assert(err, IsNil)
  1435  	os.Remove(newFile)
  1436  }
  1437  
  1438  // TestPutObjectFromFile
  1439  func (s *OssBucketSuite) TestPutObjectFromFileType(c *C) {
  1440  	objectName := objectNamePrefix + RandStr(8)
  1441  	localFile := "../sample/BingWallpaper-2015-11-07.jpg"
  1442  	newFile := RandStr(8) + ".jpg"
  1443  
  1444  	// Put
  1445  	err := s.bucket.PutObjectFromFile(objectName, localFile)
  1446  	c.Assert(err, IsNil)
  1447  
  1448  	// Check
  1449  	err = s.bucket.GetObjectToFile(objectName, newFile)
  1450  	c.Assert(err, IsNil)
  1451  	eq, err := compareFiles(localFile, newFile)
  1452  	c.Assert(err, IsNil)
  1453  	c.Assert(eq, Equals, true)
  1454  
  1455  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  1456  	c.Assert(err, IsNil)
  1457  	c.Assert(meta.Get("Content-Type"), Equals, "image/jpeg")
  1458  
  1459  	err = s.bucket.DeleteObject(objectName)
  1460  	c.Assert(err, IsNil)
  1461  	os.Remove(newFile)
  1462  }
  1463  
  1464  // TestGetObject
  1465  func (s *OssBucketSuite) TestGetObjectNormal(c *C) {
  1466  	objectName := objectNamePrefix + RandStr(8)
  1467  	objectValue := "长忆观潮,满郭人争江上望。来疑沧海尽成空,万面鼓声中。弄潮儿向涛头立,手把红旗旗不湿。别来几向梦中看,梦觉尚心寒。"
  1468  
  1469  	// Put
  1470  	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  1471  	c.Assert(err, IsNil)
  1472  
  1473  	// Check
  1474  	body, err := s.bucket.GetObject(objectName)
  1475  	c.Assert(err, IsNil)
  1476  	data, err := ioutil.ReadAll(body)
  1477  	body.Close()
  1478  	str := string(data)
  1479  	c.Assert(str, Equals, objectValue)
  1480  	testLogger.Println("GetObjec:", str)
  1481  
  1482  	// Range
  1483  	var subObjectValue = string(([]byte(objectValue))[15:36])
  1484  	body, err = s.bucket.GetObject(objectName, Range(15, 35))
  1485  	c.Assert(err, IsNil)
  1486  	data, err = ioutil.ReadAll(body)
  1487  	body.Close()
  1488  	str = string(data)
  1489  	c.Assert(str, Equals, subObjectValue)
  1490  	testLogger.Println("GetObject:", str, ",", subObjectValue)
  1491  
  1492  	// If-Modified-Since
  1493  	_, err = s.bucket.GetObject(objectName, IfModifiedSince(futureDate))
  1494  	c.Assert(err, NotNil)
  1495  
  1496  	// If-Unmodified-Since
  1497  	body, err = s.bucket.GetObject(objectName, IfUnmodifiedSince(futureDate))
  1498  	c.Assert(err, IsNil)
  1499  	data, err = ioutil.ReadAll(body)
  1500  	body.Close()
  1501  	c.Assert(string(data), Equals, objectValue)
  1502  
  1503  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  1504  	c.Assert(err, IsNil)
  1505  
  1506  	// If-Match
  1507  	body, err = s.bucket.GetObject(objectName, IfMatch(meta.Get("Etag")))
  1508  	c.Assert(err, IsNil)
  1509  	data, err = ioutil.ReadAll(body)
  1510  	body.Close()
  1511  	c.Assert(string(data), Equals, objectValue)
  1512  
  1513  	// If-None-Match
  1514  	_, err = s.bucket.GetObject(objectName, IfNoneMatch(meta.Get("Etag")))
  1515  	c.Assert(err, NotNil)
  1516  
  1517  	// process
  1518  	err = s.bucket.PutObjectFromFile(objectName, "../sample/BingWallpaper-2015-11-07.jpg")
  1519  	c.Assert(err, IsNil)
  1520  	_, err = s.bucket.GetObject(objectName, Process("image/format,png"))
  1521  	c.Assert(err, IsNil)
  1522  
  1523  	err = s.bucket.DeleteObject(objectName)
  1524  	c.Assert(err, IsNil)
  1525  }
  1526  
  1527  // TestGetObjectNegative
  1528  func (s *OssBucketSuite) TestGetObjectToWriterNegative(c *C) {
  1529  	objectName := objectNamePrefix + RandStr(8)
  1530  	objectValue := "长忆观潮,满郭人争江上望。"
  1531  
  1532  	// Object not exist
  1533  	_, err := s.bucket.GetObject("NotExist")
  1534  	c.Assert(err, NotNil)
  1535  
  1536  	// Constraint invalid
  1537  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  1538  	c.Assert(err, IsNil)
  1539  
  1540  	// Out of range
  1541  	_, err = s.bucket.GetObject(objectName, Range(15, 1000))
  1542  	c.Assert(err, IsNil)
  1543  
  1544  	// Not exist
  1545  	err = s.bucket.GetObjectToFile(objectName, "/root1/123abc9874")
  1546  	c.Assert(err, NotNil)
  1547  
  1548  	// Invalid option
  1549  	_, err = s.bucket.GetObject(objectName, ACL(ACLPublicRead))
  1550  	c.Assert(err, IsNil)
  1551  
  1552  	err = s.bucket.GetObjectToFile(objectName, "newpic15.jpg", ACL(ACLPublicRead))
  1553  	c.Assert(err, IsNil)
  1554  
  1555  	err = s.bucket.DeleteObject(objectName)
  1556  	c.Assert(err, IsNil)
  1557  }
  1558  
  1559  // TestGetObjectToFile
  1560  func (s *OssBucketSuite) TestGetObjectToFile(c *C) {
  1561  	objectName := objectNamePrefix + RandStr(8)
  1562  	objectValue := "江南好,风景旧曾谙;日出江花红胜火,春来江水绿如蓝。能不忆江南?江南忆,最忆是杭州;山寺月中寻桂子,郡亭枕上看潮头。何日更重游!"
  1563  	newFile := RandStr(8) + ".jpg"
  1564  
  1565  	// Put
  1566  	var val = []byte(objectValue)
  1567  	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  1568  	c.Assert(err, IsNil)
  1569  
  1570  	// Check
  1571  	err = s.bucket.GetObjectToFile(objectName, newFile)
  1572  	c.Assert(err, IsNil)
  1573  	eq, err := compareFileData(newFile, val)
  1574  	c.Assert(err, IsNil)
  1575  	c.Assert(eq, Equals, true)
  1576  	os.Remove(newFile)
  1577  
  1578  	// Range
  1579  	err = s.bucket.GetObjectToFile(objectName, newFile, Range(15, 35))
  1580  	c.Assert(err, IsNil)
  1581  	eq, err = compareFileData(newFile, val[15:36])
  1582  	c.Assert(err, IsNil)
  1583  	c.Assert(eq, Equals, true)
  1584  	os.Remove(newFile)
  1585  
  1586  	err = s.bucket.GetObjectToFile(objectName, newFile, NormalizedRange("15-35"))
  1587  	c.Assert(err, IsNil)
  1588  	eq, err = compareFileData(newFile, val[15:36])
  1589  	c.Assert(err, IsNil)
  1590  	c.Assert(eq, Equals, true)
  1591  	os.Remove(newFile)
  1592  
  1593  	err = s.bucket.GetObjectToFile(objectName, newFile, NormalizedRange("15-"))
  1594  	c.Assert(err, IsNil)
  1595  	eq, err = compareFileData(newFile, val[15:])
  1596  	c.Assert(err, IsNil)
  1597  	c.Assert(eq, Equals, true)
  1598  	os.Remove(newFile)
  1599  
  1600  	err = s.bucket.GetObjectToFile(objectName, newFile, NormalizedRange("-10"))
  1601  	c.Assert(err, IsNil)
  1602  	eq, err = compareFileData(newFile, val[(len(val)-10):])
  1603  	c.Assert(err, IsNil)
  1604  	c.Assert(eq, Equals, true)
  1605  	os.Remove(newFile)
  1606  
  1607  	// If-Modified-Since
  1608  	err = s.bucket.GetObjectToFile(objectName, newFile, IfModifiedSince(futureDate))
  1609  	c.Assert(err, NotNil)
  1610  
  1611  	// If-Unmodified-Since
  1612  	err = s.bucket.GetObjectToFile(objectName, newFile, IfUnmodifiedSince(futureDate))
  1613  	c.Assert(err, IsNil)
  1614  	eq, err = compareFileData(newFile, val)
  1615  	c.Assert(err, IsNil)
  1616  	c.Assert(eq, Equals, true)
  1617  	os.Remove(newFile)
  1618  
  1619  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  1620  	c.Assert(err, IsNil)
  1621  	testLogger.Println("GetObjectDetailedMeta:", meta)
  1622  
  1623  	// If-Match
  1624  	err = s.bucket.GetObjectToFile(objectName, newFile, IfMatch(meta.Get("Etag")))
  1625  	c.Assert(err, IsNil)
  1626  	eq, err = compareFileData(newFile, val)
  1627  	c.Assert(err, IsNil)
  1628  	c.Assert(eq, Equals, true)
  1629  
  1630  	// If-None-Match
  1631  	err = s.bucket.GetObjectToFile(objectName, newFile, IfNoneMatch(meta.Get("Etag")))
  1632  	c.Assert(err, NotNil)
  1633  
  1634  	// Accept-Encoding:gzip
  1635  	err = s.bucket.PutObjectFromFile(objectName, "../sample/The Go Programming Language.html")
  1636  	c.Assert(err, IsNil)
  1637  	err = s.bucket.GetObjectToFile(objectName, newFile, AcceptEncoding("gzip"))
  1638  	c.Assert(err, IsNil)
  1639  
  1640  	os.Remove(newFile)
  1641  	err = s.bucket.DeleteObject(objectName)
  1642  	c.Assert(err, IsNil)
  1643  }
  1644  
  1645  // TestListObjects
  1646  func (s *OssBucketSuite) TestListObjects(c *C) {
  1647  	objectName := objectNamePrefix + RandStr(8)
  1648  
  1649  	// List empty bucket
  1650  	lor, err := s.bucket.ListObjects()
  1651  	c.Assert(err, IsNil)
  1652  	left := len(lor.Objects)
  1653  
  1654  	// Put three objects
  1655  	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
  1656  	c.Assert(err, IsNil)
  1657  	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
  1658  	c.Assert(err, IsNil)
  1659  	err = s.bucket.PutObject(objectName+"3", strings.NewReader(""))
  1660  	c.Assert(err, IsNil)
  1661  
  1662  	// List
  1663  	lor, err = s.bucket.ListObjects()
  1664  	c.Assert(err, IsNil)
  1665  	c.Assert(len(lor.Objects), Equals, left+3)
  1666  
  1667  	// List with prefix
  1668  	lor, err = s.bucket.ListObjects(Prefix(objectName + "2"))
  1669  	c.Assert(err, IsNil)
  1670  	c.Assert(len(lor.Objects), Equals, 1)
  1671  
  1672  	lor, err = s.bucket.ListObjects(Prefix(objectName + "22"))
  1673  	c.Assert(err, IsNil)
  1674  	c.Assert(len(lor.Objects), Equals, 0)
  1675  
  1676  	// List with max keys
  1677  	lor, err = s.bucket.ListObjects(Prefix(objectName), MaxKeys(2))
  1678  	c.Assert(err, IsNil)
  1679  	c.Assert(len(lor.Objects), Equals, 2)
  1680  
  1681  	// List with marker
  1682  	lor, err = s.bucket.ListObjects(Marker(objectName+"1"), MaxKeys(1))
  1683  	c.Assert(err, IsNil)
  1684  	c.Assert(len(lor.Objects), Equals, 1)
  1685  
  1686  	err = s.bucket.DeleteObject(objectName + "1")
  1687  	c.Assert(err, IsNil)
  1688  	err = s.bucket.DeleteObject(objectName + "2")
  1689  	c.Assert(err, IsNil)
  1690  	err = s.bucket.DeleteObject(objectName + "3")
  1691  	c.Assert(err, IsNil)
  1692  }
  1693  
  1694  // TestListObjects
  1695  func (s *OssBucketSuite) TestListObjectsV2NotBatch(c *C) {
  1696  	objectName := objectNamePrefix + RandStr(8)
  1697  
  1698  	// create a bucket with default proprety
  1699  	client, err := New(endpoint, accessID, accessKey)
  1700  	c.Assert(err, IsNil)
  1701  
  1702  	bucketName := bucketNamePrefix + RandLowStr(6)
  1703  	err = client.CreateBucket(bucketName)
  1704  	c.Assert(err, IsNil)
  1705  
  1706  	bucket, err := client.Bucket(bucketName)
  1707  
  1708  	// List empty bucket
  1709  	lor, err := bucket.ListObjectsV2(StartAfter(""))
  1710  	c.Assert(err, IsNil)
  1711  	left := len(lor.Objects)
  1712  
  1713  	// Put three objects
  1714  	err = bucket.PutObject(objectName+"1", strings.NewReader(""))
  1715  	c.Assert(err, IsNil)
  1716  	err = bucket.PutObject(objectName+"2", strings.NewReader(""))
  1717  	c.Assert(err, IsNil)
  1718  	err = bucket.PutObject(objectName+"3", strings.NewReader(""))
  1719  	c.Assert(err, IsNil)
  1720  
  1721  	// List
  1722  	lor, err = bucket.ListObjectsV2(FetchOwner(true))
  1723  	c.Assert(err, IsNil)
  1724  	c.Assert(len(lor.Objects), Equals, left+3)
  1725  	c.Assert(len(lor.Objects[0].Owner.ID) > 0, Equals, true)
  1726  	c.Assert(len(lor.Objects[0].Owner.DisplayName) > 0, Equals, true)
  1727  
  1728  	// List with prefix
  1729  	lor, err = bucket.ListObjectsV2(Prefix(objectName + "2"))
  1730  	c.Assert(err, IsNil)
  1731  	c.Assert(len(lor.Objects), Equals, 1)
  1732  	c.Assert(lor.Objects[0].Key, Equals, objectName+"2")
  1733  
  1734  	lor, err = bucket.ListObjectsV2(Prefix(objectName + "22"))
  1735  	c.Assert(err, IsNil)
  1736  	c.Assert(len(lor.Objects), Equals, 0)
  1737  
  1738  	// List with max keys
  1739  	lor, err = bucket.ListObjectsV2(Prefix(objectName), MaxKeys(2))
  1740  	c.Assert(err, IsNil)
  1741  	c.Assert(len(lor.Objects), Equals, 2)
  1742  
  1743  	// List with marker
  1744  	lor, err = bucket.ListObjectsV2(StartAfter(objectName+"1"), MaxKeys(1))
  1745  	c.Assert(err, IsNil)
  1746  	c.Assert(len(lor.Objects), Equals, 1)
  1747  	c.Assert(lor.IsTruncated, Equals, true)
  1748  	c.Assert(len(lor.NextContinuationToken) > 0, Equals, true)
  1749  	c.Assert(lor.Objects[0].Key, Equals, objectName+"2")
  1750  
  1751  	lor, err = bucket.ListObjectsV2(Prefix(objectName), StartAfter(objectName+"1"), MaxKeys(2))
  1752  	c.Assert(err, IsNil)
  1753  	c.Assert(len(lor.Objects), Equals, 2)
  1754  	c.Assert(lor.IsTruncated, Equals, false)
  1755  	c.Assert(lor.NextContinuationToken, Equals, "")
  1756  	ForceDeleteBucket(client, bucketName, c)
  1757  	c.Assert(lor.Objects[0].Key, Equals, objectName+"2")
  1758  	c.Assert(lor.Objects[1].Key, Equals, objectName+"3")
  1759  }
  1760  
  1761  // TestListObjects
  1762  func (s *OssBucketSuite) TestListObjectsV2BatchList(c *C) {
  1763  	// create a bucket with default proprety
  1764  	client, err := New(endpoint, accessID, accessKey)
  1765  	c.Assert(err, IsNil)
  1766  
  1767  	bucketName := bucketNamePrefix + RandLowStr(6)
  1768  	err = client.CreateBucket(bucketName)
  1769  	c.Assert(err, IsNil)
  1770  
  1771  	bucket, err := client.Bucket(bucketName)
  1772  
  1773  	// Put three objects
  1774  	count := 17
  1775  	objectName := "testobject-" + RandLowStr(6)
  1776  	for i := 0; i < count; i++ {
  1777  		err = bucket.PutObject(objectName+strconv.Itoa(i), strings.NewReader(""))
  1778  		c.Assert(err, IsNil)
  1779  	}
  1780  
  1781  	Objects := []ObjectProperties{}
  1782  
  1783  	// List Object
  1784  	continuationToken := ""
  1785  	prefix := ""
  1786  	for {
  1787  		lor, err := bucket.ListObjectsV2(Prefix(prefix), ContinuationToken(continuationToken), MaxKeys(3))
  1788  		c.Assert(err, IsNil)
  1789  		Objects = append(Objects, lor.Objects...)
  1790  		continuationToken = lor.NextContinuationToken
  1791  		if !lor.IsTruncated {
  1792  			break
  1793  		}
  1794  	}
  1795  	c.Assert(len(Objects), Equals, count)
  1796  	ForceDeleteBucket(client, bucketName, c)
  1797  }
  1798  
  1799  // TestListObjects
  1800  func (s *OssBucketSuite) TestListObjectsEncodingType(c *C) {
  1801  	prefix := objectNamePrefix + "床前明月光,疑是地上霜。举头望明月,低头思故乡。"
  1802  
  1803  	for i := 0; i < 10; i++ {
  1804  		err := s.bucket.PutObject(prefix+strconv.Itoa(i), strings.NewReader(""))
  1805  		c.Assert(err, IsNil)
  1806  	}
  1807  
  1808  	lor, err := s.bucket.ListObjects(Prefix(objectNamePrefix + "床前明月光,"))
  1809  	c.Assert(err, IsNil)
  1810  	c.Assert(len(lor.Objects), Equals, 10)
  1811  
  1812  	lor, err = s.bucket.ListObjects(Marker(objectNamePrefix + "床前明月光,疑是地上霜。举头望明月,低头思故乡。"))
  1813  	c.Assert(err, IsNil)
  1814  	c.Assert(len(lor.Objects), Equals, 10)
  1815  
  1816  	lor, err = s.bucket.ListObjects(Prefix(objectNamePrefix + "床前明月光"))
  1817  	c.Assert(err, IsNil)
  1818  	for i, obj := range lor.Objects {
  1819  		c.Assert(obj.Key, Equals, prefix+strconv.Itoa(i))
  1820  	}
  1821  
  1822  	for i := 0; i < 10; i++ {
  1823  		err = s.bucket.DeleteObject(prefix + strconv.Itoa(i))
  1824  		c.Assert(err, IsNil)
  1825  	}
  1826  
  1827  	// Special characters
  1828  	objectName := objectNamePrefix + "` ~ ! @ # $ % ^ & * () - _ + =[] {} \\ | < > , . ? / 0"
  1829  	err = s.bucket.PutObject(objectName, strings.NewReader("明月几时有,把酒问青天"))
  1830  	c.Assert(err, IsNil)
  1831  
  1832  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  1833  	c.Assert(err, IsNil)
  1834  	c.Assert(len(lor.Objects), Equals, 1)
  1835  
  1836  	err = s.bucket.DeleteObject(objectName)
  1837  	c.Assert(err, IsNil)
  1838  
  1839  	objectName = objectNamePrefix + "中国  日本  +-#&=*"
  1840  	err = s.bucket.PutObject(objectName, strings.NewReader("明月几时有,把酒问青天"))
  1841  	c.Assert(err, IsNil)
  1842  
  1843  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  1844  	c.Assert(err, IsNil)
  1845  	c.Assert(len(lor.Objects), Equals, 1)
  1846  
  1847  	err = s.bucket.DeleteObject(objectName)
  1848  	c.Assert(err, IsNil)
  1849  }
  1850  
  1851  // TestIsBucketExist
  1852  func (s *OssBucketSuite) TestIsObjectExist(c *C) {
  1853  	objectName := objectNamePrefix + RandStr(8)
  1854  
  1855  	// Put three objects
  1856  	err := s.bucket.PutObject(objectName+"1", strings.NewReader(""))
  1857  	c.Assert(err, IsNil)
  1858  	err = s.bucket.PutObject(objectName+"11", strings.NewReader(""))
  1859  	c.Assert(err, IsNil)
  1860  	err = s.bucket.PutObject(objectName+"111", strings.NewReader(""))
  1861  	c.Assert(err, IsNil)
  1862  
  1863  	// Exist
  1864  	exist, err := s.bucket.IsObjectExist(objectName + "11")
  1865  	c.Assert(err, IsNil)
  1866  	c.Assert(exist, Equals, true)
  1867  
  1868  	exist, err = s.bucket.IsObjectExist(objectName + "1")
  1869  	c.Assert(err, IsNil)
  1870  	c.Assert(exist, Equals, true)
  1871  
  1872  	exist, err = s.bucket.IsObjectExist(objectName + "111")
  1873  	c.Assert(err, IsNil)
  1874  	c.Assert(exist, Equals, true)
  1875  
  1876  	// Not exist
  1877  	exist, err = s.bucket.IsObjectExist(objectName + "1111")
  1878  	c.Assert(err, IsNil)
  1879  	c.Assert(exist, Equals, false)
  1880  
  1881  	exist, err = s.bucket.IsObjectExist(objectName)
  1882  	c.Assert(err, IsNil)
  1883  	c.Assert(exist, Equals, false)
  1884  
  1885  	err = s.bucket.DeleteObject(objectName + "1")
  1886  	c.Assert(err, IsNil)
  1887  	err = s.bucket.DeleteObject(objectName + "11")
  1888  	c.Assert(err, IsNil)
  1889  	err = s.bucket.DeleteObject(objectName + "111")
  1890  	c.Assert(err, IsNil)
  1891  }
  1892  
  1893  // TestDeleteObject
  1894  func (s *OssBucketSuite) TestDeleteObject(c *C) {
  1895  	objectName := objectNamePrefix + RandStr(8)
  1896  
  1897  	err := s.bucket.PutObject(objectName, strings.NewReader(""))
  1898  	c.Assert(err, IsNil)
  1899  
  1900  	lor, err := s.bucket.ListObjects(Prefix(objectName))
  1901  	c.Assert(err, IsNil)
  1902  	c.Assert(len(lor.Objects), Equals, 1)
  1903  
  1904  	// Delete
  1905  	err = s.bucket.DeleteObject(objectName)
  1906  	c.Assert(err, IsNil)
  1907  
  1908  	// Duplicate delete
  1909  	err = s.bucket.DeleteObject(objectName)
  1910  	c.Assert(err, IsNil)
  1911  
  1912  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  1913  	c.Assert(err, IsNil)
  1914  	c.Assert(len(lor.Objects), Equals, 0)
  1915  }
  1916  
  1917  func (s *OssBucketSuite) TestWithEmptyObjectKey(c *C) {
  1918  	//upload
  1919  	err := s.bucket.PutObject("", strings.NewReader(""))
  1920  	c.Assert(err.Error(), Equals, "object name is empty")
  1921  	_, err = s.bucket.GetObject("")
  1922  	c.Assert(err.Error(), Equals, "object name is empty")
  1923  
  1924  	_, err = s.bucket.GetObjectTagging("")
  1925  	c.Assert(err.Error(), Equals, "object name is empty")
  1926  
  1927  	_, err = s.bucket.GetObjectACL("")
  1928  	c.Assert(err.Error(), Equals, "object name is empty")
  1929  
  1930  	_, err = s.bucket.GetObjectDetailedMeta("")
  1931  	c.Assert(err.Error(), Equals, "object name is empty")
  1932  
  1933  	err = s.bucket.GetObjectToFile("", "bucket_test.go")
  1934  	c.Assert(err.Error(), Equals, "object name is empty")
  1935  
  1936  	_, err = s.bucket.GetObjectMeta("")
  1937  	c.Assert(err.Error(), Equals, "object name is empty")
  1938  	// Delete
  1939  	err = s.bucket.DeleteObject("")
  1940  	c.Assert(err.Error(), Equals, "object name is empty")
  1941  
  1942  	err = s.bucket.DeleteObjectTagging("")
  1943  	c.Assert(err.Error(), Equals, "object name is empty")
  1944  
  1945  	_, err = s.bucket.ListObjects()
  1946  	c.Assert(err, IsNil)
  1947  
  1948  	_, err = s.bucket.ListObjectVersions()
  1949  	c.Assert(err, IsNil)
  1950  
  1951  	_, err = s.bucket.ListObjectsV2()
  1952  	c.Assert(err, IsNil)
  1953  }
  1954  
  1955  // TestDeleteObjects
  1956  func (s *OssBucketSuite) TestDeleteObjectsNormal(c *C) {
  1957  	objectName := objectNamePrefix + RandStr(8)
  1958  
  1959  	// Delete objects
  1960  	err := s.bucket.PutObject(objectName, strings.NewReader(""))
  1961  	c.Assert(err, IsNil)
  1962  
  1963  	res, err := s.bucket.DeleteObjects([]string{objectName})
  1964  	c.Assert(err, IsNil)
  1965  	c.Assert(len(res.DeletedObjects), Equals, 1)
  1966  
  1967  	lor, err := s.bucket.ListObjects(Prefix(objectName))
  1968  	c.Assert(err, IsNil)
  1969  	c.Assert(len(lor.Objects), Equals, 0)
  1970  
  1971  	// Delete objects
  1972  	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
  1973  	c.Assert(err, IsNil)
  1974  
  1975  	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
  1976  	c.Assert(err, IsNil)
  1977  
  1978  	res, err = s.bucket.DeleteObjects([]string{objectName + "1", objectName + "2"})
  1979  	c.Assert(err, IsNil)
  1980  	c.Assert(len(res.DeletedObjects), Equals, 2)
  1981  
  1982  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  1983  	c.Assert(err, IsNil)
  1984  	c.Assert(len(lor.Objects), Equals, 0)
  1985  
  1986  	// Delete 0
  1987  	_, err = s.bucket.DeleteObjects([]string{})
  1988  	c.Assert(err, NotNil)
  1989  
  1990  	// DeleteObjectsQuiet
  1991  	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
  1992  	c.Assert(err, IsNil)
  1993  
  1994  	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
  1995  	c.Assert(err, IsNil)
  1996  
  1997  	res, err = s.bucket.DeleteObjects([]string{objectName + "1", objectName + "2"},
  1998  		DeleteObjectsQuiet(false))
  1999  	c.Assert(err, IsNil)
  2000  	c.Assert(len(res.DeletedObjects), Equals, 2)
  2001  
  2002  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  2003  	c.Assert(err, IsNil)
  2004  	c.Assert(len(lor.Objects), Equals, 0)
  2005  
  2006  	// DeleteObjectsQuiet
  2007  	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
  2008  	c.Assert(err, IsNil)
  2009  
  2010  	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
  2011  	c.Assert(err, IsNil)
  2012  
  2013  	res, err = s.bucket.DeleteObjects([]string{objectName + "1", objectName + "2"},
  2014  		DeleteObjectsQuiet(true))
  2015  	c.Assert(err, IsNil)
  2016  	c.Assert(len(res.DeletedObjects), Equals, 0)
  2017  
  2018  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  2019  	c.Assert(err, IsNil)
  2020  	c.Assert(len(lor.Objects), Equals, 0)
  2021  
  2022  	// EncodingType
  2023  	err = s.bucket.PutObject("中国人", strings.NewReader(""))
  2024  	c.Assert(err, IsNil)
  2025  
  2026  	res, err = s.bucket.DeleteObjects([]string{"中国人"})
  2027  	c.Assert(err, IsNil)
  2028  	c.Assert(len(res.DeletedObjects), Equals, 1)
  2029  	c.Assert(res.DeletedObjects[0], Equals, "中国人")
  2030  
  2031  	// EncodingType
  2032  	err = s.bucket.PutObject("中国人", strings.NewReader(""))
  2033  	c.Assert(err, IsNil)
  2034  
  2035  	res, err = s.bucket.DeleteObjects([]string{"中国人"}, DeleteObjectsQuiet(false))
  2036  	c.Assert(err, IsNil)
  2037  	c.Assert(len(res.DeletedObjects), Equals, 1)
  2038  	c.Assert(res.DeletedObjects[0], Equals, "中国人")
  2039  
  2040  	// EncodingType
  2041  	err = s.bucket.PutObject("中国人", strings.NewReader(""))
  2042  	c.Assert(err, IsNil)
  2043  
  2044  	res, err = s.bucket.DeleteObjects([]string{"中国人"}, DeleteObjectsQuiet(true))
  2045  	c.Assert(err, IsNil)
  2046  	c.Assert(len(res.DeletedObjects), Equals, 0)
  2047  
  2048  	// Special characters
  2049  	key := "A ' < > \" & ~ ` ! @ # $ % ^ & * ( ) [] {} - _ + = / | \\ ? . , : ; A"
  2050  	err = s.bucket.PutObject(key, strings.NewReader("value"))
  2051  	c.Assert(err, IsNil)
  2052  
  2053  	_, err = s.bucket.DeleteObjects([]string{key})
  2054  	c.Assert(err, IsNil)
  2055  
  2056  	ress, err := s.bucket.ListObjects(Prefix(key))
  2057  	c.Assert(err, IsNil)
  2058  	c.Assert(len(ress.Objects), Equals, 0)
  2059  
  2060  	// Special characters two
  2061  	key = "\f"
  2062  	err = s.bucket.PutObject(key, strings.NewReader("value \f"))
  2063  	c.Assert(err, IsNil)
  2064  
  2065  	_, err = s.bucket.DeleteObjects([]string{key})
  2066  	c.Assert(err, IsNil)
  2067  
  2068  	ress, err = s.bucket.ListObjects(Prefix(key))
  2069  	c.Assert(err, IsNil)
  2070  	c.Assert(len(ress.Objects), Equals, 0)
  2071  
  2072  	key = "\v"
  2073  	err = s.bucket.PutObject(key, strings.NewReader("value \v"))
  2074  	c.Assert(err, IsNil)
  2075  
  2076  	_, err = s.bucket.DeleteObjects([]string{key})
  2077  	c.Assert(err, IsNil)
  2078  
  2079  	ress, err = s.bucket.ListObjects(Prefix(key))
  2080  	c.Assert(err, IsNil)
  2081  	c.Assert(len(ress.Objects), Equals, 0)
  2082  
  2083  	key = "\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
  2084  	err = s.bucket.PutObject(key, strings.NewReader("value test 0x20 \v"))
  2085  	c.Assert(err, IsNil)
  2086  
  2087  	_, err = s.bucket.DeleteObjects([]string{key})
  2088  	c.Assert(err, IsNil)
  2089  
  2090  	ress, err = s.bucket.ListObjects(Prefix(key))
  2091  	c.Assert(err, IsNil)
  2092  	c.Assert(len(ress.Objects), Equals, 0)
  2093  
  2094  	// Not exist
  2095  	_, err = s.bucket.DeleteObjects([]string{"NotExistObject"})
  2096  	c.Assert(err, IsNil)
  2097  }
  2098  
  2099  // TestSetObjectMeta
  2100  func (s *OssBucketSuite) TestSetObjectMeta(c *C) {
  2101  	objectName := objectNamePrefix + RandStr(8)
  2102  
  2103  	err := s.bucket.PutObject(objectName, strings.NewReader(""))
  2104  	c.Assert(err, IsNil)
  2105  
  2106  	err = s.bucket.SetObjectMeta(objectName,
  2107  		Expires(futureDate),
  2108  		Meta("myprop", "mypropval"))
  2109  	c.Assert(err, IsNil)
  2110  
  2111  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  2112  	c.Assert(err, IsNil)
  2113  	testLogger.Println("Meta:", meta)
  2114  	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
  2115  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  2116  
  2117  	acl, err := s.bucket.GetObjectACL(objectName)
  2118  	c.Assert(err, IsNil)
  2119  	c.Assert(acl.ACL, Equals, "default")
  2120  
  2121  	// Invalid option
  2122  	err = s.bucket.SetObjectMeta(objectName, AcceptEncoding("url"))
  2123  	c.Assert(err, IsNil)
  2124  
  2125  	// Invalid option value
  2126  	err = s.bucket.SetObjectMeta(objectName, ServerSideEncryption("invalid"))
  2127  	c.Assert(err, NotNil)
  2128  
  2129  	err = s.bucket.DeleteObject(objectName)
  2130  	c.Assert(err, IsNil)
  2131  
  2132  	// Not exist
  2133  	err = s.bucket.SetObjectMeta(objectName, Expires(futureDate))
  2134  	c.Assert(err, NotNil)
  2135  }
  2136  
  2137  // TestGetObjectMeta
  2138  func (s *OssBucketSuite) TestGetObjectMeta(c *C) {
  2139  	objectName := objectNamePrefix + RandStr(8)
  2140  
  2141  	// Put
  2142  	err := s.bucket.PutObject(objectName, strings.NewReader(""))
  2143  	c.Assert(err, IsNil)
  2144  
  2145  	meta, err := s.bucket.GetObjectMeta(objectName)
  2146  	c.Assert(err, IsNil)
  2147  	c.Assert(len(meta) > 0, Equals, true)
  2148  
  2149  	err = s.bucket.DeleteObject(objectName)
  2150  	c.Assert(err, IsNil)
  2151  
  2152  	_, err = s.bucket.GetObjectMeta("NotExistObject")
  2153  	c.Assert(err, NotNil)
  2154  }
  2155  
  2156  // TestErrorFromHeader
  2157  func (s *OssBucketSuite) TestErrorFromHeader(c *C) {
  2158  	objectName := objectNamePrefix + RandStr(8)
  2159  
  2160  	// Put
  2161  	err := s.bucket.PutObject(objectName, strings.NewReader(""))
  2162  	c.Assert(err, IsNil)
  2163  
  2164  	_, err = s.bucket.GetObject(objectName)
  2165  	c.Assert(err, IsNil)
  2166  
  2167  	meta, err := s.bucket.GetObjectMeta(objectName)
  2168  	c.Assert(err, IsNil)
  2169  	c.Assert(len(meta) > 0, Equals, true)
  2170  
  2171  	exist, err := s.bucket.IsObjectExist(objectName)
  2172  	c.Assert(err, IsNil)
  2173  	c.Assert(exist, Equals, true)
  2174  	err = s.bucket.DeleteObject(objectName)
  2175  	c.Assert(err, IsNil)
  2176  
  2177  	_, err = s.bucket.GetObject(objectName)
  2178  	c.Assert(err, NotNil)
  2179  	c.Assert(err.(ServiceError).Code, Equals, "NoSuchKey")
  2180  	c.Assert(err.(ServiceError).Ec != "", Equals, true)
  2181  	c.Assert(err.(ServiceError).RequestID != "", Equals, true)
  2182  	c.Assert(err.(ServiceError).HostID != "", Equals, true)
  2183  
  2184  	exist, err = s.bucket.IsObjectExist(objectName)
  2185  	c.Assert(err, IsNil)
  2186  	c.Assert(exist, Equals, false)
  2187  
  2188  	_, err = s.bucket.GetObjectMeta("NotExistObject")
  2189  	c.Assert(err, NotNil)
  2190  	c.Assert(err.(ServiceError).Code, Equals, "NoSuchKey")
  2191  	c.Assert(err.(ServiceError).Ec != "", Equals, true)
  2192  	c.Assert(err.(ServiceError).RequestID != "", Equals, true)
  2193  	c.Assert(err.(ServiceError).HostID != "", Equals, true)
  2194  }
  2195  
  2196  // TestGetObjectDetailedMeta
  2197  func (s *OssBucketSuite) TestGetObjectDetailedMeta(c *C) {
  2198  	objectName := objectNamePrefix + RandStr(8)
  2199  
  2200  	// Put
  2201  	err := s.bucket.PutObject(objectName, strings.NewReader(""),
  2202  		Expires(futureDate), Meta("myprop", "mypropval"))
  2203  	c.Assert(err, IsNil)
  2204  
  2205  	// Check
  2206  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  2207  	c.Assert(err, IsNil)
  2208  	testLogger.Println("GetObjectDetailedMeta:", meta)
  2209  	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
  2210  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  2211  	c.Assert(meta.Get("Content-Length"), Equals, "0")
  2212  	c.Assert(len(meta.Get("Date")) > 0, Equals, true)
  2213  	c.Assert(len(meta.Get("X-Oss-Request-Id")) > 0, Equals, true)
  2214  	c.Assert(len(meta.Get("Last-Modified")) > 0, Equals, true)
  2215  
  2216  	// IfModifiedSince/IfModifiedSince
  2217  	_, err = s.bucket.GetObjectDetailedMeta(objectName, IfModifiedSince(futureDate))
  2218  	c.Assert(err, NotNil)
  2219  
  2220  	meta, err = s.bucket.GetObjectDetailedMeta(objectName, IfUnmodifiedSince(futureDate))
  2221  	c.Assert(err, IsNil)
  2222  	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
  2223  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  2224  
  2225  	// IfMatch/IfNoneMatch
  2226  	_, err = s.bucket.GetObjectDetailedMeta(objectName, IfNoneMatch(meta.Get("Etag")))
  2227  	c.Assert(err, NotNil)
  2228  
  2229  	meta, err = s.bucket.GetObjectDetailedMeta(objectName, IfMatch(meta.Get("Etag")))
  2230  	c.Assert(err, IsNil)
  2231  	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
  2232  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  2233  
  2234  	err = s.bucket.DeleteObject(objectName)
  2235  	c.Assert(err, IsNil)
  2236  
  2237  	_, err = s.bucket.GetObjectDetailedMeta("NotExistObject")
  2238  	c.Assert(err, NotNil)
  2239  }
  2240  
  2241  // TestSetAndGetObjectAcl
  2242  func (s *OssBucketSuite) TestSetAndGetObjectAcl(c *C) {
  2243  	objectName := objectNamePrefix + RandStr(8)
  2244  
  2245  	err := s.bucket.PutObject(objectName, strings.NewReader(""))
  2246  	c.Assert(err, IsNil)
  2247  
  2248  	// Default
  2249  	acl, err := s.bucket.GetObjectACL(objectName)
  2250  	c.Assert(err, IsNil)
  2251  	c.Assert(acl.ACL, Equals, "default")
  2252  
  2253  	// Set ACL_PUBLIC_RW
  2254  	err = s.bucket.SetObjectACL(objectName, ACLPublicReadWrite)
  2255  	c.Assert(err, IsNil)
  2256  
  2257  	acl, err = s.bucket.GetObjectACL(objectName)
  2258  	c.Assert(err, IsNil)
  2259  	c.Assert(acl.ACL, Equals, string(ACLPublicReadWrite))
  2260  
  2261  	// Set ACL_PRIVATE
  2262  	err = s.bucket.SetObjectACL(objectName, ACLPrivate)
  2263  	c.Assert(err, IsNil)
  2264  
  2265  	acl, err = s.bucket.GetObjectACL(objectName)
  2266  	c.Assert(err, IsNil)
  2267  	c.Assert(acl.ACL, Equals, string(ACLPrivate))
  2268  
  2269  	// Set ACL_PUBLIC_R
  2270  	err = s.bucket.SetObjectACL(objectName, ACLPublicRead)
  2271  	c.Assert(err, IsNil)
  2272  
  2273  	acl, err = s.bucket.GetObjectACL(objectName)
  2274  	c.Assert(err, IsNil)
  2275  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
  2276  
  2277  	err = s.bucket.DeleteObject(objectName)
  2278  	c.Assert(err, IsNil)
  2279  }
  2280  
  2281  // TestSetAndGetObjectAclNegative
  2282  func (s *OssBucketSuite) TestSetAndGetObjectAclNegative(c *C) {
  2283  	objectName := objectNamePrefix + RandStr(8)
  2284  
  2285  	// Object not exist
  2286  	err := s.bucket.SetObjectACL(objectName, ACLPublicRead)
  2287  	c.Assert(err, NotNil)
  2288  }
  2289  
  2290  // TestCopyObject
  2291  func (s *OssBucketSuite) TestCopyObject(c *C) {
  2292  	objectName := objectNamePrefix + RandStr(8)
  2293  	objectValue := "男儿何不带吴钩,收取关山五十州。请君暂上凌烟阁,若个书生万户侯?"
  2294  
  2295  	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue),
  2296  		ACL(ACLPublicRead), Meta("my", "myprop"))
  2297  	c.Assert(err, IsNil)
  2298  
  2299  	// Copy
  2300  	var objectNameDest = objectName + "dest"
  2301  	_, err = s.bucket.CopyObject(objectName, objectNameDest)
  2302  	c.Assert(err, IsNil)
  2303  
  2304  	// Check
  2305  	lor, err := s.bucket.ListObjects(Prefix(objectName))
  2306  	c.Assert(err, IsNil)
  2307  	testLogger.Println("objects:", lor.Objects)
  2308  	c.Assert(len(lor.Objects), Equals, 2)
  2309  
  2310  	body, err := s.bucket.GetObject(objectName)
  2311  	c.Assert(err, IsNil)
  2312  	str, err := readBody(body)
  2313  	c.Assert(err, IsNil)
  2314  	c.Assert(str, Equals, objectValue)
  2315  
  2316  	err = s.bucket.DeleteObject(objectNameDest)
  2317  	c.Assert(err, IsNil)
  2318  
  2319  	// Copy with constraints x-oss-copy-source-if-modified-since
  2320  	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfModifiedSince(futureDate))
  2321  	c.Assert(err, NotNil)
  2322  	testLogger.Println("CopyObject:", err)
  2323  
  2324  	// Copy with constraints x-oss-copy-source-if-unmodified-since
  2325  	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfUnmodifiedSince(futureDate))
  2326  	c.Assert(err, IsNil)
  2327  
  2328  	// Check
  2329  	lor, err = s.bucket.ListObjects(Prefix(objectName))
  2330  	c.Assert(err, IsNil)
  2331  	testLogger.Println("objects:", lor.Objects)
  2332  	c.Assert(len(lor.Objects), Equals, 2)
  2333  
  2334  	body, err = s.bucket.GetObject(objectName)
  2335  	c.Assert(err, IsNil)
  2336  	str, err = readBody(body)
  2337  	c.Assert(err, IsNil)
  2338  	c.Assert(str, Equals, objectValue)
  2339  
  2340  	err = s.bucket.DeleteObject(objectNameDest)
  2341  	c.Assert(err, IsNil)
  2342  
  2343  	// Copy with constraints x-oss-copy-source-if-match
  2344  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  2345  	c.Assert(err, IsNil)
  2346  	testLogger.Println("GetObjectDetailedMeta:", meta)
  2347  
  2348  	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfMatch(meta.Get("Etag")))
  2349  	c.Assert(err, IsNil)
  2350  
  2351  	// Check
  2352  	body, err = s.bucket.GetObject(objectName)
  2353  	c.Assert(err, IsNil)
  2354  	str, err = readBody(body)
  2355  	c.Assert(err, IsNil)
  2356  	c.Assert(str, Equals, objectValue)
  2357  
  2358  	err = s.bucket.DeleteObject(objectNameDest)
  2359  	c.Assert(err, IsNil)
  2360  
  2361  	// Copy with constraints x-oss-copy-source-if-none-match
  2362  	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfNoneMatch(meta.Get("Etag")))
  2363  	c.Assert(err, NotNil)
  2364  
  2365  	// Copy with constraints x-oss-metadata-directive
  2366  	_, err = s.bucket.CopyObject(objectName, objectNameDest, Meta("my", "mydestprop"),
  2367  		MetadataDirective(MetaCopy))
  2368  	c.Assert(err, IsNil)
  2369  
  2370  	// Check
  2371  	body, err = s.bucket.GetObject(objectName)
  2372  	c.Assert(err, IsNil)
  2373  	str, err = readBody(body)
  2374  	c.Assert(err, IsNil)
  2375  	c.Assert(str, Equals, objectValue)
  2376  
  2377  	destMeta, err := s.bucket.GetObjectDetailedMeta(objectNameDest)
  2378  	c.Assert(err, IsNil)
  2379  	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
  2380  
  2381  	acl, err := s.bucket.GetObjectACL(objectNameDest)
  2382  	c.Assert(err, IsNil)
  2383  	c.Assert(acl.ACL, Equals, "default")
  2384  
  2385  	err = s.bucket.DeleteObject(objectNameDest)
  2386  	c.Assert(err, IsNil)
  2387  
  2388  	// Copy with constraints x-oss-metadata-directive and self defined dest object meta
  2389  	options := []Option{
  2390  		ObjectACL(ACLPublicReadWrite),
  2391  		Meta("my", "mydestprop"),
  2392  		MetadataDirective(MetaReplace),
  2393  	}
  2394  	_, err = s.bucket.CopyObject(objectName, objectNameDest, options...)
  2395  	c.Assert(err, IsNil)
  2396  
  2397  	// Check
  2398  	body, err = s.bucket.GetObject(objectName)
  2399  	c.Assert(err, IsNil)
  2400  	str, err = readBody(body)
  2401  	c.Assert(err, IsNil)
  2402  	c.Assert(str, Equals, objectValue)
  2403  
  2404  	destMeta, err = s.bucket.GetObjectDetailedMeta(objectNameDest)
  2405  	c.Assert(err, IsNil)
  2406  	c.Assert(destMeta.Get("X-Oss-Meta-My"), Equals, "mydestprop")
  2407  
  2408  	acl, err = s.bucket.GetObjectACL(objectNameDest)
  2409  	c.Assert(err, IsNil)
  2410  	c.Assert(acl.ACL, Equals, string(ACLPublicReadWrite))
  2411  
  2412  	err = s.bucket.DeleteObject(objectNameDest)
  2413  	c.Assert(err, IsNil)
  2414  
  2415  	err = s.bucket.DeleteObject(objectName)
  2416  	c.Assert(err, IsNil)
  2417  }
  2418  
  2419  // TestCopyObjectToOrFrom
  2420  func (s *OssBucketSuite) TestCopyObjectToOrFrom(c *C) {
  2421  	objectName := objectNamePrefix + RandStr(8)
  2422  	objectValue := "男儿何不带吴钩,收取关山五十州。请君暂上凌烟阁,若个书生万户侯?"
  2423  	destBucketName := bucketName + "-dest"
  2424  	objectNameDest := objectName + "-dest"
  2425  
  2426  	err := s.client.CreateBucket(destBucketName)
  2427  	c.Assert(err, IsNil)
  2428  
  2429  	destBucket, err := s.client.Bucket(destBucketName)
  2430  	c.Assert(err, IsNil)
  2431  
  2432  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  2433  	c.Assert(err, IsNil)
  2434  
  2435  	// Copy from
  2436  	_, err = destBucket.CopyObjectFrom(bucketName, objectName, objectNameDest)
  2437  	c.Assert(err, IsNil)
  2438  
  2439  	// Check
  2440  	body, err := destBucket.GetObject(objectNameDest)
  2441  	c.Assert(err, IsNil)
  2442  	str, err := readBody(body)
  2443  	c.Assert(err, IsNil)
  2444  	c.Assert(str, Equals, objectValue)
  2445  
  2446  	err = s.bucket.DeleteObject(objectName)
  2447  	c.Assert(err, IsNil)
  2448  
  2449  	// Copy to
  2450  	_, err = destBucket.CopyObjectTo(bucketName, objectName, objectNameDest)
  2451  	c.Assert(err, IsNil)
  2452  
  2453  	// Check
  2454  	body, err = s.bucket.GetObject(objectName)
  2455  	c.Assert(err, IsNil)
  2456  	str, err = readBody(body)
  2457  	c.Assert(err, IsNil)
  2458  	c.Assert(str, Equals, objectValue)
  2459  
  2460  	// Clean
  2461  	err = destBucket.DeleteObject(objectNameDest)
  2462  	c.Assert(err, IsNil)
  2463  
  2464  	err = s.bucket.DeleteObject(objectName)
  2465  	c.Assert(err, IsNil)
  2466  
  2467  	err = s.client.DeleteBucket(destBucketName)
  2468  	c.Assert(err, IsNil)
  2469  }
  2470  
  2471  // TestCopyObjectToOrFromNegative
  2472  func (s *OssBucketSuite) TestCopyObjectToOrFromNegative(c *C) {
  2473  	objectName := objectNamePrefix + RandStr(8)
  2474  	destBucket := bucketName + "-dest"
  2475  	objectNameDest := objectName + "-dest"
  2476  
  2477  	// Object not exist
  2478  	_, err := s.bucket.CopyObjectTo(bucketName, objectName, objectNameDest)
  2479  	c.Assert(err, NotNil)
  2480  
  2481  	// Bucket not exist
  2482  	_, err = s.bucket.CopyObjectFrom(destBucket, objectNameDest, objectName)
  2483  	c.Assert(err, NotNil)
  2484  }
  2485  
  2486  // TestAppendObject
  2487  func (s *OssBucketSuite) TestAppendObject(c *C) {
  2488  	objectName := objectNamePrefix + RandStr(8)
  2489  	objectValue := "昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。"
  2490  	var val = []byte(objectValue)
  2491  	var localFile = RandStr(8) + ".txt"
  2492  	var nextPos int64
  2493  	var midPos = 1 + rand.Intn(len(val)-1)
  2494  
  2495  	var err = CreateFileAndWrite(localFile+"1", val[0:midPos])
  2496  	c.Assert(err, IsNil)
  2497  	err = CreateFileAndWrite(localFile+"2", val[midPos:])
  2498  	c.Assert(err, IsNil)
  2499  
  2500  	// String append
  2501  	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,"), nextPos)
  2502  	c.Assert(err, IsNil)
  2503  	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("却道海棠依旧。知否?知否?应是绿肥红瘦。"), nextPos)
  2504  	c.Assert(err, IsNil)
  2505  
  2506  	body, err := s.bucket.GetObject(objectName)
  2507  	c.Assert(err, IsNil)
  2508  	str, err := readBody(body)
  2509  	c.Assert(err, IsNil)
  2510  	c.Assert(str, Equals, objectValue)
  2511  
  2512  	err = s.bucket.DeleteObject(objectName)
  2513  	c.Assert(err, IsNil)
  2514  
  2515  	// Byte append
  2516  	nextPos = 0
  2517  	nextPos, err = s.bucket.AppendObject(objectName, bytes.NewReader(val[0:midPos]), nextPos)
  2518  	c.Assert(err, IsNil)
  2519  	nextPos, err = s.bucket.AppendObject(objectName, bytes.NewReader(val[midPos:]), nextPos)
  2520  	c.Assert(err, IsNil)
  2521  
  2522  	body, err = s.bucket.GetObject(objectName)
  2523  	c.Assert(err, IsNil)
  2524  	str, err = readBody(body)
  2525  	c.Assert(err, IsNil)
  2526  	c.Assert(str, Equals, objectValue)
  2527  
  2528  	err = s.bucket.DeleteObject(objectName)
  2529  	c.Assert(err, IsNil)
  2530  
  2531  	// File append
  2532  	options := []Option{
  2533  		ObjectACL(ACLPublicReadWrite),
  2534  		Meta("my", "myprop"),
  2535  	}
  2536  
  2537  	fd, err := os.Open(localFile + "1")
  2538  	c.Assert(err, IsNil)
  2539  	defer fd.Close()
  2540  	nextPos = 0
  2541  	nextPos, err = s.bucket.AppendObject(objectName, fd, nextPos, options...)
  2542  	c.Assert(err, IsNil)
  2543  
  2544  	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  2545  	c.Assert(err, IsNil)
  2546  	testLogger.Println("GetObjectDetailedMeta:", meta, ",", nextPos)
  2547  	c.Assert(meta.Get("X-Oss-Object-Type"), Equals, "Appendable")
  2548  	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
  2549  	c.Assert(meta.Get("x-oss-Meta-Mine"), Equals, "")
  2550  	c.Assert(meta.Get("X-Oss-Next-Append-Position"), Equals, strconv.FormatInt(nextPos, 10))
  2551  
  2552  	acl, err := s.bucket.GetObjectACL(objectName)
  2553  	c.Assert(err, IsNil)
  2554  	testLogger.Println("GetObjectACL:", acl)
  2555  	c.Assert(acl.ACL, Equals, string(ACLPublicReadWrite))
  2556  
  2557  	// Second append
  2558  	options = []Option{
  2559  		ObjectACL(ACLPublicRead),
  2560  		Meta("my", "myproptwo"),
  2561  		Meta("mine", "mypropmine"),
  2562  	}
  2563  	fd, err = os.Open(localFile + "2")
  2564  	c.Assert(err, IsNil)
  2565  	defer fd.Close()
  2566  	nextPos, err = s.bucket.AppendObject(objectName, fd, nextPos, options...)
  2567  	c.Assert(err, IsNil)
  2568  
  2569  	body, err = s.bucket.GetObject(objectName)
  2570  	c.Assert(err, IsNil)
  2571  	str, err = readBody(body)
  2572  	c.Assert(err, IsNil)
  2573  	c.Assert(str, Equals, objectValue)
  2574  
  2575  	meta, err = s.bucket.GetObjectDetailedMeta(objectName)
  2576  	c.Assert(err, IsNil)
  2577  	testLogger.Println("GetObjectDetailedMeta xxx:", meta)
  2578  	c.Assert(meta.Get("X-Oss-Object-Type"), Equals, "Appendable")
  2579  	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
  2580  	c.Assert(meta.Get("x-Oss-Meta-Mine"), Equals, "")
  2581  	c.Assert(meta.Get("X-Oss-Next-Append-Position"), Equals, strconv.FormatInt(nextPos, 10))
  2582  
  2583  	acl, err = s.bucket.GetObjectACL(objectName)
  2584  	c.Assert(err, IsNil)
  2585  	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
  2586  
  2587  	err = s.bucket.DeleteObject(objectName)
  2588  	c.Assert(err, IsNil)
  2589  }
  2590  
  2591  // TestAppendObjectNegative
  2592  func (s *OssBucketSuite) TestAppendObjectNegative(c *C) {
  2593  	objectName := objectNamePrefix + RandStr(8)
  2594  	nextPos := int64(0)
  2595  
  2596  	nextPos, err := s.bucket.AppendObject(objectName, strings.NewReader("ObjectValue"), nextPos)
  2597  	c.Assert(err, IsNil)
  2598  
  2599  	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("ObjectValue"), 0)
  2600  	c.Assert(err, NotNil)
  2601  
  2602  	err = s.bucket.DeleteObject(objectName)
  2603  	c.Assert(err, IsNil)
  2604  }
  2605  
  2606  // TestContentType
  2607  func (s *OssBucketSuite) TestAddContentType(c *C) {
  2608  	opts := AddContentType(nil, "abc.txt")
  2609  	typ, err := FindOption(opts, HTTPHeaderContentType, "")
  2610  	c.Assert(err, IsNil)
  2611  	c.Assert(strings.Contains(typ.(string), "text/plain"), Equals, true)
  2612  
  2613  	opts = AddContentType(nil)
  2614  	typ, err = FindOption(opts, HTTPHeaderContentType, "")
  2615  	c.Assert(err, IsNil)
  2616  	c.Assert(len(opts), Equals, 1)
  2617  	c.Assert(strings.Contains(typ.(string), "application/octet-stream"), Equals, true)
  2618  
  2619  	opts = AddContentType(nil, "abc.txt", "abc.pdf")
  2620  	typ, err = FindOption(opts, HTTPHeaderContentType, "")
  2621  	c.Assert(err, IsNil)
  2622  	c.Assert(strings.Contains(typ.(string), "text/plain"), Equals, true)
  2623  
  2624  	opts = AddContentType(nil, "abc", "abc.txt", "abc.pdf")
  2625  	typ, err = FindOption(opts, HTTPHeaderContentType, "")
  2626  	c.Assert(err, IsNil)
  2627  	c.Assert(strings.Contains(typ.(string), "text/plain"), Equals, true)
  2628  
  2629  	opts = AddContentType(nil, "abc", "abc", "edf")
  2630  	typ, err = FindOption(opts, HTTPHeaderContentType, "")
  2631  	c.Assert(err, IsNil)
  2632  	c.Assert(strings.Contains(typ.(string), "application/octet-stream"), Equals, true)
  2633  
  2634  	opts = AddContentType([]Option{Meta("meta", "my")}, "abc", "abc.txt", "abc.pdf")
  2635  	typ, err = FindOption(opts, HTTPHeaderContentType, "")
  2636  	c.Assert(err, IsNil)
  2637  	c.Assert(len(opts), Equals, 2)
  2638  	c.Assert(strings.Contains(typ.(string), "text/plain"), Equals, true)
  2639  }
  2640  
  2641  func (s *OssBucketSuite) TestGetConfig(c *C) {
  2642  	client, err := New(endpoint, accessID, accessKey, UseCname(true),
  2643  		Timeout(11, 12), SecurityToken("token"), EnableMD5(false))
  2644  	c.Assert(err, IsNil)
  2645  
  2646  	bucket, err := client.Bucket(bucketName)
  2647  	c.Assert(err, IsNil)
  2648  
  2649  	c.Assert(bucket.GetConfig().HTTPTimeout.ConnectTimeout, Equals, time.Second*11)
  2650  	c.Assert(bucket.GetConfig().HTTPTimeout.ReadWriteTimeout, Equals, time.Second*12)
  2651  	c.Assert(bucket.GetConfig().HTTPTimeout.HeaderTimeout, Equals, time.Second*12)
  2652  	c.Assert(bucket.GetConfig().HTTPTimeout.IdleConnTimeout, Equals, time.Second*12)
  2653  	c.Assert(bucket.GetConfig().HTTPTimeout.LongTimeout, Equals, time.Second*12*10)
  2654  
  2655  	c.Assert(bucket.GetConfig().SecurityToken, Equals, "token")
  2656  	c.Assert(bucket.GetConfig().IsCname, Equals, true)
  2657  	c.Assert(bucket.GetConfig().IsEnableMD5, Equals, false)
  2658  }
  2659  
  2660  func (s *OssBucketSuite) TestForcePathStyle(c *C) {
  2661  	url, err := url.ParseRequestURI(endpoint)
  2662  	client, err := New(endpoint, accessID, accessKey, ForcePathStyle(true))
  2663  	c.Assert(err, IsNil)
  2664  
  2665  	_, err = client.GetBucketInfo(bucketName)
  2666  	c.Assert(err, NotNil)
  2667  	c.Assert(err.(ServiceError).Code, Equals, "SecondLevelDomainForbidden")
  2668  	c.Assert(err.(ServiceError).HostID, Equals, url.Host)
  2669  
  2670  	bucket, err := client.Bucket(bucketName)
  2671  	c.Assert(err, IsNil)
  2672  
  2673  	c.Assert(bucket.GetConfig().IsPathStyle, Equals, true)
  2674  
  2675  	objectName := "demo.txt"
  2676  
  2677  	err = bucket.PutObject(objectName, strings.NewReader("hi oss"))
  2678  	c.Assert(err, NotNil)
  2679  	c.Assert(err.(ServiceError).Code, Equals, "SecondLevelDomainForbidden")
  2680  
  2681  	str, err := bucket.SignURL(objectName, HTTPPut, 3600)
  2682  	c.Assert(err, IsNil)
  2683  	strUrl := endpoint + "/" + bucketName + "/" + objectName
  2684  	c.Assert(strings.Contains(str, strUrl), Equals, true)
  2685  }
  2686  
  2687  func (s *OssBucketSuite) TestUseCname(c *C) {
  2688  	url, err := url.ParseRequestURI(endpoint)
  2689  	c.Assert(err, IsNil)
  2690  	cnameEndpoint := bucketName + "." + url.Host
  2691  	client, err := New(cnameEndpoint, accessID, accessKey, UseCname(true))
  2692  	c.Assert(err, IsNil)
  2693  
  2694  	info, err := client.GetBucketInfo(bucketName)
  2695  
  2696  	c.Assert(err, IsNil)
  2697  	c.Assert(info.BucketInfo.Name, Equals, bucketName)
  2698  
  2699  	client, err = New(cnameEndpoint, accessID, accessKey)
  2700  	_, err = client.GetBucketInfo(bucketName)
  2701  	c.Assert(err, NotNil)
  2702  	c.Assert(err.(ServiceError).HostID, Equals, bucketName+"."+cnameEndpoint)
  2703  }
  2704  
  2705  func (s *OssBucketSuite) TestContextTimeout(c *C) {
  2706  	client, err := New(endpoint, accessID, accessKey)
  2707  	c.Assert(err, IsNil)
  2708  
  2709  	bucket, err := client.Bucket(bucketName)
  2710  	c.Assert(err, IsNil)
  2711  
  2712  	objectName := objectNamePrefix + RandStr(8)
  2713  	objectValue := "红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月满西楼。"
  2714  
  2715  	bucketNameDest := bucketNamePrefix + RandLowStr(8)
  2716  	c.Assert(err, IsNil)
  2717  
  2718  	objectNameDest := objectName + RandLowStr(5)
  2719  
  2720  	// Put
  2721  	ctx := context.Background()
  2722  	ctx, cancel := context.WithTimeout(ctx, 1*time.Nanosecond)
  2723  	defer cancel()
  2724  	err = bucket.PutObject(objectName, strings.NewReader(objectValue), WithContext(ctx))
  2725  	c.Assert(err, NotNil)
  2726  	c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2727  
  2728  	// Get not exist object
  2729  	_, err = bucket.GetObject(objectName)
  2730  	c.Assert(err, NotNil)
  2731  	c.Assert(err.(ServiceError).StatusCode, Equals, 404)
  2732  
  2733  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  2734  	c.Assert(err, IsNil)
  2735  
  2736  	// Get
  2737  	_, err = bucket.GetObject(objectName, WithContext(ctx))
  2738  	c.Assert(err, NotNil)
  2739  	c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2740  
  2741  	// CopyObjectTo
  2742  	_, err = bucket.CopyObjectTo(bucketNameDest, objectNameDest, objectName, WithContext(ctx))
  2743  	c.Assert(err, NotNil)
  2744  	c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2745  	// Delete
  2746  	err = s.bucket.DeleteObject(objectName)
  2747  	c.Assert(err, IsNil)
  2748  
  2749  	var nextPos int64
  2750  	// String append
  2751  	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("红藕香残玉簟秋。轻解罗裳,独上兰舟。"), nextPos, WithContext(ctx))
  2752  	c.Assert(err, NotNil)
  2753  
  2754  	// Put with URL
  2755  	signedURL, err := bucket.SignURL(objectName, HTTPPut, 3600)
  2756  	c.Assert(err, IsNil)
  2757  
  2758  	err = bucket.PutObjectWithURL(signedURL, strings.NewReader(objectValue), WithContext(ctx))
  2759  	c.Assert(err, NotNil)
  2760  	c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2761  
  2762  	// Get not exist object
  2763  	_, err = bucket.GetObject(objectName)
  2764  	c.Assert(err, NotNil)
  2765  	c.Assert(err.(ServiceError).StatusCode, Equals, 404)
  2766  
  2767  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue))
  2768  	c.Assert(err, IsNil)
  2769  
  2770  	// Get with URL
  2771  	signedURL, err = bucket.SignURL(objectName, HTTPGet, 3600)
  2772  	c.Assert(err, IsNil)
  2773  
  2774  	_, err = bucket.GetObjectWithURL(signedURL, WithContext(ctx))
  2775  	c.Assert(err, NotNil)
  2776  	c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2777  
  2778  	err = s.bucket.DeleteObject(objectName)
  2779  	c.Assert(err, IsNil)
  2780  
  2781  	content := RandStr(1024 * 1024)
  2782  	var fileName = "test-file-" + RandStr(8)
  2783  	CreateFile(fileName, content, c)
  2784  
  2785  	fd, err := os.Open(fileName)
  2786  	c.Assert(err, IsNil)
  2787  	defer fd.Close()
  2788  
  2789  	err = bucket.PutObjectFromFile(objectName, fileName, WithContext(ctx))
  2790  	c.Assert(err, NotNil)
  2791  	c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2792  
  2793  	os.Remove(fileName)
  2794  }
  2795  
  2796  func (s *OssBucketSuite) TestContextTimeoutBigFile(c *C) {
  2797  	client, err := New(endpoint, accessID, accessKey)
  2798  	c.Assert(err, IsNil)
  2799  
  2800  	bucket, err := client.Bucket(bucketName)
  2801  	c.Assert(err, IsNil)
  2802  
  2803  	objectName := objectNamePrefix + RandStr(8)
  2804  
  2805  	//big file
  2806  	content := RandStr(5 * 1024 * 1024)
  2807  	var fileName = "test-file-" + RandStr(8)
  2808  	CreateFile(fileName, content, c)
  2809  
  2810  	fd, err := os.Open(fileName)
  2811  	c.Assert(err, IsNil)
  2812  	defer fd.Close()
  2813  
  2814  	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
  2815  	defer cancel()
  2816  	objectNameBigfile := objectName + "-bigfile"
  2817  	err = bucket.PutObjectFromFile(objectNameBigfile, fileName, WithContext(ctx))
  2818  	if ctx != nil {
  2819  		select {
  2820  		case <-ctx.Done():
  2821  			c.Assert(err, NotNil)
  2822  			c.Assert(strings.Contains(err.Error(), "context deadline exceeded"), Equals, true)
  2823  		default:
  2824  			c.Fail()
  2825  		}
  2826  	}
  2827  
  2828  	// Get not exist object
  2829  	_, err = bucket.GetObject(objectNameBigfile)
  2830  	c.Assert(err, NotNil)
  2831  	c.Assert(err.(ServiceError).StatusCode, Equals, 404)
  2832  
  2833  	os.Remove(fileName)
  2834  }
  2835  
  2836  func (s *OssBucketSuite) TestSTSToken(c *C) {
  2837  	objectName := objectNamePrefix + RandStr(8)
  2838  	objectValue := "红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月满西楼。"
  2839  
  2840  	resp, err := stsAssumeRole(stsaccessID, stsaccessKey, stsARN, "oss_test_sess", 1800)
  2841  	c.Assert(err, IsNil)
  2842  	fmt.Print(resp)
  2843  
  2844  	client, err := New(endpoint, resp.Credentials.AccessKeyId, resp.Credentials.AccessKeySecret,
  2845  		SecurityToken(resp.Credentials.SecurityToken))
  2846  	c.Assert(err, IsNil)
  2847  
  2848  	bucket, err := client.Bucket(bucketName)
  2849  	c.Assert(err, IsNil)
  2850  
  2851  	// Put
  2852  	err = bucket.PutObject(objectName, strings.NewReader(objectValue))
  2853  	c.Assert(err, IsNil)
  2854  
  2855  	// Get
  2856  	body, err := bucket.GetObject(objectName)
  2857  	c.Assert(err, IsNil)
  2858  	str, err := readBody(body)
  2859  	c.Assert(err, IsNil)
  2860  	c.Assert(str, Equals, objectValue)
  2861  
  2862  	// List
  2863  	lor, err := bucket.ListObjects()
  2864  	c.Assert(err, IsNil)
  2865  	testLogger.Println("Objects:", lor.Objects)
  2866  
  2867  	// Put with URL
  2868  	signedURL, err := bucket.SignURL(objectName, HTTPPut, 3600)
  2869  	c.Assert(err, IsNil)
  2870  
  2871  	err = bucket.PutObjectWithURL(signedURL, strings.NewReader(objectValue))
  2872  	c.Assert(err, IsNil)
  2873  
  2874  	// Get with URL
  2875  	signedURL, err = bucket.SignURL(objectName, HTTPGet, 3600)
  2876  	c.Assert(err, IsNil)
  2877  
  2878  	body, err = bucket.GetObjectWithURL(signedURL)
  2879  	c.Assert(err, IsNil)
  2880  	str, err = readBody(body)
  2881  	c.Assert(err, IsNil)
  2882  	c.Assert(str, Equals, objectValue)
  2883  
  2884  	// Delete
  2885  	err = bucket.DeleteObject(objectName)
  2886  	c.Assert(err, IsNil)
  2887  }
  2888  
  2889  func (s *OssBucketSuite) TestSTSTonekNegative(c *C) {
  2890  	objectName := objectNamePrefix + RandStr(8)
  2891  	localFile := objectName + ".jpg"
  2892  
  2893  	client, err := New(endpoint, accessID, accessKey, SecurityToken("Invalid"))
  2894  	c.Assert(err, IsNil)
  2895  
  2896  	_, err = client.ListBuckets()
  2897  	c.Assert(err, NotNil)
  2898  
  2899  	bucket, err := client.Bucket(bucketName)
  2900  	c.Assert(err, IsNil)
  2901  
  2902  	err = bucket.PutObject(objectName, strings.NewReader(""))
  2903  	c.Assert(err, NotNil)
  2904  
  2905  	err = bucket.PutObjectFromFile(objectName, "")
  2906  	c.Assert(err, NotNil)
  2907  
  2908  	_, err = bucket.GetObject(objectName)
  2909  	c.Assert(err, NotNil)
  2910  
  2911  	err = bucket.GetObjectToFile(objectName, "")
  2912  	c.Assert(err, NotNil)
  2913  
  2914  	_, err = bucket.ListObjects()
  2915  	c.Assert(err, NotNil)
  2916  
  2917  	err = bucket.SetObjectACL(objectName, ACLPublicRead)
  2918  	c.Assert(err, NotNil)
  2919  
  2920  	_, err = bucket.GetObjectACL(objectName)
  2921  	c.Assert(err, NotNil)
  2922  
  2923  	err = bucket.UploadFile(objectName, localFile, MinPartSize)
  2924  	c.Assert(err, NotNil)
  2925  
  2926  	err = bucket.DownloadFile(objectName, localFile, MinPartSize)
  2927  	c.Assert(err, NotNil)
  2928  
  2929  	_, err = bucket.IsObjectExist(objectName)
  2930  	c.Assert(err, NotNil)
  2931  
  2932  	_, err = bucket.ListMultipartUploads()
  2933  	c.Assert(err, NotNil)
  2934  
  2935  	err = bucket.DeleteObject(objectName)
  2936  	c.Assert(err, NotNil)
  2937  
  2938  	_, err = bucket.DeleteObjects([]string{objectName})
  2939  	c.Assert(err, NotNil)
  2940  
  2941  	err = client.DeleteBucket(bucketName)
  2942  	c.Assert(err, NotNil)
  2943  }
  2944  
  2945  func (s *OssBucketSuite) TestUploadBigFile(c *C) {
  2946  	objectName := objectNamePrefix + RandStr(8)
  2947  	bigFile := "D:\\tmp\\bigfile.zip"
  2948  	newFile := "D:\\tmp\\newbigfile.zip"
  2949  
  2950  	exist, err := isFileExist(bigFile)
  2951  	c.Assert(err, IsNil)
  2952  	if !exist {
  2953  		return
  2954  	}
  2955  
  2956  	// Put
  2957  	start := GetNowSec()
  2958  	err = s.bucket.PutObjectFromFile(objectName, bigFile)
  2959  	c.Assert(err, IsNil)
  2960  	end := GetNowSec()
  2961  	testLogger.Println("Put big file:", bigFile, "use sec:", end-start)
  2962  
  2963  	// Check
  2964  	start = GetNowSec()
  2965  	err = s.bucket.GetObjectToFile(objectName, newFile)
  2966  	c.Assert(err, IsNil)
  2967  	end = GetNowSec()
  2968  	testLogger.Println("Get big file:", bigFile, "use sec:", end-start)
  2969  
  2970  	start = GetNowSec()
  2971  	eq, err := compareFiles(bigFile, newFile)
  2972  	c.Assert(err, IsNil)
  2973  	c.Assert(eq, Equals, true)
  2974  	end = GetNowSec()
  2975  	testLogger.Println("Compare big file:", bigFile, "use sec:", end-start)
  2976  
  2977  	err = s.bucket.DeleteObject(objectName)
  2978  	c.Assert(err, IsNil)
  2979  }
  2980  
  2981  func (s *OssBucketSuite) TestSymlink(c *C) {
  2982  	objectName := objectNamePrefix + RandStr(8)
  2983  	targetObjectName := objectName + "target"
  2984  
  2985  	err := s.bucket.DeleteObject(objectName)
  2986  	c.Assert(err, IsNil)
  2987  
  2988  	err = s.bucket.DeleteObject(targetObjectName)
  2989  	c.Assert(err, IsNil)
  2990  
  2991  	meta, err := s.bucket.GetSymlink(objectName)
  2992  	c.Assert(err, NotNil)
  2993  
  2994  	// Put symlink
  2995  	err = s.bucket.PutSymlink(objectName, targetObjectName)
  2996  	c.Assert(err, IsNil)
  2997  
  2998  	err = s.bucket.PutObject(targetObjectName, strings.NewReader("target"))
  2999  	c.Assert(err, IsNil)
  3000  
  3001  	err = s.bucket.PutSymlink(objectName, targetObjectName)
  3002  	c.Assert(err, IsNil)
  3003  
  3004  	meta, err = s.bucket.GetSymlink(objectName)
  3005  	c.Assert(err, IsNil)
  3006  	c.Assert(meta.Get(HTTPHeaderOssSymlinkTarget), Equals, targetObjectName)
  3007  
  3008  	// List object
  3009  	lor, err := s.bucket.ListObjects()
  3010  	c.Assert(err, IsNil)
  3011  	exist, v := s.getObject(lor.Objects, objectName)
  3012  	c.Assert(exist, Equals, true)
  3013  	c.Assert(v.Type, Equals, "Symlink")
  3014  
  3015  	body, err := s.bucket.GetObject(objectName)
  3016  	c.Assert(err, IsNil)
  3017  	str, err := readBody(body)
  3018  	c.Assert(err, IsNil)
  3019  	c.Assert(str, Equals, "target")
  3020  
  3021  	meta, err = s.bucket.GetSymlink(targetObjectName)
  3022  	c.Assert(err, NotNil)
  3023  
  3024  	err = s.bucket.PutObject(objectName, strings.NewReader("src"))
  3025  	c.Assert(err, IsNil)
  3026  
  3027  	body, err = s.bucket.GetObject(objectName)
  3028  	c.Assert(err, IsNil)
  3029  	str, err = readBody(body)
  3030  	c.Assert(err, IsNil)
  3031  	c.Assert(str, Equals, "src")
  3032  
  3033  	err = s.bucket.DeleteObject(objectName)
  3034  	c.Assert(err, IsNil)
  3035  
  3036  	err = s.bucket.DeleteObject(targetObjectName)
  3037  	c.Assert(err, IsNil)
  3038  
  3039  	// Put symlink again
  3040  	objectName = objectNamePrefix + RandStr(8)
  3041  	targetObjectName = objectName + "-target"
  3042  
  3043  	err = s.bucket.PutSymlink(objectName, targetObjectName)
  3044  	c.Assert(err, IsNil)
  3045  
  3046  	err = s.bucket.PutObject(targetObjectName, strings.NewReader("target1"))
  3047  	c.Assert(err, IsNil)
  3048  
  3049  	meta, err = s.bucket.GetSymlink(objectName)
  3050  	c.Assert(err, IsNil)
  3051  	c.Assert(meta.Get(HTTPHeaderOssSymlinkTarget), Equals, targetObjectName)
  3052  
  3053  	body, err = s.bucket.GetObject(objectName)
  3054  	c.Assert(err, IsNil)
  3055  	str, err = readBody(body)
  3056  	c.Assert(err, IsNil)
  3057  	c.Assert(str, Equals, "target1")
  3058  
  3059  	err = s.bucket.DeleteObject(objectName)
  3060  	c.Assert(err, IsNil)
  3061  
  3062  	err = s.bucket.DeleteObject(targetObjectName)
  3063  	c.Assert(err, IsNil)
  3064  }
  3065  
  3066  // TestRestoreObject
  3067  func (s *OssBucketSuite) TestRestoreObject(c *C) {
  3068  	objectName := objectNamePrefix + RandStr(8)
  3069  
  3070  	// List objects
  3071  	lor, err := s.archiveBucket.ListObjects()
  3072  	c.Assert(err, IsNil)
  3073  	left := len(lor.Objects)
  3074  
  3075  	// Put object
  3076  	err = s.archiveBucket.PutObject(objectName, strings.NewReader(""))
  3077  	c.Assert(err, IsNil)
  3078  
  3079  	// List
  3080  	lor, err = s.archiveBucket.ListObjects()
  3081  	c.Assert(err, IsNil)
  3082  	c.Assert(len(lor.Objects), Equals, left+1)
  3083  	for _, object := range lor.Objects {
  3084  		c.Assert(object.StorageClass, Equals, string(StorageArchive))
  3085  		c.Assert(object.Type, Equals, "Normal")
  3086  	}
  3087  
  3088  	// Head object
  3089  	meta, err := s.archiveBucket.GetObjectDetailedMeta(objectName)
  3090  	c.Assert(err, IsNil)
  3091  	_, ok := meta["X-Oss-Restore"]
  3092  	c.Assert(ok, Equals, false)
  3093  	c.Assert(meta.Get("X-Oss-Storage-Class"), Equals, "Archive")
  3094  
  3095  	// Error restore object
  3096  	err = s.archiveBucket.RestoreObject("notexistobject")
  3097  	c.Assert(err, NotNil)
  3098  
  3099  	// Restore object
  3100  	err = s.archiveBucket.RestoreObject(objectName)
  3101  	c.Assert(err, IsNil)
  3102  
  3103  	// Head object
  3104  	meta, err = s.archiveBucket.GetObjectDetailedMeta(objectName)
  3105  	c.Assert(err, IsNil)
  3106  	c.Assert(meta.Get("X-Oss-Restore"), Equals, "ongoing-request=\"true\"")
  3107  	c.Assert(meta.Get("X-Oss-Storage-Class"), Equals, "Archive")
  3108  }
  3109  
  3110  // TestRestoreObjectWithXml
  3111  func (s *OssBucketSuite) TestRestoreObjectWithConfig(c *C) {
  3112  	// create a bucket with default proprety
  3113  	client, err := New(endpoint, accessID, accessKey)
  3114  	c.Assert(err, IsNil)
  3115  
  3116  	bucketName := bucketNamePrefix + RandLowStr(6)
  3117  	err = client.CreateBucket(bucketName, StorageClass(StorageColdArchive))
  3118  	c.Assert(err, IsNil)
  3119  
  3120  	bucket, err := client.Bucket(bucketName)
  3121  	objectName := objectNamePrefix + RandStr(8)
  3122  
  3123  	// Put object
  3124  	err = bucket.PutObject(objectName, strings.NewReader("123456789"), ObjectStorageClass(StorageColdArchive))
  3125  	c.Assert(err, IsNil)
  3126  
  3127  	var restoreConfig RestoreConfiguration
  3128  	restoreConfig.Days = 2
  3129  
  3130  	err = bucket.RestoreObjectDetail(objectName, restoreConfig)
  3131  	c.Assert(err, IsNil)
  3132  
  3133  	objectName = objectNamePrefix + RandStr(8)
  3134  	err = bucket.PutObject(objectName, strings.NewReader("123456789"), ObjectStorageClass(StorageColdArchive))
  3135  	c.Assert(err, IsNil)
  3136  	restoreConfig.Tier = string(RestoreBulk)
  3137  	err = bucket.RestoreObjectDetail(objectName, restoreConfig)
  3138  	c.Assert(err, IsNil)
  3139  
  3140  	objectName = objectNamePrefix + RandStr(8)
  3141  	err = bucket.PutObject(objectName, strings.NewReader("123456789"), ObjectStorageClass(StorageColdArchive))
  3142  	c.Assert(err, IsNil)
  3143  	restoreConfig.Days = 0
  3144  	err = bucket.RestoreObjectDetail(objectName, restoreConfig)
  3145  	c.Assert(err, IsNil)
  3146  
  3147  	ForceDeleteBucket(client, bucketName, c)
  3148  }
  3149  
  3150  // TestRestoreObjectWithXml
  3151  func (s *OssBucketSuite) TestRestoreObjectWithXml(c *C) {
  3152  	// create a bucket with default proprety
  3153  	client, err := New(endpoint, accessID, accessKey)
  3154  	c.Assert(err, IsNil)
  3155  
  3156  	bucketName := bucketNamePrefix + RandLowStr(6)
  3157  	err = client.CreateBucket(bucketName, StorageClass(StorageArchive))
  3158  	c.Assert(err, IsNil)
  3159  
  3160  	bucket, err := client.Bucket(bucketName)
  3161  	objectName := objectNamePrefix + RandStr(8)
  3162  
  3163  	// Put object
  3164  	err = bucket.PutObject(objectName, strings.NewReader("123456789"), ObjectStorageClass(StorageArchive))
  3165  	c.Assert(err, IsNil)
  3166  
  3167  	xmlConfig := `<RestoreRequest><Days>7</Days></RestoreRequest>`
  3168  
  3169  	err = bucket.RestoreObjectXML(objectName, xmlConfig)
  3170  	c.Assert(err, IsNil)
  3171  	ForceDeleteBucket(client, bucketName, c)
  3172  }
  3173  
  3174  // TestProcessObject
  3175  func (s *OssBucketSuite) TestProcessObject(c *C) {
  3176  	objectName := objectNamePrefix + RandStr(8) + ".jpg"
  3177  	err := s.bucket.PutObjectFromFile(objectName, "../sample/BingWallpaper-2015-11-07.jpg")
  3178  	c.Assert(err, IsNil)
  3179  
  3180  	// If bucket-name not specified, it is saved to the current bucket by default.
  3181  	destObjName := objectNamePrefix + RandStr(8) + "-dest.jpg"
  3182  	process := fmt.Sprintf("image/resize,w_100|sys/saveas,o_%v", base64.URLEncoding.EncodeToString([]byte(destObjName)))
  3183  	result, err := s.bucket.ProcessObject(objectName, process)
  3184  	c.Assert(err, IsNil)
  3185  	exist, _ := s.bucket.IsObjectExist(destObjName)
  3186  	c.Assert(exist, Equals, true)
  3187  	c.Assert(result.Bucket, Equals, "")
  3188  	c.Assert(result.Object, Equals, destObjName)
  3189  
  3190  	destObjName = objectNamePrefix + RandStr(8) + "-dest.jpg"
  3191  	process = fmt.Sprintf("image/resize,w_100|sys/saveas,o_%v,b_%v", base64.URLEncoding.EncodeToString([]byte(destObjName)), base64.URLEncoding.EncodeToString([]byte(s.bucket.BucketName)))
  3192  	result, err = s.bucket.ProcessObject(objectName, process)
  3193  	c.Assert(err, IsNil)
  3194  	exist, _ = s.bucket.IsObjectExist(destObjName)
  3195  	c.Assert(exist, Equals, true)
  3196  	c.Assert(result.Bucket, Equals, s.bucket.BucketName)
  3197  	c.Assert(result.Object, Equals, destObjName)
  3198  
  3199  	//no support process
  3200  	process = fmt.Sprintf("image/resize,w_100|saveas,o_%v,b_%v", base64.URLEncoding.EncodeToString([]byte(destObjName)), base64.URLEncoding.EncodeToString([]byte(s.bucket.BucketName)))
  3201  	result, err = s.bucket.ProcessObject(objectName, process)
  3202  	c.Assert(err, NotNil)
  3203  }
  3204  
  3205  // TestAsyncProcessObject
  3206  func (s *OssBucketSuite) TestAsyncProcessObject(c *C) {
  3207  	videoUrl := "https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4?spm=a2c4g.64555.0.0.515675979u4B8w&file=video.mp4"
  3208  	fileName := "video.mp4"
  3209  	// 发起get请求
  3210  	resp, err := http.Get(videoUrl)
  3211  	c.Assert(err, IsNil)
  3212  	defer resp.Body.Close()
  3213  
  3214  	// 创建文件
  3215  	file, err := os.Create(fileName)
  3216  	c.Assert(err, IsNil)
  3217  	defer file.Close()
  3218  	_, err = io.Copy(file, resp.Body)
  3219  	c.Assert(err, IsNil)
  3220  
  3221  	err = s.bucket.PutObjectFromFile("demo.avi", fileName)
  3222  	c.Assert(err, IsNil)
  3223  
  3224  	sourceImageName := "demo.avi"
  3225  	style := "video/convert,f_avi,vcodec_h265,s_1920x1080,vb_2000000,fps_30,acodec_aac,ab_100000,sn_1"
  3226  	targetObject := "demo"
  3227  	process := fmt.Sprintf("%s|sys/saveas,b_%v,o_%v", style, strings.TrimRight(base64.URLEncoding.EncodeToString([]byte(bucketName)), "="), strings.TrimRight(base64.URLEncoding.EncodeToString([]byte(targetObject)), "="))
  3228  	_, err = s.bucket.AsyncProcessObject(sourceImageName, process)
  3229  	c.Assert(err, NotNil)
  3230  	c.Assert(err.(ServiceError).Code, Equals, "Imm Client")
  3231  	c.Assert(strings.Contains(err.(ServiceError).Message, "ResourceNotFound, The specified resource Attachment is not found"), Equals, true)
  3232  
  3233  	os.Remove(fileName)
  3234  }
  3235  
  3236  // Private
  3237  func CreateFileAndWrite(fileName string, data []byte) error {
  3238  	os.Remove(fileName)
  3239  
  3240  	fo, err := os.Create(fileName)
  3241  	if err != nil {
  3242  		return err
  3243  	}
  3244  	defer fo.Close()
  3245  
  3246  	bytes, err := fo.Write(data)
  3247  	if err != nil {
  3248  		return err
  3249  	}
  3250  
  3251  	if bytes != len(data) {
  3252  		return fmt.Errorf(fmt.Sprintf("write %d bytes not equal data length %d", bytes, len(data)))
  3253  	}
  3254  
  3255  	return nil
  3256  }
  3257  
  3258  // Compare the content between fileL and fileR
  3259  func compareFiles(fileL string, fileR string) (bool, error) {
  3260  	finL, err := os.Open(fileL)
  3261  	if err != nil {
  3262  		return false, err
  3263  	}
  3264  	defer finL.Close()
  3265  
  3266  	finR, err := os.Open(fileR)
  3267  	if err != nil {
  3268  		return false, err
  3269  	}
  3270  	defer finR.Close()
  3271  
  3272  	statL, err := finL.Stat()
  3273  	if err != nil {
  3274  		return false, err
  3275  	}
  3276  
  3277  	statR, err := finR.Stat()
  3278  	if err != nil {
  3279  		return false, err
  3280  	}
  3281  
  3282  	if statL.Size() != statR.Size() {
  3283  		return false, nil
  3284  	}
  3285  
  3286  	size := statL.Size()
  3287  	if size > 102400 {
  3288  		size = 102400
  3289  	}
  3290  
  3291  	bufL := make([]byte, size)
  3292  	bufR := make([]byte, size)
  3293  	for {
  3294  		n, _ := finL.Read(bufL)
  3295  		if 0 == n {
  3296  			break
  3297  		}
  3298  
  3299  		n, _ = finR.Read(bufR)
  3300  		if 0 == n {
  3301  			break
  3302  		}
  3303  
  3304  		if !bytes.Equal(bufL, bufR) {
  3305  			return false, nil
  3306  		}
  3307  	}
  3308  
  3309  	return true, nil
  3310  }
  3311  
  3312  // Compare the content of file and data
  3313  func compareFileData(file string, data []byte) (bool, error) {
  3314  	fin, err := os.Open(file)
  3315  	if err != nil {
  3316  		return false, err
  3317  	}
  3318  	defer fin.Close()
  3319  
  3320  	stat, err := fin.Stat()
  3321  	if err != nil {
  3322  		return false, err
  3323  	}
  3324  
  3325  	if stat.Size() != (int64)(len(data)) {
  3326  		return false, nil
  3327  	}
  3328  
  3329  	buf := make([]byte, stat.Size())
  3330  	n, err := fin.Read(buf)
  3331  	if err != nil {
  3332  		return false, err
  3333  	}
  3334  	if stat.Size() != (int64)(n) {
  3335  		return false, errors.New("read error")
  3336  	}
  3337  
  3338  	if !bytes.Equal(buf, data) {
  3339  		return false, nil
  3340  	}
  3341  
  3342  	return true, nil
  3343  }
  3344  
  3345  func walkDir(dirPth, suffix string) ([]string, error) {
  3346  	var files = []string{}
  3347  	suffix = strings.ToUpper(suffix)
  3348  	err := filepath.Walk(dirPth,
  3349  		func(filename string, fi os.FileInfo, err error) error {
  3350  			if err != nil {
  3351  				return err
  3352  			}
  3353  			if fi.IsDir() {
  3354  				return nil
  3355  			}
  3356  			if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
  3357  				files = append(files, filename)
  3358  			}
  3359  			return nil
  3360  		})
  3361  	return files, err
  3362  }
  3363  
  3364  func removeTempFiles(path string, prefix string) error {
  3365  	files, err := walkDir(path, prefix)
  3366  	if err != nil {
  3367  		return nil
  3368  	}
  3369  
  3370  	for _, file := range files {
  3371  		os.Remove(file)
  3372  	}
  3373  
  3374  	return nil
  3375  }
  3376  
  3377  func isFileExist(filename string) (bool, error) {
  3378  	_, err := os.Stat(filename)
  3379  	if err != nil && os.IsNotExist(err) {
  3380  		return false, nil
  3381  	} else if err != nil {
  3382  		return false, err
  3383  	} else {
  3384  		return true, nil
  3385  	}
  3386  }
  3387  
  3388  func readBody(body io.ReadCloser) (string, error) {
  3389  	data, err := ioutil.ReadAll(body)
  3390  	body.Close()
  3391  	if err != nil {
  3392  		return "", err
  3393  	}
  3394  	return string(data), nil
  3395  }
  3396  
  3397  func (s *OssBucketSuite) getObject(objects []ObjectProperties, object string) (bool, ObjectProperties) {
  3398  	for _, v := range objects {
  3399  		if v.Key == object {
  3400  			return true, v
  3401  		}
  3402  	}
  3403  	return false, ObjectProperties{}
  3404  }
  3405  
  3406  func (s *OssBucketSuite) detectUploadSpeed(bucket *Bucket, c *C) (upSpeed int) {
  3407  	objectName := objectNamePrefix + RandStr(8)
  3408  
  3409  	// 1M byte
  3410  	textBuffer := RandStr(1024 * 1024)
  3411  
  3412  	// Put string
  3413  	startT := time.Now()
  3414  	err := bucket.PutObject(objectName, strings.NewReader(textBuffer))
  3415  	endT := time.Now()
  3416  
  3417  	c.Assert(err, IsNil)
  3418  	err = bucket.DeleteObject(objectName)
  3419  	c.Assert(err, IsNil)
  3420  
  3421  	// byte/s
  3422  	upSpeed = len(textBuffer) * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
  3423  	return upSpeed
  3424  }
  3425  
  3426  func (s *OssBucketSuite) TestPutSingleObjectLimitSpeed(c *C) {
  3427  
  3428  	// create client and bucket
  3429  	client, err := New(endpoint, accessID, accessKey)
  3430  	c.Assert(err, IsNil)
  3431  
  3432  	err = client.LimitUploadSpeed(1)
  3433  	if err != nil {
  3434  		// go version is less than go1.7,not support limit upload speed
  3435  		// doesn't run this test
  3436  		return
  3437  	}
  3438  	// set unlimited again
  3439  	client.LimitUploadSpeed(0)
  3440  
  3441  	bucketName := bucketNamePrefix + RandLowStr(6)
  3442  	err = client.CreateBucket(bucketName)
  3443  	c.Assert(err, IsNil)
  3444  
  3445  	bucket, err := client.Bucket(bucketName)
  3446  	c.Assert(err, IsNil)
  3447  
  3448  	//detect speed:byte/s
  3449  	detectSpeed := s.detectUploadSpeed(bucket, c)
  3450  
  3451  	var limitSpeed = 0
  3452  	if detectSpeed <= perTokenBandwidthSize*2 {
  3453  		limitSpeed = perTokenBandwidthSize
  3454  	} else {
  3455  		//this situation, the test works better
  3456  		limitSpeed = detectSpeed / 2
  3457  	}
  3458  
  3459  	// KB/s
  3460  	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
  3461  	c.Assert(err, IsNil)
  3462  
  3463  	objectName := objectNamePrefix + RandStr(8)
  3464  
  3465  	// 1M byte
  3466  	textBuffer := RandStr(1024 * 1024)
  3467  
  3468  	// Put body
  3469  	startT := time.Now()
  3470  	err = bucket.PutObject(objectName, strings.NewReader(textBuffer))
  3471  	endT := time.Now()
  3472  
  3473  	realSpeed := int64(len(textBuffer)) * 1000 / (endT.UnixNano()/1000/1000 - startT.UnixNano()/1000/1000)
  3474  
  3475  	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
  3476  
  3477  	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
  3478  
  3479  	if detectSpeed > perTokenBandwidthSize {
  3480  		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
  3481  		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
  3482  	}
  3483  
  3484  	// Get object and compare content
  3485  	body, err := bucket.GetObject(objectName)
  3486  	c.Assert(err, IsNil)
  3487  	str, err := readBody(body)
  3488  	c.Assert(err, IsNil)
  3489  	c.Assert(str, Equals, textBuffer)
  3490  
  3491  	bucket.DeleteObject(objectName)
  3492  	client.DeleteBucket(bucketName)
  3493  	c.Assert(err, IsNil)
  3494  
  3495  	return
  3496  }
  3497  
  3498  func putObjectRoutin(bucket *Bucket, object string, textBuffer *string, notifyChan chan int) error {
  3499  	err := bucket.PutObject(object, strings.NewReader(*textBuffer))
  3500  	if err == nil {
  3501  		notifyChan <- 1
  3502  	} else {
  3503  		notifyChan <- 0
  3504  	}
  3505  	return err
  3506  }
  3507  
  3508  func (s *OssBucketSuite) TestPutManyObjectLimitSpeed(c *C) {
  3509  	// create client and bucket
  3510  	client, err := New(endpoint, accessID, accessKey)
  3511  	c.Assert(err, IsNil)
  3512  
  3513  	err = client.LimitUploadSpeed(1)
  3514  	if err != nil {
  3515  		// go version is less than go1.7,not support limit upload speed
  3516  		// doesn't run this test
  3517  		return
  3518  	}
  3519  	// set unlimited
  3520  	client.LimitUploadSpeed(0)
  3521  
  3522  	bucketName := bucketNamePrefix + RandLowStr(6)
  3523  	err = client.CreateBucket(bucketName)
  3524  	c.Assert(err, IsNil)
  3525  
  3526  	bucket, err := client.Bucket(bucketName)
  3527  	c.Assert(err, IsNil)
  3528  
  3529  	//detect speed:byte/s
  3530  	detectSpeed := s.detectUploadSpeed(bucket, c)
  3531  	var limitSpeed = 0
  3532  	if detectSpeed <= perTokenBandwidthSize*2 {
  3533  		limitSpeed = perTokenBandwidthSize
  3534  	} else {
  3535  		limitSpeed = detectSpeed / 2
  3536  	}
  3537  
  3538  	// KB/s
  3539  	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
  3540  	c.Assert(err, IsNil)
  3541  
  3542  	// object1
  3543  	objectNameFirst := objectNamePrefix + RandStr(8)
  3544  	objectNameSecond := objectNamePrefix + RandStr(8)
  3545  
  3546  	// 1M byte
  3547  	textBuffer := RandStr(1024 * 1024)
  3548  
  3549  	objectCount := 2
  3550  	notifyChan := make(chan int, objectCount)
  3551  
  3552  	//start routin
  3553  	startT := time.Now()
  3554  	go putObjectRoutin(bucket, objectNameFirst, &textBuffer, notifyChan)
  3555  	go putObjectRoutin(bucket, objectNameSecond, &textBuffer, notifyChan)
  3556  
  3557  	// wait routin end
  3558  	sum := int(0)
  3559  	for j := 0; j < objectCount; j++ {
  3560  		result := <-notifyChan
  3561  		sum += result
  3562  	}
  3563  	endT := time.Now()
  3564  
  3565  	realSpeed := len(textBuffer) * 2 * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
  3566  	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
  3567  
  3568  	if detectSpeed > perTokenBandwidthSize {
  3569  		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
  3570  		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
  3571  	}
  3572  	c.Assert(sum, Equals, 2)
  3573  
  3574  	// Get object and compare content
  3575  	body, err := bucket.GetObject(objectNameFirst)
  3576  	c.Assert(err, IsNil)
  3577  	str, err := readBody(body)
  3578  	c.Assert(err, IsNil)
  3579  	c.Assert(str, Equals, textBuffer)
  3580  
  3581  	body, err = bucket.GetObject(objectNameSecond)
  3582  	c.Assert(err, IsNil)
  3583  	str, err = readBody(body)
  3584  	c.Assert(err, IsNil)
  3585  	c.Assert(str, Equals, textBuffer)
  3586  
  3587  	// clear bucket and object
  3588  	bucket.DeleteObject(objectNameFirst)
  3589  	bucket.DeleteObject(objectNameSecond)
  3590  	client.DeleteBucket(bucketName)
  3591  
  3592  	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
  3593  
  3594  	return
  3595  }
  3596  
  3597  func (s *OssBucketSuite) TestPutMultipartObjectLimitSpeed(c *C) {
  3598  
  3599  	// create client and bucket
  3600  	client, err := New(endpoint, accessID, accessKey)
  3601  	c.Assert(err, IsNil)
  3602  
  3603  	err = client.LimitUploadSpeed(1)
  3604  	if err != nil {
  3605  		// go version is less than go1.7,not support limit upload speed
  3606  		// doesn't run this test
  3607  		return
  3608  	}
  3609  	// set unlimited
  3610  	client.LimitUploadSpeed(0)
  3611  
  3612  	bucketName := bucketNamePrefix + RandLowStr(6)
  3613  	err = client.CreateBucket(bucketName)
  3614  	c.Assert(err, IsNil)
  3615  
  3616  	bucket, err := client.Bucket(bucketName)
  3617  	c.Assert(err, IsNil)
  3618  
  3619  	//detect speed:byte/s
  3620  	detectSpeed := s.detectUploadSpeed(bucket, c)
  3621  
  3622  	var limitSpeed = 0
  3623  	if detectSpeed <= perTokenBandwidthSize*2 {
  3624  		limitSpeed = perTokenBandwidthSize
  3625  	} else {
  3626  		//this situation, the test works better
  3627  		limitSpeed = detectSpeed / 2
  3628  	}
  3629  
  3630  	// KB/s
  3631  	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
  3632  	c.Assert(err, IsNil)
  3633  
  3634  	objectName := objectNamePrefix + RandStr(8)
  3635  	fileName := "." + string(os.PathSeparator) + objectName
  3636  
  3637  	// 1M byte
  3638  	fileSize := 0
  3639  	textBuffer := RandStr(1024 * 1024)
  3640  	if detectSpeed < perTokenBandwidthSize {
  3641  		ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
  3642  		f, err := os.Stat(fileName)
  3643  		c.Assert(err, IsNil)
  3644  
  3645  		fileSize = int(f.Size())
  3646  		c.Assert(fileSize, Equals, len(textBuffer))
  3647  
  3648  	} else {
  3649  		loopCount := 5
  3650  		f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660)
  3651  		c.Assert(err, IsNil)
  3652  
  3653  		for i := 0; i < loopCount; i++ {
  3654  			f.Write([]byte(textBuffer))
  3655  		}
  3656  
  3657  		fileInfo, err := f.Stat()
  3658  		c.Assert(err, IsNil)
  3659  
  3660  		fileSize = int(fileInfo.Size())
  3661  		c.Assert(fileSize, Equals, len(textBuffer)*loopCount)
  3662  
  3663  		f.Close()
  3664  	}
  3665  
  3666  	// Put body
  3667  	startT := time.Now()
  3668  	err = bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), Checkpoint(true, ""))
  3669  	endT := time.Now()
  3670  
  3671  	c.Assert(err, IsNil)
  3672  	realSpeed := fileSize * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
  3673  	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
  3674  
  3675  	if detectSpeed > perTokenBandwidthSize {
  3676  		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
  3677  		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
  3678  	}
  3679  
  3680  	// Get object and compare content
  3681  	body, err := bucket.GetObject(objectName)
  3682  	c.Assert(err, IsNil)
  3683  	str, err := readBody(body)
  3684  	c.Assert(err, IsNil)
  3685  
  3686  	fileBody, err := ioutil.ReadFile(fileName)
  3687  	c.Assert(err, IsNil)
  3688  	c.Assert(str, Equals, string(fileBody))
  3689  
  3690  	// delete bucket、object、file
  3691  	bucket.DeleteObject(objectName)
  3692  	client.DeleteBucket(bucketName)
  3693  	os.Remove(fileName)
  3694  
  3695  	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
  3696  
  3697  	return
  3698  }
  3699  
  3700  func (s *OssBucketSuite) TestPutObjectFromFileLimitSpeed(c *C) {
  3701  	// create client and bucket
  3702  	client, err := New(endpoint, accessID, accessKey)
  3703  	c.Assert(err, IsNil)
  3704  
  3705  	err = client.LimitUploadSpeed(1)
  3706  	if err != nil {
  3707  		// go version is less than go1.7,not support limit upload speed
  3708  		// doesn't run this test
  3709  		return
  3710  	}
  3711  	// set unlimited
  3712  	client.LimitUploadSpeed(0)
  3713  
  3714  	bucketName := bucketNamePrefix + RandLowStr(6)
  3715  	err = client.CreateBucket(bucketName)
  3716  	c.Assert(err, IsNil)
  3717  
  3718  	bucket, err := client.Bucket(bucketName)
  3719  	c.Assert(err, IsNil)
  3720  
  3721  	//detect speed:byte/s
  3722  	detectSpeed := s.detectUploadSpeed(bucket, c)
  3723  
  3724  	var limitSpeed = 0
  3725  	if detectSpeed <= perTokenBandwidthSize*2 {
  3726  		limitSpeed = perTokenBandwidthSize
  3727  	} else {
  3728  		//this situation, the test works better
  3729  		limitSpeed = detectSpeed / 2
  3730  	}
  3731  
  3732  	// KB/s
  3733  	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
  3734  	c.Assert(err, IsNil)
  3735  
  3736  	objectName := objectNamePrefix + RandStr(8)
  3737  	fileName := "." + string(os.PathSeparator) + objectName
  3738  
  3739  	// 1M byte
  3740  	fileSize := 0
  3741  	textBuffer := RandStr(1024 * 1024)
  3742  	if detectSpeed < perTokenBandwidthSize {
  3743  		ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
  3744  		f, err := os.Stat(fileName)
  3745  		c.Assert(err, IsNil)
  3746  
  3747  		fileSize = int(f.Size())
  3748  		c.Assert(fileSize, Equals, len(textBuffer))
  3749  
  3750  	} else {
  3751  		loopCount := 2
  3752  		f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660)
  3753  		c.Assert(err, IsNil)
  3754  
  3755  		for i := 0; i < loopCount; i++ {
  3756  			f.Write([]byte(textBuffer))
  3757  		}
  3758  
  3759  		fileInfo, err := f.Stat()
  3760  		c.Assert(err, IsNil)
  3761  
  3762  		fileSize = int(fileInfo.Size())
  3763  		c.Assert(fileSize, Equals, len(textBuffer)*loopCount)
  3764  
  3765  		f.Close()
  3766  	}
  3767  
  3768  	// Put body
  3769  	startT := time.Now()
  3770  	err = bucket.PutObjectFromFile(objectName, fileName)
  3771  	endT := time.Now()
  3772  
  3773  	c.Assert(err, IsNil)
  3774  	realSpeed := fileSize * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
  3775  	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
  3776  
  3777  	if detectSpeed > perTokenBandwidthSize {
  3778  		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
  3779  		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
  3780  	}
  3781  
  3782  	// Get object and compare content
  3783  	body, err := bucket.GetObject(objectName)
  3784  	c.Assert(err, IsNil)
  3785  	str, err := readBody(body)
  3786  	c.Assert(err, IsNil)
  3787  
  3788  	fileBody, err := ioutil.ReadFile(fileName)
  3789  	c.Assert(err, IsNil)
  3790  	c.Assert(str, Equals, string(fileBody))
  3791  
  3792  	// delete bucket、file、object
  3793  	bucket.DeleteObject(objectName)
  3794  	client.DeleteBucket(bucketName)
  3795  	os.Remove(fileName)
  3796  
  3797  	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
  3798  
  3799  	return
  3800  }
  3801  
  3802  // upload speed limit parameters will not affect download speed
  3803  func (s *OssBucketSuite) TestUploadObjectLimitSpeed(c *C) {
  3804  	// create limit client and bucket
  3805  	client, err := New(endpoint, accessID, accessKey)
  3806  	c.Assert(err, IsNil)
  3807  
  3808  	tokenCount := 1
  3809  	err = client.LimitUploadSpeed(tokenCount)
  3810  	if err != nil {
  3811  		// go version is less than go1.7,not support limit upload speed
  3812  		// doesn't run this test
  3813  		return
  3814  	}
  3815  	// set unlimited
  3816  	client.LimitUploadSpeed(0)
  3817  
  3818  	bucketName := bucketNamePrefix + RandLowStr(6)
  3819  	err = client.CreateBucket(bucketName)
  3820  	c.Assert(err, IsNil)
  3821  
  3822  	bucket, err := client.Bucket(bucketName)
  3823  	c.Assert(err, IsNil)
  3824  
  3825  	//first:upload a object
  3826  	textBuffer := RandStr(1024 * 100)
  3827  	objectName := objectNamePrefix + RandStr(8)
  3828  	err = bucket.PutObject(objectName, strings.NewReader(textBuffer))
  3829  	c.Assert(err, IsNil)
  3830  
  3831  	// limit upload speed
  3832  	err = client.LimitUploadSpeed(tokenCount)
  3833  	c.Assert(err, IsNil)
  3834  
  3835  	// then download the object
  3836  	startT := time.Now()
  3837  	body, err := bucket.GetObject(objectName)
  3838  	c.Assert(err, IsNil)
  3839  
  3840  	str, err := readBody(body)
  3841  	c.Assert(err, IsNil)
  3842  	endT := time.Now()
  3843  
  3844  	c.Assert(str, Equals, textBuffer)
  3845  
  3846  	// byte/s
  3847  	downloadSpeed := len(textBuffer) * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
  3848  
  3849  	// upload speed limit parameters will not affect download speed
  3850  	c.Assert(downloadSpeed > 2*tokenCount*perTokenBandwidthSize, Equals, true)
  3851  
  3852  	bucket.DeleteObject(objectName)
  3853  	client.DeleteBucket(bucketName)
  3854  }
  3855  
  3856  // test LimitUploadSpeed failure
  3857  func (s *OssBucketSuite) TestLimitUploadSpeedFail(c *C) {
  3858  	// create limit client and bucket
  3859  	client, err := New(endpoint, accessID, accessKey)
  3860  	c.Assert(err, IsNil)
  3861  
  3862  	err = client.LimitUploadSpeed(-1)
  3863  	c.Assert(err, NotNil)
  3864  
  3865  	client.Config = nil
  3866  	err = client.LimitUploadSpeed(100)
  3867  	c.Assert(err, NotNil)
  3868  }
  3869  
  3870  // upload webp object
  3871  func (s *OssBucketSuite) TestUploadObjectWithWebpFormat(c *C) {
  3872  	client, err := New(endpoint, accessID, accessKey)
  3873  	c.Assert(err, IsNil)
  3874  
  3875  	bucketName := bucketNamePrefix + RandLowStr(6)
  3876  	err = client.CreateBucket(bucketName)
  3877  	c.Assert(err, IsNil)
  3878  
  3879  	bucket, err := client.Bucket(bucketName)
  3880  	c.Assert(err, IsNil)
  3881  
  3882  	// create webp file
  3883  	textBuffer := RandStr(1024)
  3884  	objectName := objectNamePrefix + RandStr(8)
  3885  	fileName := "." + string(os.PathSeparator) + objectName + ".webp"
  3886  	ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
  3887  	_, err = os.Stat(fileName)
  3888  	c.Assert(err, IsNil)
  3889  
  3890  	err = bucket.PutObjectFromFile(objectName, fileName)
  3891  	c.Assert(err, IsNil)
  3892  
  3893  	// check object content-type
  3894  	props, err := bucket.GetObjectDetailedMeta(objectName)
  3895  	c.Assert(err, IsNil)
  3896  	c.Assert(props["Content-Type"][0], Equals, "image/webp")
  3897  
  3898  	os.Remove(fileName)
  3899  	bucket.DeleteObject(objectName)
  3900  	client.DeleteBucket(bucketName)
  3901  }
  3902  
  3903  func (s *OssBucketSuite) TestPutObjectTagging(c *C) {
  3904  	// put object with tagging
  3905  	objectName := objectNamePrefix + RandStr(8)
  3906  	tag1 := Tag{
  3907  		Key:   RandStr(8),
  3908  		Value: RandStr(9),
  3909  	}
  3910  	tag2 := Tag{
  3911  		Key:   RandStr(10),
  3912  		Value: RandStr(11),
  3913  	}
  3914  	tagging := Tagging{
  3915  		Tags: []Tag{tag1, tag2},
  3916  	}
  3917  	err := s.bucket.PutObject(objectName, strings.NewReader(RandStr(1024)), SetTagging(tagging))
  3918  	c.Assert(err, IsNil)
  3919  
  3920  	headers, err := s.bucket.GetObjectDetailedMeta(objectName)
  3921  	taggingCount, err := strconv.Atoi(headers["X-Oss-Tagging-Count"][0])
  3922  	c.Assert(err, IsNil)
  3923  	c.Assert(taggingCount, Equals, 2)
  3924  
  3925  	// copy object with default option
  3926  	destObjectName := objectNamePrefix + RandStr(8)
  3927  	_, err = s.bucket.CopyObject(objectName, destObjectName)
  3928  	c.Assert(err, IsNil)
  3929  	headers, err = s.bucket.GetObjectDetailedMeta(destObjectName)
  3930  	taggingCount, err = strconv.Atoi(headers["X-Oss-Tagging-Count"][0])
  3931  	c.Assert(err, IsNil)
  3932  	c.Assert(taggingCount, Equals, 2)
  3933  
  3934  	// delete object tagging
  3935  	err = s.bucket.DeleteObjectTagging(objectName)
  3936  	c.Assert(err, IsNil)
  3937  
  3938  	// get object tagging again
  3939  	taggingResult, err := s.bucket.GetObjectTagging(objectName)
  3940  	c.Assert(err, IsNil)
  3941  	c.Assert(len(taggingResult.Tags), Equals, 0)
  3942  
  3943  	// put tagging
  3944  	tag := Tag{
  3945  		Key:   RandStr(8),
  3946  		Value: RandStr(16),
  3947  	}
  3948  	tagging.Tags = []Tag{tag}
  3949  	err = s.bucket.PutObjectTagging(objectName, tagging)
  3950  	c.Assert(err, IsNil)
  3951  
  3952  	taggingResult, err = s.bucket.GetObjectTagging(objectName)
  3953  	c.Assert(len(taggingResult.Tags), Equals, 1)
  3954  	c.Assert(taggingResult.Tags[0].Key, Equals, tag.Key)
  3955  	c.Assert(taggingResult.Tags[0].Value, Equals, tag.Value)
  3956  
  3957  	//put tagging, the length of the key exceeds 128
  3958  	tag = Tag{
  3959  		Key:   RandStr(129),
  3960  		Value: RandStr(16),
  3961  	}
  3962  	tagging.Tags = []Tag{tag}
  3963  	err = s.bucket.PutObjectTagging(objectName, tagging)
  3964  	c.Assert(err, NotNil)
  3965  
  3966  	//put tagging, the length of the value exceeds 256
  3967  	tag = Tag{
  3968  		Key:   RandStr(8),
  3969  		Value: RandStr(257),
  3970  	}
  3971  	tagging.Tags = []Tag{tag}
  3972  	err = s.bucket.PutObjectTagging(objectName, tagging)
  3973  	c.Assert(err, NotNil)
  3974  
  3975  	//put tagging, the lens of tags exceed 10
  3976  	tagging.Tags = []Tag{}
  3977  	for i := 0; i < 11; i++ {
  3978  		tag = Tag{
  3979  			Key:   RandStr(8),
  3980  			Value: RandStr(16),
  3981  		}
  3982  		tagging.Tags = append(tagging.Tags, tag)
  3983  	}
  3984  	err = s.bucket.PutObjectTagging(objectName, tagging)
  3985  	c.Assert(err, NotNil)
  3986  
  3987  	//put tagging, invalid value of tag key
  3988  	tag = Tag{
  3989  		Key:   RandStr(8) + "&",
  3990  		Value: RandStr(16),
  3991  	}
  3992  	tagging.Tags = []Tag{tag}
  3993  	err = s.bucket.PutObjectTagging(objectName, tagging)
  3994  	c.Assert(err, NotNil)
  3995  
  3996  	//put tagging, invalid value of tag value
  3997  	tag = Tag{
  3998  		Key:   RandStr(8),
  3999  		Value: RandStr(16) + "&",
  4000  	}
  4001  	tagging.Tags = []Tag{tag}
  4002  	err = s.bucket.PutObjectTagging(objectName, tagging)
  4003  	c.Assert(err, NotNil)
  4004  
  4005  	//put tagging, repeated tag keys
  4006  	tag1 = Tag{
  4007  		Key:   RandStr(8),
  4008  		Value: RandStr(16),
  4009  	}
  4010  	tag2 = Tag{
  4011  		Key:   tag1.Key,
  4012  		Value: RandStr(16),
  4013  	}
  4014  	tagging.Tags = []Tag{tag1, tag2}
  4015  	err = s.bucket.PutObjectTagging(objectName, tagging)
  4016  	c.Assert(err, NotNil)
  4017  
  4018  	s.bucket.DeleteObject(destObjectName)
  4019  	s.bucket.DeleteObject(objectName)
  4020  }
  4021  
  4022  func (s *OssBucketSuite) TestGetObjectTagging(c *C) {
  4023  	// get object which has 2 tags
  4024  	objectName := objectNamePrefix + RandStr(8)
  4025  	tag1 := Tag{
  4026  		Key:   RandStr(8),
  4027  		Value: RandStr(9),
  4028  	}
  4029  	tag2 := Tag{
  4030  		Key:   RandStr(10),
  4031  		Value: RandStr(11),
  4032  	}
  4033  
  4034  	taggingInfo := Tagging{
  4035  		Tags: []Tag{tag1, tag2},
  4036  	}
  4037  
  4038  	err := s.bucket.PutObject(objectName, strings.NewReader(RandStr(1024)), SetTagging(taggingInfo))
  4039  	c.Assert(err, IsNil)
  4040  
  4041  	tagging, err := s.bucket.GetObjectTagging(objectName)
  4042  	c.Assert(len(tagging.Tags), Equals, 2)
  4043  	if tagging.Tags[0].Key == tag1.Key {
  4044  		c.Assert(tagging.Tags[0].Value, Equals, tag1.Value)
  4045  		c.Assert(tagging.Tags[1].Key, Equals, tag2.Key)
  4046  		c.Assert(tagging.Tags[1].Value, Equals, tag2.Value)
  4047  	} else {
  4048  		c.Assert(tagging.Tags[0].Key, Equals, tag2.Key)
  4049  		c.Assert(tagging.Tags[0].Value, Equals, tag2.Value)
  4050  		c.Assert(tagging.Tags[1].Key, Equals, tag1.Key)
  4051  		c.Assert(tagging.Tags[1].Value, Equals, tag1.Value)
  4052  	}
  4053  
  4054  	// get tagging of an object that is not exist
  4055  	err = s.bucket.DeleteObject(objectName)
  4056  	c.Assert(err, IsNil)
  4057  	tagging, err = s.bucket.GetObjectTagging(objectName)
  4058  	c.Assert(err, NotNil)
  4059  	c.Assert(len(tagging.Tags), Equals, 0)
  4060  
  4061  	// get object which has no tag
  4062  	objectName = objectNamePrefix + RandStr(8)
  4063  	err = s.bucket.PutObject(objectName, strings.NewReader(RandStr(1024)))
  4064  	c.Assert(err, IsNil)
  4065  	tagging, err = s.bucket.GetObjectTagging(objectName)
  4066  	c.Assert(err, IsNil)
  4067  	c.Assert(len(tagging.Tags), Equals, 0)
  4068  
  4069  	// copy object, with tagging option
  4070  	destObjectName := objectName + "-dest"
  4071  	tagging.Tags = []Tag{tag1, tag2}
  4072  	_, err = s.bucket.CopyObject(objectName, destObjectName, SetTagging(taggingInfo))
  4073  	c.Assert(err, IsNil)
  4074  	tagging, err = s.bucket.GetObjectTagging(objectName)
  4075  	c.Assert(err, IsNil)
  4076  	c.Assert(len(tagging.Tags), Equals, 0)
  4077  
  4078  	// copy object, with tagging option, the value of tagging directive is "REPLACE"
  4079  	tagging.Tags = []Tag{tag1, tag2}
  4080  	_, err = s.bucket.CopyObject(objectName, destObjectName, SetTagging(taggingInfo), TaggingDirective(TaggingReplace))
  4081  	c.Assert(err, IsNil)
  4082  	tagging, err = s.bucket.GetObjectTagging(destObjectName)
  4083  	c.Assert(err, IsNil)
  4084  	c.Assert(len(tagging.Tags), Equals, 2)
  4085  	if tagging.Tags[0].Key == tag1.Key {
  4086  		c.Assert(tagging.Tags[0].Value, Equals, tag1.Value)
  4087  		c.Assert(tagging.Tags[1].Key, Equals, tag2.Key)
  4088  		c.Assert(tagging.Tags[1].Value, Equals, tag2.Value)
  4089  	} else {
  4090  		c.Assert(tagging.Tags[0].Key, Equals, tag2.Key)
  4091  		c.Assert(tagging.Tags[0].Value, Equals, tag2.Value)
  4092  		c.Assert(tagging.Tags[1].Key, Equals, tag1.Key)
  4093  		c.Assert(tagging.Tags[1].Value, Equals, tag1.Value)
  4094  	}
  4095  
  4096  	s.bucket.DeleteObject(objectName)
  4097  	s.bucket.DeleteObject(destObjectName)
  4098  }
  4099  
  4100  func (s *OssBucketSuite) TestDeleteObjectTagging(c *C) {
  4101  	// delete object tagging, the object is not exist
  4102  	objectName := objectNamePrefix + RandStr(8)
  4103  	err := s.bucket.DeleteObjectTagging(objectName)
  4104  	c.Assert(err, NotNil)
  4105  
  4106  	// delete object tagging
  4107  	tag := Tag{
  4108  		Key:   RandStr(8),
  4109  		Value: RandStr(16),
  4110  	}
  4111  	tagging := Tagging{
  4112  		Tags: []Tag{tag},
  4113  	}
  4114  	err = s.bucket.PutObject(objectName, strings.NewReader(RandStr(1024)), SetTagging(tagging))
  4115  	c.Assert(err, IsNil)
  4116  	err = s.bucket.DeleteObjectTagging(objectName)
  4117  	c.Assert(err, IsNil)
  4118  	taggingResult, err := s.bucket.GetObjectTagging(objectName)
  4119  	c.Assert(err, IsNil)
  4120  	c.Assert(len(taggingResult.Tags), Equals, 0)
  4121  
  4122  	//delete object tagging again
  4123  	err = s.bucket.DeleteObjectTagging(objectName)
  4124  	c.Assert(err, IsNil)
  4125  
  4126  	s.bucket.DeleteObject(objectName)
  4127  }
  4128  
  4129  func (s *OssBucketSuite) TestUploadFileMimeShtml(c *C) {
  4130  	// create a bucket with default proprety
  4131  	client, err := New(endpoint, accessID, accessKey)
  4132  	c.Assert(err, IsNil)
  4133  
  4134  	bucketName := bucketNamePrefix + RandLowStr(6)
  4135  	err = client.CreateBucket(bucketName)
  4136  	c.Assert(err, IsNil)
  4137  
  4138  	bucket, err := client.Bucket(bucketName)
  4139  	objectName := objectNamePrefix + RandStr(8)
  4140  	fileName := "oss-sdk-test-file-" + RandLowStr(5) + ".shtml"
  4141  	CreateFile(fileName, "123", c)
  4142  
  4143  	err = bucket.PutObjectFromFile(objectName, fileName)
  4144  	c.Assert(err, IsNil)
  4145  
  4146  	headResult, err := bucket.GetObjectDetailedMeta(objectName)
  4147  	c.Assert(err, IsNil)
  4148  	strContentType := headResult.Get("Content-Type")
  4149  	c.Assert(strings.Contains(strContentType, "text/html"), Equals, true)
  4150  	os.Remove(fileName)
  4151  	ForceDeleteBucket(client, bucketName, c)
  4152  }
  4153  
  4154  func (s *OssBucketSuite) TestVersioningBucketVerison(c *C) {
  4155  	// create a bucket with default proprety
  4156  	client, err := New(endpoint, accessID, accessKey)
  4157  	c.Assert(err, IsNil)
  4158  
  4159  	bucketName := bucketNamePrefix + RandLowStr(6)
  4160  	err = client.CreateBucket(bucketName)
  4161  	c.Assert(err, IsNil)
  4162  
  4163  	// Get default bucket info
  4164  	bucketResult, err := client.GetBucketInfo(bucketName)
  4165  	c.Assert(err, IsNil)
  4166  
  4167  	c.Assert(bucketResult.BucketInfo.SseRule.KMSMasterKeyID, Equals, "")
  4168  	c.Assert(bucketResult.BucketInfo.SseRule.SSEAlgorithm, Equals, "")
  4169  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, "")
  4170  
  4171  	// put bucket version:enabled
  4172  	var respHeader http.Header
  4173  	var versioningConfig VersioningConfig
  4174  	versioningConfig.Status = string(VersionEnabled)
  4175  	err = client.SetBucketVersioning(bucketName, versioningConfig, GetResponseHeader(&respHeader))
  4176  	c.Assert(err, IsNil)
  4177  	c.Assert(GetRequestId(respHeader) != "", Equals, true)
  4178  	time.Sleep(timeoutInOperation)
  4179  
  4180  	bucketResult, err = client.GetBucketInfo(bucketName)
  4181  	c.Assert(err, IsNil)
  4182  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4183  
  4184  	// put bucket version:Suspended
  4185  	versioningConfig.Status = string(VersionSuspended)
  4186  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4187  	c.Assert(err, IsNil)
  4188  	time.Sleep(timeoutInOperation)
  4189  
  4190  	bucketResult, err = client.GetBucketInfo(bucketName)
  4191  	c.Assert(err, IsNil)
  4192  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionSuspended))
  4193  
  4194  	ForceDeleteBucket(client, bucketName, c)
  4195  }
  4196  
  4197  func (s *OssBucketSuite) TestVersioningPutAndGetObject(c *C) {
  4198  	// create a bucket with default proprety
  4199  	client, err := New(endpoint, accessID, accessKey)
  4200  	c.Assert(err, IsNil)
  4201  
  4202  	bucketName := bucketNamePrefix + RandLowStr(6)
  4203  	err = client.CreateBucket(bucketName)
  4204  	c.Assert(err, IsNil)
  4205  
  4206  	bucket, err := client.Bucket(bucketName)
  4207  
  4208  	// put bucket version:enabled
  4209  	var versioningConfig VersioningConfig
  4210  	versioningConfig.Status = string(VersionEnabled)
  4211  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4212  	c.Assert(err, IsNil)
  4213  	time.Sleep(timeoutInOperation)
  4214  
  4215  	bucketResult, err := client.GetBucketInfo(bucketName)
  4216  	c.Assert(err, IsNil)
  4217  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4218  
  4219  	// put object v1
  4220  	objectName := objectNamePrefix + RandStr(8)
  4221  	contextV1 := RandStr(100)
  4222  	versionIdV1 := ""
  4223  
  4224  	var respHeader http.Header
  4225  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4226  	c.Assert(err, IsNil)
  4227  	versionIdV1 = GetVersionId(respHeader)
  4228  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4229  
  4230  	// put object v2
  4231  	contextV2 := RandStr(200)
  4232  	versionIdV2 := ""
  4233  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4234  	c.Assert(err, IsNil)
  4235  	versionIdV2 = GetVersionId(respHeader)
  4236  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4237  
  4238  	// check v1 and v2
  4239  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4240  
  4241  	// get object v1
  4242  	body, err := bucket.GetObject(objectName, VersionId(versionIdV1))
  4243  	c.Assert(err, IsNil)
  4244  	str, err := readBody(body)
  4245  	c.Assert(err, IsNil)
  4246  	body.Close()
  4247  	c.Assert(str, Equals, contextV1)
  4248  
  4249  	// get object v2
  4250  	body, err = bucket.GetObject(objectName, VersionId(versionIdV2))
  4251  	c.Assert(err, IsNil)
  4252  	str, err = readBody(body)
  4253  	c.Assert(err, IsNil)
  4254  	body.Close()
  4255  	c.Assert(str, Equals, contextV2)
  4256  
  4257  	// get object without version
  4258  	body, err = bucket.GetObject(objectName)
  4259  	c.Assert(err, IsNil)
  4260  	str, err = readBody(body)
  4261  	c.Assert(err, IsNil)
  4262  	body.Close()
  4263  	c.Assert(str, Equals, contextV2)
  4264  
  4265  	err = bucket.DeleteObject(objectName, VersionId(versionIdV1))
  4266  	err = bucket.DeleteObject(objectName, VersionId(versionIdV2))
  4267  	ForceDeleteBucket(client, bucketName, c)
  4268  }
  4269  
  4270  func (s *OssBucketSuite) TestVersioningHeadObject(c *C) {
  4271  	// create a bucket with default proprety
  4272  	client, err := New(endpoint, accessID, accessKey)
  4273  	c.Assert(err, IsNil)
  4274  
  4275  	bucketName := bucketNamePrefix + RandLowStr(6)
  4276  	err = client.CreateBucket(bucketName)
  4277  	c.Assert(err, IsNil)
  4278  
  4279  	bucket, err := client.Bucket(bucketName)
  4280  
  4281  	// put bucket version:enabled
  4282  	var versioningConfig VersioningConfig
  4283  	versioningConfig.Status = string(VersionEnabled)
  4284  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4285  	c.Assert(err, IsNil)
  4286  	time.Sleep(timeoutInOperation)
  4287  
  4288  	bucketResult, err := client.GetBucketInfo(bucketName)
  4289  	c.Assert(err, IsNil)
  4290  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4291  
  4292  	// put object v1
  4293  	objectName := objectNamePrefix + RandStr(8)
  4294  	contextV1 := RandStr(100)
  4295  	versionIdV1 := ""
  4296  
  4297  	var respHeader http.Header
  4298  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4299  	c.Assert(err, IsNil)
  4300  	versionIdV1 = GetVersionId(respHeader)
  4301  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4302  
  4303  	// put object v2
  4304  	contextV2 := RandStr(200)
  4305  	versionIdV2 := ""
  4306  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4307  	c.Assert(err, IsNil)
  4308  	versionIdV2 = GetVersionId(respHeader)
  4309  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4310  
  4311  	// check v1 and v2
  4312  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4313  
  4314  	// head object v1
  4315  	headResultV1, err := bucket.GetObjectMeta(objectName, VersionId(versionIdV1))
  4316  	objLen, err := strconv.Atoi(headResultV1.Get("Content-Length"))
  4317  	c.Assert(objLen, Equals, len(contextV1))
  4318  
  4319  	headResultV1, err = bucket.GetObjectDetailedMeta(objectName, VersionId(versionIdV1))
  4320  	objLen, err = strconv.Atoi(headResultV1.Get("Content-Length"))
  4321  	c.Assert(objLen, Equals, len(contextV1))
  4322  
  4323  	// head object v2
  4324  	headResultV2, err := bucket.GetObjectMeta(objectName, VersionId(versionIdV2))
  4325  	objLen, err = strconv.Atoi(headResultV2.Get("Content-Length"))
  4326  	c.Assert(objLen, Equals, len(contextV2))
  4327  
  4328  	headResultV2, err = bucket.GetObjectDetailedMeta(objectName, VersionId(versionIdV2))
  4329  	objLen, err = strconv.Atoi(headResultV2.Get("Content-Length"))
  4330  	c.Assert(objLen, Equals, len(contextV2))
  4331  
  4332  	// head object without version
  4333  	// head object v2
  4334  	headResult, err := bucket.GetObjectMeta(objectName)
  4335  	objLen, err = strconv.Atoi(headResult.Get("Content-Length"))
  4336  	c.Assert(objLen, Equals, len(contextV2))
  4337  
  4338  	headResult, err = bucket.GetObjectDetailedMeta(objectName)
  4339  	objLen, err = strconv.Atoi(headResultV2.Get("Content-Length"))
  4340  	c.Assert(objLen, Equals, len(contextV2))
  4341  
  4342  	err = bucket.DeleteObject(objectName, VersionId(versionIdV1))
  4343  	err = bucket.DeleteObject(objectName, VersionId(versionIdV2))
  4344  	ForceDeleteBucket(client, bucketName, c)
  4345  }
  4346  
  4347  func (s *OssBucketSuite) TestVersioningDeleteLatestVersionObject(c *C) {
  4348  	// create a bucket with default proprety
  4349  	client, err := New(endpoint, accessID, accessKey)
  4350  	c.Assert(err, IsNil)
  4351  
  4352  	bucketName := bucketNamePrefix + RandLowStr(6)
  4353  	err = client.CreateBucket(bucketName)
  4354  	c.Assert(err, IsNil)
  4355  
  4356  	bucket, err := client.Bucket(bucketName)
  4357  
  4358  	// put bucket version:enabled
  4359  	var versioningConfig VersioningConfig
  4360  	versioningConfig.Status = string(VersionEnabled)
  4361  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4362  	c.Assert(err, IsNil)
  4363  	time.Sleep(timeoutInOperation)
  4364  
  4365  	bucketResult, err := client.GetBucketInfo(bucketName)
  4366  	c.Assert(err, IsNil)
  4367  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4368  
  4369  	// put object v1
  4370  	objectName := objectNamePrefix + RandStr(8)
  4371  	contextV1 := RandStr(100)
  4372  	versionIdV1 := ""
  4373  
  4374  	var respHeader http.Header
  4375  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4376  	c.Assert(err, IsNil)
  4377  	versionIdV1 = GetVersionId(respHeader)
  4378  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4379  
  4380  	// put object v2
  4381  	contextV2 := RandStr(200)
  4382  	versionIdV2 := ""
  4383  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4384  	c.Assert(err, IsNil)
  4385  	versionIdV2 = GetVersionId(respHeader)
  4386  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4387  
  4388  	// check v1 and v2
  4389  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4390  
  4391  	// delete v2 object:permently delete
  4392  	options := []Option{VersionId(versionIdV2), GetResponseHeader(&respHeader)}
  4393  	err = bucket.DeleteObject(objectName, options...)
  4394  	c.Assert(err, IsNil)
  4395  	c.Assert(GetVersionId(respHeader), Equals, versionIdV2)
  4396  
  4397  	// get v2 object failure
  4398  	body, err := bucket.GetObject(objectName, VersionId(versionIdV2))
  4399  	c.Assert(err, NotNil)
  4400  	c.Assert(err.(ServiceError).Code, Equals, "NoSuchVersion")
  4401  
  4402  	// get v1 object success
  4403  	body, err = bucket.GetObject(objectName, VersionId(versionIdV1))
  4404  	c.Assert(err, IsNil)
  4405  	str, err := readBody(body)
  4406  	body.Close()
  4407  	c.Assert(err, IsNil)
  4408  	c.Assert(str, Equals, contextV1)
  4409  
  4410  	// get default object success:v1
  4411  	body, err = bucket.GetObject(objectName)
  4412  	c.Assert(err, IsNil)
  4413  	str, err = readBody(body)
  4414  	body.Close()
  4415  	c.Assert(err, IsNil)
  4416  	c.Assert(str, Equals, contextV1)
  4417  
  4418  	err = bucket.DeleteObject(objectName, VersionId(versionIdV1))
  4419  	err = bucket.DeleteObject(objectName, VersionId(versionIdV2))
  4420  	ForceDeleteBucket(client, bucketName, c)
  4421  }
  4422  
  4423  func (s *OssBucketSuite) TestVersioningDeleteOldVersionObject(c *C) {
  4424  	// create a bucket with default proprety
  4425  	client, err := New(endpoint, accessID, accessKey)
  4426  	c.Assert(err, IsNil)
  4427  
  4428  	bucketName := bucketNamePrefix + RandLowStr(6)
  4429  	err = client.CreateBucket(bucketName)
  4430  	c.Assert(err, IsNil)
  4431  
  4432  	bucket, err := client.Bucket(bucketName)
  4433  
  4434  	// put bucket version:enabled
  4435  	var versioningConfig VersioningConfig
  4436  	versioningConfig.Status = string(VersionEnabled)
  4437  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4438  	c.Assert(err, IsNil)
  4439  	time.Sleep(timeoutInOperation)
  4440  	time.Sleep(timeoutInOperation)
  4441  
  4442  	bucketResult, err := client.GetBucketInfo(bucketName)
  4443  	c.Assert(err, IsNil)
  4444  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4445  
  4446  	// put object v1
  4447  	objectName := objectNamePrefix + RandStr(8)
  4448  	contextV1 := RandStr(100)
  4449  	versionIdV1 := ""
  4450  
  4451  	var respHeader http.Header
  4452  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4453  	c.Assert(err, IsNil)
  4454  	versionIdV1 = GetVersionId(respHeader)
  4455  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4456  
  4457  	// put object v2
  4458  	contextV2 := RandStr(200)
  4459  	versionIdV2 := ""
  4460  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4461  	c.Assert(err, IsNil)
  4462  	versionIdV2 = GetVersionId(respHeader)
  4463  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4464  
  4465  	// check v1 and v2
  4466  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4467  
  4468  	// delete v1 object:permently delete
  4469  	options := []Option{VersionId(versionIdV1), GetResponseHeader(&respHeader)}
  4470  	err = bucket.DeleteObject(objectName, options...)
  4471  	c.Assert(err, IsNil)
  4472  	c.Assert(GetVersionId(respHeader), Equals, versionIdV1)
  4473  
  4474  	// get v2 object success
  4475  	body, err := bucket.GetObject(objectName, VersionId(versionIdV2))
  4476  	c.Assert(err, IsNil)
  4477  	str, err := readBody(body)
  4478  	body.Close()
  4479  	c.Assert(err, IsNil)
  4480  	c.Assert(str, Equals, contextV2)
  4481  
  4482  	// get v1 object faliure
  4483  	body, err = bucket.GetObject(objectName, VersionId(versionIdV1))
  4484  	c.Assert(err, NotNil)
  4485  	c.Assert(err.(ServiceError).Code, Equals, "NoSuchVersion")
  4486  
  4487  	// get default object success:v2
  4488  	body, err = bucket.GetObject(objectName)
  4489  	c.Assert(err, IsNil)
  4490  	str, err = readBody(body)
  4491  	body.Close()
  4492  	c.Assert(err, IsNil)
  4493  	c.Assert(str, Equals, contextV2)
  4494  
  4495  	err = bucket.DeleteObject(objectName, VersionId(versionIdV1))
  4496  	err = bucket.DeleteObject(objectName, VersionId(versionIdV2))
  4497  	ForceDeleteBucket(client, bucketName, c)
  4498  }
  4499  
  4500  func (s *OssBucketSuite) TestVersioningDeleteDefaultVersionObject(c *C) {
  4501  	// create a bucket with default proprety
  4502  	client, err := New(endpoint, accessID, accessKey)
  4503  	c.Assert(err, IsNil)
  4504  
  4505  	bucketName := bucketNamePrefix + RandLowStr(6)
  4506  	err = client.CreateBucket(bucketName)
  4507  	c.Assert(err, IsNil)
  4508  
  4509  	bucket, err := client.Bucket(bucketName)
  4510  
  4511  	// put bucket version:enabled
  4512  	var versioningConfig VersioningConfig
  4513  	versioningConfig.Status = string(VersionEnabled)
  4514  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4515  	c.Assert(err, IsNil)
  4516  	time.Sleep(timeoutInOperation)
  4517  
  4518  	bucketResult, err := client.GetBucketInfo(bucketName)
  4519  	c.Assert(err, IsNil)
  4520  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4521  
  4522  	// put object v1
  4523  	objectName := objectNamePrefix + RandStr(8)
  4524  	contextV1 := RandStr(100)
  4525  	versionIdV1 := ""
  4526  
  4527  	var respHeader http.Header
  4528  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4529  	c.Assert(err, IsNil)
  4530  	versionIdV1 = GetVersionId(respHeader)
  4531  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4532  
  4533  	// put object v2
  4534  	contextV2 := RandStr(200)
  4535  	versionIdV2 := ""
  4536  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4537  	c.Assert(err, IsNil)
  4538  	versionIdV2 = GetVersionId(respHeader)
  4539  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4540  
  4541  	// check v1 and v2
  4542  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4543  
  4544  	// delete default object:mark delete v2
  4545  	options := []Option{GetResponseHeader(&respHeader)}
  4546  	err = bucket.DeleteObject(objectName, options...)
  4547  	c.Assert(err, IsNil)
  4548  
  4549  	markVersionId := GetVersionId(respHeader)
  4550  	c.Assert(len(markVersionId) > 0, Equals, true)
  4551  	c.Assert(respHeader.Get("x-oss-delete-marker"), Equals, "true")
  4552  
  4553  	// get v2 object success
  4554  	body, err := bucket.GetObject(objectName, VersionId(versionIdV2))
  4555  	c.Assert(err, IsNil)
  4556  	str, err := readBody(body)
  4557  	body.Close()
  4558  	c.Assert(err, IsNil)
  4559  	c.Assert(str, Equals, contextV2)
  4560  
  4561  	// get v1 object success
  4562  	body, err = bucket.GetObject(objectName, VersionId(versionIdV1))
  4563  	c.Assert(err, IsNil)
  4564  	str, err = readBody(body)
  4565  	body.Close()
  4566  	c.Assert(err, IsNil)
  4567  	c.Assert(str, Equals, contextV1)
  4568  
  4569  	// get default object failure:marker v2
  4570  	body, err = bucket.GetObject(objectName, GetResponseHeader(&respHeader))
  4571  	c.Assert(err, NotNil)
  4572  	c.Assert(err.(ServiceError).Code, Equals, "NoSuchKey")
  4573  	c.Assert(respHeader.Get("x-oss-delete-marker"), Equals, "true")
  4574  
  4575  	// delete mark v2
  4576  	options = []Option{VersionId(markVersionId), GetResponseHeader(&respHeader)}
  4577  	err = bucket.DeleteObject(objectName, options...)
  4578  	c.Assert(err, IsNil)
  4579  	c.Assert(GetVersionId(respHeader), Equals, markVersionId)
  4580  
  4581  	// get default object success:v2
  4582  	body, err = bucket.GetObject(objectName, VersionId(versionIdV2))
  4583  	c.Assert(err, IsNil)
  4584  	str, err = readBody(body)
  4585  	body.Close()
  4586  	c.Assert(err, IsNil)
  4587  	c.Assert(str, Equals, contextV2)
  4588  
  4589  	err = bucket.DeleteObject(objectName, VersionId(versionIdV1))
  4590  	err = bucket.DeleteObject(objectName, VersionId(versionIdV2))
  4591  	ForceDeleteBucket(client, bucketName, c)
  4592  }
  4593  
  4594  func (s *OssBucketSuite) TestVersioningListObjectVersions(c *C) {
  4595  	// create a bucket with default proprety
  4596  	client, err := New(endpoint, accessID, accessKey)
  4597  	c.Assert(err, IsNil)
  4598  
  4599  	bucketName := bucketNamePrefix + RandLowStr(6)
  4600  	err = client.CreateBucket(bucketName)
  4601  	c.Assert(err, IsNil)
  4602  
  4603  	bucket, err := client.Bucket(bucketName)
  4604  
  4605  	// put bucket version:enabled
  4606  	var versioningConfig VersioningConfig
  4607  	versioningConfig.Status = string(VersionEnabled)
  4608  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4609  	c.Assert(err, IsNil)
  4610  	time.Sleep(timeoutInOperation)
  4611  
  4612  	bucketResult, err := client.GetBucketInfo(bucketName)
  4613  	c.Assert(err, IsNil)
  4614  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4615  
  4616  	// put object v1
  4617  	objectName := objectNamePrefix + RandStr(8)
  4618  	contextV1 := RandStr(100)
  4619  	versionIdV1 := ""
  4620  
  4621  	var respHeader http.Header
  4622  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4623  	c.Assert(err, IsNil)
  4624  	versionIdV1 = GetVersionId(respHeader)
  4625  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4626  
  4627  	// put object v2
  4628  	contextV2 := RandStr(200)
  4629  	versionIdV2 := ""
  4630  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4631  	c.Assert(err, IsNil)
  4632  	versionIdV2 = GetVersionId(respHeader)
  4633  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4634  
  4635  	// check v1 and v2
  4636  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4637  
  4638  	// delete default object:mark delete v2
  4639  	options := []Option{GetResponseHeader(&respHeader)}
  4640  	err = bucket.DeleteObject(objectName, options...)
  4641  	c.Assert(err, IsNil)
  4642  
  4643  	markVersionId := GetVersionId(respHeader)
  4644  	c.Assert(len(markVersionId) > 0, Equals, true)
  4645  	c.Assert(respHeader.Get("x-oss-delete-marker"), Equals, "true")
  4646  
  4647  	// delete default object again:mark delete v2
  4648  	err = bucket.DeleteObject(objectName, options...)
  4649  	c.Assert(err, IsNil)
  4650  	markVersionIdAgain := GetVersionId(respHeader)
  4651  	c.Assert(len(markVersionIdAgain) > 0, Equals, true)
  4652  	c.Assert(respHeader.Get("x-oss-delete-marker"), Equals, "true")
  4653  	c.Assert(markVersionId != markVersionIdAgain, Equals, true)
  4654  
  4655  	// list bucket versions
  4656  	listResult, err := bucket.ListObjectVersions()
  4657  	c.Assert(err, IsNil)
  4658  	c.Assert(len(listResult.ObjectDeleteMarkers), Equals, 2)
  4659  	c.Assert(len(listResult.ObjectVersions), Equals, 2)
  4660  	mapMarkVersion := map[string]string{}
  4661  	mapMarkVersion[listResult.ObjectDeleteMarkers[0].VersionId] = listResult.ObjectDeleteMarkers[0].VersionId
  4662  	mapMarkVersion[listResult.ObjectDeleteMarkers[1].VersionId] = listResult.ObjectDeleteMarkers[1].VersionId
  4663  
  4664  	// check delete mark
  4665  	_, ok := mapMarkVersion[markVersionId]
  4666  	c.Assert(ok == true, Equals, true)
  4667  	_, ok = mapMarkVersion[markVersionIdAgain]
  4668  	c.Assert(ok == true, Equals, true)
  4669  
  4670  	// check versionId
  4671  	mapVersion := map[string]string{}
  4672  	mapVersion[listResult.ObjectVersions[0].VersionId] = listResult.ObjectVersions[0].VersionId
  4673  	mapVersion[listResult.ObjectVersions[1].VersionId] = listResult.ObjectVersions[1].VersionId
  4674  	_, ok = mapVersion[versionIdV1]
  4675  	c.Assert(ok == true, Equals, true)
  4676  	_, ok = mapVersion[versionIdV2]
  4677  	c.Assert(ok == true, Equals, true)
  4678  
  4679  	// delete deleteMark v2
  4680  	options = []Option{VersionId(markVersionId), GetResponseHeader(&respHeader)}
  4681  	err = bucket.DeleteObject(objectName, options...)
  4682  	c.Assert(err, IsNil)
  4683  	c.Assert(GetVersionId(respHeader), Equals, markVersionId)
  4684  
  4685  	// delete deleteMark v2 again
  4686  	options = []Option{VersionId(markVersionIdAgain), GetResponseHeader(&respHeader)}
  4687  	err = bucket.DeleteObject(objectName, options...)
  4688  	c.Assert(err, IsNil)
  4689  	c.Assert(GetVersionId(respHeader), Equals, markVersionIdAgain)
  4690  
  4691  	// delete versionId
  4692  	bucket.DeleteObject(objectName, VersionId(versionIdV1))
  4693  	bucket.DeleteObject(objectName, VersionId(versionIdV2))
  4694  	ForceDeleteBucket(client, bucketName, c)
  4695  }
  4696  
  4697  func (s *OssBucketSuite) TestVersioningBatchDeleteVersionObjects(c *C) {
  4698  	// create a bucket with default proprety
  4699  	client, err := New(endpoint, accessID, accessKey)
  4700  	c.Assert(err, IsNil)
  4701  
  4702  	bucketName := bucketNamePrefix + RandLowStr(6)
  4703  	err = client.CreateBucket(bucketName)
  4704  	c.Assert(err, IsNil)
  4705  
  4706  	bucket, err := client.Bucket(bucketName)
  4707  
  4708  	// put bucket version:enabled
  4709  	var versioningConfig VersioningConfig
  4710  	versioningConfig.Status = string(VersionEnabled)
  4711  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4712  	c.Assert(err, IsNil)
  4713  	time.Sleep(timeoutInOperation)
  4714  	time.Sleep(timeoutInOperation)
  4715  
  4716  	bucketResult, err := client.GetBucketInfo(bucketName)
  4717  	c.Assert(err, IsNil)
  4718  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4719  
  4720  	// put object v1
  4721  	objectName1 := objectNamePrefix + RandStr(8)
  4722  	contextV1 := RandStr(100)
  4723  	versionIdV1 := ""
  4724  
  4725  	var respHeader http.Header
  4726  	err = bucket.PutObject(objectName1, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4727  	c.Assert(err, IsNil)
  4728  	versionIdV1 = GetVersionId(respHeader)
  4729  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4730  
  4731  	// put object v2
  4732  	objectName2 := objectNamePrefix + RandStr(8)
  4733  	contextV2 := RandStr(200)
  4734  	versionIdV2 := ""
  4735  	err = bucket.PutObject(objectName2, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4736  	c.Assert(err, IsNil)
  4737  	versionIdV2 = GetVersionId(respHeader)
  4738  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4739  
  4740  	// check v1 and v2
  4741  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4742  
  4743  	//batch delete objects
  4744  	versionIds := []DeleteObject{{Key: objectName1, VersionId: versionIdV1},
  4745  		{Key: objectName2, VersionId: versionIdV2}}
  4746  	deleteResult, err := bucket.DeleteObjectVersions(versionIds)
  4747  	c.Assert(err, IsNil)
  4748  	c.Assert(len(deleteResult.DeletedObjectsDetail), Equals, 2)
  4749  
  4750  	// check delete detail info:key
  4751  	deleteMap := map[string]string{}
  4752  	deleteMap[deleteResult.DeletedObjectsDetail[0].Key] = deleteResult.DeletedObjectsDetail[0].VersionId
  4753  	deleteMap[deleteResult.DeletedObjectsDetail[1].Key] = deleteResult.DeletedObjectsDetail[1].VersionId
  4754  	id1, ok := deleteMap[objectName1]
  4755  	c.Assert(ok, Equals, true)
  4756  	c.Assert(id1, Equals, versionIdV1)
  4757  
  4758  	id2, ok := deleteMap[objectName2]
  4759  	c.Assert(ok, Equals, true)
  4760  	c.Assert(id2, Equals, versionIdV2)
  4761  
  4762  	// special key
  4763  	objectName2 = objectNamePrefix + "\f" + RandLowStr(5)
  4764  	contextV2 = RandStr(200)
  4765  	versionIdV2 = ""
  4766  	err = bucket.PutObject(objectName2, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4767  	c.Assert(err, IsNil)
  4768  	versionIdV2 = GetVersionId(respHeader)
  4769  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4770  
  4771  	// check v1 and v2
  4772  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4773  
  4774  	//batch delete objects
  4775  	versionIds = []DeleteObject{{Key: objectName1, VersionId: versionIdV1},
  4776  		{Key: objectName2, VersionId: versionIdV2}}
  4777  	deleteResult, err = bucket.DeleteObjectVersions(versionIds)
  4778  	c.Assert(err, IsNil)
  4779  	c.Assert(len(deleteResult.DeletedObjectsDetail), Equals, 2)
  4780  
  4781  	// special key
  4782  	str := "\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
  4783  	objectName2 = objectNamePrefix + str + RandLowStr(5)
  4784  	contextV2 = RandStr(200)
  4785  	versionIdV2 = ""
  4786  	err = bucket.PutObject(objectName2, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4787  	c.Assert(err, IsNil)
  4788  	versionIdV2 = GetVersionId(respHeader)
  4789  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4790  
  4791  	// check v1 and v2
  4792  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4793  
  4794  	//batch delete objects
  4795  	versionIds = []DeleteObject{{Key: objectName1, VersionId: versionIdV1},
  4796  		{Key: objectName2, VersionId: versionIdV2}}
  4797  	deleteResult, err = bucket.DeleteObjectVersions(versionIds)
  4798  	c.Assert(err, IsNil)
  4799  	c.Assert(len(deleteResult.DeletedObjectsDetail), Equals, 2)
  4800  
  4801  	ForceDeleteBucket(client, bucketName, c)
  4802  }
  4803  
  4804  func (s *OssBucketSuite) TestVersioningBatchDeleteDefaultVersionObjects(c *C) {
  4805  	// create a bucket with default proprety
  4806  	client, err := New(endpoint, accessID, accessKey)
  4807  	c.Assert(err, IsNil)
  4808  
  4809  	bucketName := bucketNamePrefix + RandLowStr(6)
  4810  	err = client.CreateBucket(bucketName)
  4811  	c.Assert(err, IsNil)
  4812  
  4813  	bucket, err := client.Bucket(bucketName)
  4814  
  4815  	// put bucket version:enabled
  4816  	var versioningConfig VersioningConfig
  4817  	versioningConfig.Status = string(VersionEnabled)
  4818  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4819  	c.Assert(err, IsNil)
  4820  	time.Sleep(timeoutInOperation)
  4821  
  4822  	bucketResult, err := client.GetBucketInfo(bucketName)
  4823  	c.Assert(err, IsNil)
  4824  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  4825  
  4826  	// put object v1
  4827  	objectName1 := objectNamePrefix + RandStr(8)
  4828  	contextV1 := RandStr(100)
  4829  	versionIdV1 := ""
  4830  
  4831  	var respHeader http.Header
  4832  	err = bucket.PutObject(objectName1, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4833  	c.Assert(err, IsNil)
  4834  	versionIdV1 = GetVersionId(respHeader)
  4835  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4836  
  4837  	// put object v2
  4838  	objectName2 := objectNamePrefix + RandStr(8)
  4839  	contextV2 := RandStr(200)
  4840  	versionIdV2 := ""
  4841  	err = bucket.PutObject(objectName2, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4842  	c.Assert(err, IsNil)
  4843  	versionIdV2 = GetVersionId(respHeader)
  4844  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4845  
  4846  	// check v1 and v2
  4847  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4848  
  4849  	//batch delete objects
  4850  	versionIds := []DeleteObject{{Key: objectName1, VersionId: ""},
  4851  		{Key: objectName2, VersionId: ""}}
  4852  	deleteResult, err := bucket.DeleteObjectVersions(versionIds)
  4853  	c.Assert(err, IsNil)
  4854  
  4855  	// check delete detail info:key
  4856  	deleteDetailMap := map[string]DeletedKeyInfo{}
  4857  	deleteDetailMap[deleteResult.DeletedObjectsDetail[0].Key] = deleteResult.DeletedObjectsDetail[0]
  4858  	deleteDetailMap[deleteResult.DeletedObjectsDetail[1].Key] = deleteResult.DeletedObjectsDetail[1]
  4859  	keyInfo1, ok := deleteDetailMap[objectName1]
  4860  	c.Assert(ok, Equals, true)
  4861  	c.Assert(keyInfo1.Key, Equals, objectName1)
  4862  	c.Assert(keyInfo1.VersionId, Equals, "")
  4863  	c.Assert(keyInfo1.DeleteMarker, Equals, true)
  4864  	c.Assert(keyInfo1.DeleteMarkerVersionId != versionIdV1, Equals, true)
  4865  
  4866  	keyInfo2, ok := deleteDetailMap[objectName2]
  4867  	c.Assert(ok, Equals, true)
  4868  	c.Assert(keyInfo2.Key, Equals, objectName2)
  4869  	c.Assert(keyInfo2.VersionId, Equals, "")
  4870  	c.Assert(keyInfo2.DeleteMarker, Equals, true)
  4871  	c.Assert(keyInfo2.DeleteMarkerVersionId != versionIdV2, Equals, true)
  4872  
  4873  	// list bucket versions
  4874  	listResult, err := bucket.ListObjectVersions()
  4875  	c.Assert(err, IsNil)
  4876  	c.Assert(len(listResult.ObjectDeleteMarkers), Equals, 2)
  4877  	c.Assert(len(listResult.ObjectVersions), Equals, 2)
  4878  
  4879  	// delete version object
  4880  	versionIds = []DeleteObject{{Key: objectName1, VersionId: versionIdV1},
  4881  		{Key: objectName2, VersionId: versionIdV2}}
  4882  	deleteResult, err = bucket.DeleteObjectVersions(versionIds)
  4883  	c.Assert(err, IsNil)
  4884  
  4885  	// delete deleteMark object
  4886  	versionIds = []DeleteObject{{Key: objectName1, VersionId: keyInfo1.DeleteMarkerVersionId},
  4887  		{Key: objectName2, VersionId: keyInfo2.DeleteMarkerVersionId}}
  4888  	deleteResult, err = bucket.DeleteObjectVersions(versionIds)
  4889  	c.Assert(err, IsNil)
  4890  
  4891  	ForceDeleteBucket(client, bucketName, c)
  4892  }
  4893  
  4894  // bucket has no versioning flag
  4895  func (s *OssBucketSuite) TestVersioningBatchDeleteNormalObjects(c *C) {
  4896  	// create a bucket with default proprety
  4897  	client, err := New(endpoint, accessID, accessKey)
  4898  	c.Assert(err, IsNil)
  4899  
  4900  	bucketName := bucketNamePrefix + RandLowStr(6)
  4901  	err = client.CreateBucket(bucketName)
  4902  	c.Assert(err, IsNil)
  4903  
  4904  	// not put bucket versioning
  4905  
  4906  	bucket, err := client.Bucket(bucketName)
  4907  
  4908  	// put object v1
  4909  	objectName1 := objectNamePrefix + RandStr(8)
  4910  	contextV1 := RandStr(100)
  4911  	versionIdV1 := ""
  4912  
  4913  	var respHeader http.Header
  4914  	err = bucket.PutObject(objectName1, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4915  	c.Assert(err, IsNil)
  4916  	versionIdV1 = GetVersionId(respHeader)
  4917  	c.Assert(len(versionIdV1), Equals, 0)
  4918  
  4919  	// put object v2
  4920  	objectName2 := objectNamePrefix + RandStr(8)
  4921  	contextV2 := RandStr(200)
  4922  	versionIdV2 := ""
  4923  	err = bucket.PutObject(objectName2, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4924  	c.Assert(err, IsNil)
  4925  	versionIdV2 = GetVersionId(respHeader)
  4926  	c.Assert(len(versionIdV2), Equals, 0)
  4927  
  4928  	//batch delete objects
  4929  	keys := []string{objectName1, objectName2}
  4930  	deleteResult, err := bucket.DeleteObjects(keys)
  4931  	c.Assert(len(deleteResult.DeletedObjects), Equals, 2)
  4932  
  4933  	// check delete info
  4934  	deleteMap := map[string]string{}
  4935  	deleteMap[deleteResult.DeletedObjects[0]] = deleteResult.DeletedObjects[0]
  4936  	deleteMap[deleteResult.DeletedObjects[1]] = deleteResult.DeletedObjects[1]
  4937  	_, ok := deleteMap[objectName1]
  4938  	c.Assert(ok, Equals, true)
  4939  	_, ok = deleteMap[objectName2]
  4940  	c.Assert(ok, Equals, true)
  4941  
  4942  	ForceDeleteBucket(client, bucketName, c)
  4943  	c.Assert(err, IsNil)
  4944  }
  4945  
  4946  func (s *OssBucketSuite) TestVersioningSymlink(c *C) {
  4947  	// create a bucket with default proprety
  4948  	client, err := New(endpoint, accessID, accessKey)
  4949  	c.Assert(err, IsNil)
  4950  
  4951  	bucketName := bucketNamePrefix + RandLowStr(6)
  4952  	err = client.CreateBucket(bucketName)
  4953  	c.Assert(err, IsNil)
  4954  
  4955  	bucket, err := client.Bucket(bucketName)
  4956  
  4957  	// put bucket version:enabled
  4958  	var versioningConfig VersioningConfig
  4959  	versioningConfig.Status = string(VersionEnabled)
  4960  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  4961  	c.Assert(err, IsNil)
  4962  	time.Sleep(timeoutInOperation)
  4963  
  4964  	// put object 1
  4965  	objectName1 := objectNamePrefix + RandStr(8)
  4966  	contextV1 := RandStr(100)
  4967  	versionIdV1 := ""
  4968  
  4969  	var respHeader http.Header
  4970  	err = bucket.PutObject(objectName1, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  4971  	c.Assert(err, IsNil)
  4972  	versionIdV1 = GetVersionId(respHeader)
  4973  	c.Assert(len(versionIdV1) > 0, Equals, true)
  4974  
  4975  	// put object 2
  4976  	objectName2 := objectNamePrefix + RandStr(8)
  4977  	contextV2 := RandStr(200)
  4978  	versionIdV2 := ""
  4979  	err = bucket.PutObject(objectName2, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  4980  	c.Assert(err, IsNil)
  4981  	versionIdV2 = GetVersionId(respHeader)
  4982  	c.Assert(len(versionIdV2) > 0, Equals, true)
  4983  
  4984  	// check v1 and v2
  4985  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  4986  
  4987  	// put symlink for object 1
  4988  	linkName := objectNamePrefix + RandStr(8)
  4989  	err = bucket.PutSymlink(linkName, objectName1, GetResponseHeader(&respHeader))
  4990  	c.Assert(err, IsNil)
  4991  	linkVersionIdV1 := GetVersionId(respHeader)
  4992  
  4993  	// PutSymlink for object 2
  4994  	err = bucket.PutSymlink(linkName, objectName2, GetResponseHeader(&respHeader))
  4995  	c.Assert(err, IsNil)
  4996  	linkVersionIdV2 := GetVersionId(respHeader)
  4997  
  4998  	// check v1 and v2
  4999  	c.Assert(linkVersionIdV1 != linkVersionIdV2, Equals, true)
  5000  
  5001  	// GetSymlink for object1
  5002  	getResult, err := bucket.GetSymlink(linkName, VersionId(linkVersionIdV1))
  5003  	c.Assert(err, IsNil)
  5004  	c.Assert(getResult.Get("x-oss-symlink-target"), Equals, objectName1)
  5005  
  5006  	// GetSymlink for object2
  5007  	getResult, err = bucket.GetSymlink(linkName, VersionId(linkVersionIdV2))
  5008  	c.Assert(err, IsNil)
  5009  	c.Assert(getResult.Get("x-oss-symlink-target"), Equals, objectName2)
  5010  
  5011  	bucket.DeleteObject(linkName)
  5012  	bucket.DeleteObject(objectName1)
  5013  	bucket.DeleteObject(objectName2)
  5014  	ForceDeleteBucket(client, bucketName, c)
  5015  }
  5016  
  5017  func (s *OssBucketSuite) TestVersioningObjectAcl(c *C) {
  5018  	// create a bucket with default proprety
  5019  	client, err := New(endpoint, accessID, accessKey)
  5020  	c.Assert(err, IsNil)
  5021  
  5022  	bucketName := bucketNamePrefix + RandLowStr(6)
  5023  	err = client.CreateBucket(bucketName)
  5024  	c.Assert(err, IsNil)
  5025  
  5026  	bucket, err := client.Bucket(bucketName)
  5027  
  5028  	// put bucket version:enabled
  5029  	var versioningConfig VersioningConfig
  5030  	versioningConfig.Status = string(VersionEnabled)
  5031  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5032  	c.Assert(err, IsNil)
  5033  	time.Sleep(timeoutInOperation)
  5034  
  5035  	// put object v1
  5036  	objectName := objectNamePrefix + RandStr(8)
  5037  	contextV1 := RandStr(100)
  5038  	versionIdV1 := ""
  5039  
  5040  	var respHeader http.Header
  5041  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  5042  	c.Assert(err, IsNil)
  5043  	versionIdV1 = GetVersionId(respHeader)
  5044  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5045  
  5046  	// put object v2
  5047  	contextV2 := RandStr(200)
  5048  	versionIdV2 := ""
  5049  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  5050  	c.Assert(err, IsNil)
  5051  	versionIdV2 = GetVersionId(respHeader)
  5052  	c.Assert(len(versionIdV2) > 0, Equals, true)
  5053  
  5054  	// check v1 and v2
  5055  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  5056  
  5057  	// put Acl for v1
  5058  	err = bucket.SetObjectACL(objectName, ACLPublicRead, VersionId(versionIdV1))
  5059  	c.Assert(err, IsNil)
  5060  
  5061  	// put Acl for v2
  5062  	err = bucket.SetObjectACL(objectName, ACLPublicReadWrite, VersionId(versionIdV2))
  5063  	c.Assert(err, IsNil)
  5064  
  5065  	// GetAcl for v1
  5066  	getResult, err := bucket.GetObjectACL(objectName, VersionId(versionIdV1))
  5067  	c.Assert(err, IsNil)
  5068  	c.Assert(getResult.ACL, Equals, string(ACLPublicRead))
  5069  
  5070  	// GetAcl for v2
  5071  	getResult, err = bucket.GetObjectACL(objectName, VersionId(versionIdV2))
  5072  	c.Assert(err, IsNil)
  5073  	c.Assert(getResult.ACL, Equals, string(ACLPublicReadWrite))
  5074  
  5075  	// delete default version
  5076  	err = bucket.DeleteObject(objectName, GetResponseHeader(&respHeader))
  5077  	c.Assert(len(GetVersionId(respHeader)) > 0, Equals, true)
  5078  	c.Assert(respHeader.Get("x-oss-delete-marker"), Equals, "true")
  5079  
  5080  	// GetAcl for v1 agagin
  5081  	getResult, err = bucket.GetObjectACL(objectName, VersionId(versionIdV1))
  5082  	c.Assert(err, IsNil)
  5083  	c.Assert(getResult.ACL, Equals, string(ACLPublicRead))
  5084  
  5085  	// GetAcl for v2 again
  5086  	getResult, err = bucket.GetObjectACL(objectName, VersionId(versionIdV2))
  5087  	c.Assert(err, IsNil)
  5088  	c.Assert(getResult.ACL, Equals, string(ACLPublicReadWrite))
  5089  
  5090  	// GetAcl for default failure
  5091  	getResult, err = bucket.GetObjectACL(objectName)
  5092  	c.Assert(err, NotNil)
  5093  
  5094  	bucket.DeleteObject(objectName)
  5095  	ForceDeleteBucket(client, bucketName, c)
  5096  }
  5097  
  5098  func (s *OssBucketSuite) TestVersioningAppendObject(c *C) {
  5099  	// create a bucket with default proprety
  5100  	client, err := New(endpoint, accessID, accessKey)
  5101  	c.Assert(err, IsNil)
  5102  
  5103  	bucketName := bucketNamePrefix + RandLowStr(6)
  5104  	err = client.CreateBucket(bucketName)
  5105  	c.Assert(err, IsNil)
  5106  
  5107  	bucket, err := client.Bucket(bucketName)
  5108  
  5109  	// put bucket version:enabled
  5110  	var versioningConfig VersioningConfig
  5111  	versioningConfig.Status = string(VersionEnabled)
  5112  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5113  	c.Assert(err, IsNil)
  5114  	time.Sleep(timeoutInOperation)
  5115  
  5116  	// append object
  5117  	var nextPos int64 = 0
  5118  	var respHeader http.Header
  5119  	objectName := objectNamePrefix + RandStr(8)
  5120  	nextPos, err = bucket.AppendObject(objectName, strings.NewReader("123"), nextPos, GetResponseHeader(&respHeader))
  5121  	c.Assert(err, IsNil)
  5122  	versionId := GetVersionId(respHeader)
  5123  	c.Assert(versionId == NullVersion, Equals, false)
  5124  
  5125  	nextPos, err = bucket.AppendObject(objectName, strings.NewReader("456"), nextPos, GetResponseHeader(&respHeader))
  5126  	c.Assert(err, IsNil)
  5127  	versionId = GetVersionId(respHeader)
  5128  	c.Assert(versionId == NullVersion, Equals, false)
  5129  
  5130  	// delete object
  5131  	err = bucket.DeleteObject(objectName, GetResponseHeader(&respHeader))
  5132  	markVersionId := GetVersionId(respHeader)
  5133  
  5134  	// get default object failure
  5135  	_, err = bucket.GetObject(objectName)
  5136  	c.Assert(err, NotNil)
  5137  
  5138  	// get version success
  5139  	body, err := bucket.GetObject(objectName, VersionId(versionId))
  5140  	c.Assert(err, IsNil)
  5141  	str, err := readBody(body)
  5142  	c.Assert(err, IsNil)
  5143  	c.Assert(str, Equals, "123456")
  5144  
  5145  	// append object again:success
  5146  	nextPos, err = bucket.AppendObject(objectName, strings.NewReader("789"), 0, GetResponseHeader(&respHeader))
  5147  	c.Assert(err, IsNil)
  5148  
  5149  	// delete deletemark
  5150  	options := []Option{VersionId(markVersionId), GetResponseHeader(&respHeader)}
  5151  	err = bucket.DeleteObject(objectName, options...)
  5152  	c.Assert(markVersionId, Equals, GetVersionId(respHeader))
  5153  
  5154  	// append object again:success
  5155  	nextPos, err = bucket.AppendObject(objectName, strings.NewReader("789"), nextPos, GetResponseHeader(&respHeader))
  5156  	c.Assert(err, IsNil)
  5157  	c.Assert(int(nextPos), Equals, 6)
  5158  
  5159  	bucket.DeleteObject(objectName)
  5160  	ForceDeleteBucket(client, bucketName, c)
  5161  }
  5162  
  5163  func (s *OssBucketSuite) TestVersioningCopyObject(c *C) {
  5164  	// create a bucket with default proprety
  5165  	client, err := New(endpoint, accessID, accessKey)
  5166  	c.Assert(err, IsNil)
  5167  
  5168  	bucketName := bucketNamePrefix + RandLowStr(6)
  5169  	err = client.CreateBucket(bucketName)
  5170  	c.Assert(err, IsNil)
  5171  
  5172  	bucket, err := client.Bucket(bucketName)
  5173  
  5174  	// put bucket version:enabled
  5175  	var versioningConfig VersioningConfig
  5176  	versioningConfig.Status = string(VersionEnabled)
  5177  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5178  	c.Assert(err, IsNil)
  5179  	time.Sleep(timeoutInOperation)
  5180  
  5181  	// put object v1
  5182  	objectName := objectNamePrefix + RandStr(8)
  5183  	contextV1 := RandStr(100)
  5184  	versionIdV1 := ""
  5185  
  5186  	var respHeader http.Header
  5187  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  5188  	c.Assert(err, IsNil)
  5189  	versionIdV1 = GetVersionId(respHeader)
  5190  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5191  
  5192  	// put object v2
  5193  	contextV2 := RandStr(200)
  5194  	versionIdV2 := ""
  5195  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  5196  	c.Assert(err, IsNil)
  5197  	versionIdV2 = GetVersionId(respHeader)
  5198  	c.Assert(len(versionIdV2) > 0, Equals, true)
  5199  
  5200  	// check v1 and v2
  5201  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  5202  
  5203  	destObjectKey := objectNamePrefix + RandStr(8)
  5204  
  5205  	// copyobject default
  5206  	_, err = bucket.CopyObject(objectName, destObjectKey, GetResponseHeader(&respHeader))
  5207  	c.Assert(err, IsNil)
  5208  	srcVersionId := GetCopySrcVersionId(respHeader)
  5209  	c.Assert(srcVersionId, Equals, versionIdV2)
  5210  
  5211  	body, err := bucket.GetObject(destObjectKey)
  5212  	c.Assert(err, IsNil)
  5213  	str, err := readBody(body)
  5214  	c.Assert(err, IsNil)
  5215  	c.Assert(str, Equals, contextV2)
  5216  
  5217  	//  copyobject v1
  5218  	options := []Option{VersionId(versionIdV1), GetResponseHeader(&respHeader)}
  5219  	_, err = bucket.CopyObject(objectName, destObjectKey, options...)
  5220  	c.Assert(err, IsNil)
  5221  	srcVersionId = GetCopySrcVersionId(respHeader)
  5222  	c.Assert(srcVersionId, Equals, versionIdV1)
  5223  
  5224  	body, err = bucket.GetObject(destObjectKey)
  5225  	c.Assert(err, IsNil)
  5226  	str, err = readBody(body)
  5227  	c.Assert(err, IsNil)
  5228  	c.Assert(str, Equals, contextV1)
  5229  
  5230  	// delete object
  5231  	err = bucket.DeleteObject(objectName)
  5232  	c.Assert(err, IsNil)
  5233  
  5234  	// default copyobject again,failuer
  5235  	_, err = bucket.CopyObject(objectName, destObjectKey, GetResponseHeader(&respHeader))
  5236  	c.Assert(err, NotNil)
  5237  
  5238  	bucket.DeleteObject(objectName)
  5239  	ForceDeleteBucket(client, bucketName, c)
  5240  }
  5241  
  5242  func (s *OssBucketSuite) TestVersioningCompleteMultipartUpload(c *C) {
  5243  	// create a bucket with default proprety
  5244  	client, err := New(endpoint, accessID, accessKey)
  5245  	c.Assert(err, IsNil)
  5246  
  5247  	bucketName := bucketNamePrefix + RandLowStr(6)
  5248  	err = client.CreateBucket(bucketName)
  5249  	c.Assert(err, IsNil)
  5250  
  5251  	bucket, err := client.Bucket(bucketName)
  5252  
  5253  	// put bucket version:enabled
  5254  	var versioningConfig VersioningConfig
  5255  	versioningConfig.Status = string(VersionEnabled)
  5256  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5257  	c.Assert(err, IsNil)
  5258  	time.Sleep(timeoutInOperation)
  5259  
  5260  	objectName := objectNamePrefix + RandStr(8)
  5261  	var fileName = "test-file-" + RandStr(8)
  5262  	content := RandStr(500 * 1024)
  5263  	CreateFile(fileName, content, c)
  5264  
  5265  	chunks, err := SplitFileByPartNum(fileName, 3)
  5266  	c.Assert(err, IsNil)
  5267  
  5268  	options := []Option{
  5269  		Expires(futureDate), Meta("my", "myprop"),
  5270  	}
  5271  
  5272  	fd, err := os.Open(fileName)
  5273  	c.Assert(err, IsNil)
  5274  	defer fd.Close()
  5275  
  5276  	imur, err := bucket.InitiateMultipartUpload(objectName, options...)
  5277  	c.Assert(err, IsNil)
  5278  	var parts []UploadPart
  5279  	for _, chunk := range chunks {
  5280  		fd.Seek(chunk.Offset, os.SEEK_SET)
  5281  		part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number)
  5282  		c.Assert(err, IsNil)
  5283  		parts = append(parts, part)
  5284  	}
  5285  
  5286  	var respHeader http.Header
  5287  	_, err = bucket.CompleteMultipartUpload(imur, parts, GetResponseHeader(&respHeader))
  5288  	c.Assert(err, IsNil)
  5289  
  5290  	//get versionId
  5291  	versionIdV1 := GetVersionId(respHeader)
  5292  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5293  
  5294  	meta, err := bucket.GetObjectDetailedMeta(objectName)
  5295  	c.Assert(err, IsNil)
  5296  	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
  5297  	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
  5298  	c.Assert(meta.Get("X-Oss-Object-Type"), Equals, "Multipart")
  5299  
  5300  	// put object agagin
  5301  	err = bucket.PutObject(objectName, strings.NewReader(""), GetResponseHeader(&respHeader))
  5302  	c.Assert(err, IsNil)
  5303  	versionIdV2 := GetVersionId(respHeader)
  5304  	c.Assert(versionIdV1 == versionIdV2, Equals, false)
  5305  
  5306  	// get meta v1
  5307  	meta, err = bucket.GetObjectDetailedMeta(objectName, VersionId(versionIdV1))
  5308  	c.Assert(err, IsNil)
  5309  	c.Assert(meta.Get("content-length"), Equals, strconv.Itoa(len(content)))
  5310  
  5311  	// get meta v2
  5312  	meta, err = bucket.GetObjectDetailedMeta(objectName, VersionId(versionIdV2))
  5313  	c.Assert(err, IsNil)
  5314  	c.Assert(meta.Get("content-length"), Equals, strconv.Itoa(0))
  5315  
  5316  	os.Remove(fileName)
  5317  	bucket.DeleteObject(objectName)
  5318  	ForceDeleteBucket(client, bucketName, c)
  5319  }
  5320  
  5321  func (s *OssBucketSuite) TestVersioningUploadPartCopy(c *C) {
  5322  	// create a bucket with default proprety
  5323  	client, err := New(endpoint, accessID, accessKey)
  5324  	c.Assert(err, IsNil)
  5325  
  5326  	bucketName := bucketNamePrefix + RandLowStr(6)
  5327  	err = client.CreateBucket(bucketName)
  5328  	c.Assert(err, IsNil)
  5329  
  5330  	bucket, err := client.Bucket(bucketName)
  5331  
  5332  	// put bucket version:enabled
  5333  	var versioningConfig VersioningConfig
  5334  	versioningConfig.Status = string(VersionEnabled)
  5335  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5336  	c.Assert(err, IsNil)
  5337  
  5338  	// put object v1
  5339  	objectName := objectNamePrefix + RandStr(8)
  5340  	contextV1 := RandStr(100)
  5341  	versionIdV1 := ""
  5342  
  5343  	var respHeader http.Header
  5344  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  5345  	c.Assert(err, IsNil)
  5346  	versionIdV1 = GetVersionId(respHeader)
  5347  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5348  
  5349  	// put object v2
  5350  	contextV2 := RandStr(200)
  5351  	versionIdV2 := ""
  5352  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  5353  	c.Assert(err, IsNil)
  5354  	versionIdV2 = GetVersionId(respHeader)
  5355  	c.Assert(len(versionIdV2) > 0, Equals, true)
  5356  
  5357  	// upload mutlipart object with v1
  5358  	multiName := objectNamePrefix + RandStr(8)
  5359  	var parts []UploadPart
  5360  	imur, err := bucket.InitiateMultipartUpload(multiName)
  5361  	c.Assert(err, IsNil)
  5362  
  5363  	part, err := bucket.UploadPartCopy(imur, bucketName, objectName, 0, int64(len(contextV1)), 1, VersionId(versionIdV1))
  5364  	parts = []UploadPart{part}
  5365  	c.Assert(err, IsNil)
  5366  
  5367  	_, err = bucket.CompleteMultipartUpload(imur, parts, GetResponseHeader(&respHeader))
  5368  	c.Assert(err, IsNil)
  5369  
  5370  	//get versionId
  5371  	partVersionIdV1 := GetVersionId(respHeader)
  5372  	c.Assert(len(partVersionIdV1) > 0, Equals, true)
  5373  
  5374  	// get meta v1
  5375  	meta, err := bucket.GetObjectDetailedMeta(multiName, VersionId(partVersionIdV1))
  5376  	c.Assert(err, IsNil)
  5377  	c.Assert(meta.Get("content-length"), Equals, strconv.Itoa(len(contextV1)))
  5378  
  5379  	// upload mutlipart object with v2
  5380  	imur, err = bucket.InitiateMultipartUpload(multiName)
  5381  	part, err = bucket.UploadPartCopy(imur, bucketName, objectName, 0, int64(len(contextV2)), 1, VersionId(versionIdV2))
  5382  	parts = []UploadPart{part}
  5383  
  5384  	_, err = bucket.CompleteMultipartUpload(imur, parts, GetResponseHeader(&respHeader))
  5385  	c.Assert(err, IsNil)
  5386  
  5387  	//get versionId
  5388  	partVersionIdV2 := GetVersionId(respHeader)
  5389  	c.Assert(len(partVersionIdV2) > 0, Equals, true)
  5390  
  5391  	// get meta v2
  5392  	meta, err = bucket.GetObjectDetailedMeta(multiName, VersionId(partVersionIdV2))
  5393  	c.Assert(err, IsNil)
  5394  	c.Assert(meta.Get("content-length"), Equals, strconv.Itoa(len(contextV2)))
  5395  
  5396  	bucket.DeleteObject(objectName)
  5397  	bucket.DeleteObject(multiName)
  5398  	ForceDeleteBucket(client, bucketName, c)
  5399  }
  5400  
  5401  func (s *OssBucketSuite) TestVersioningRestoreObject(c *C) {
  5402  	// create a bucket with default proprety
  5403  	client, err := New(endpoint, accessID, accessKey)
  5404  	c.Assert(err, IsNil)
  5405  
  5406  	bucketName := bucketNamePrefix + RandLowStr(6)
  5407  	err = client.CreateBucket(bucketName, StorageClass(StorageArchive))
  5408  	c.Assert(err, IsNil)
  5409  
  5410  	bucket, err := client.Bucket(bucketName)
  5411  
  5412  	// put bucket version:enabled
  5413  	var versioningConfig VersioningConfig
  5414  	versioningConfig.Status = string(VersionEnabled)
  5415  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5416  	c.Assert(err, IsNil)
  5417  	time.Sleep(timeoutInOperation)
  5418  
  5419  	// put object v1
  5420  	objectName := objectNamePrefix + RandStr(8)
  5421  	contextV1 := RandStr(100)
  5422  	versionIdV1 := ""
  5423  
  5424  	var respHeader http.Header
  5425  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  5426  	c.Assert(err, IsNil)
  5427  	versionIdV1 = GetVersionId(respHeader)
  5428  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5429  
  5430  	// put object v2
  5431  	contextV2 := RandStr(200)
  5432  	versionIdV2 := ""
  5433  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  5434  	c.Assert(err, IsNil)
  5435  	versionIdV2 = GetVersionId(respHeader)
  5436  	c.Assert(len(versionIdV2) > 0, Equals, true)
  5437  
  5438  	// RestoreObject v1
  5439  	options := []Option{GetResponseHeader(&respHeader), VersionId(versionIdV1)}
  5440  	err = bucket.RestoreObject(objectName, options...)
  5441  	c.Assert(err, IsNil)
  5442  	c.Assert(GetVersionId(respHeader), Equals, versionIdV1)
  5443  
  5444  	// RestoreObject v2
  5445  	options = []Option{GetResponseHeader(&respHeader), VersionId(versionIdV2)}
  5446  	err = bucket.RestoreObject(objectName, options...)
  5447  	c.Assert(err, IsNil)
  5448  	c.Assert(GetVersionId(respHeader), Equals, versionIdV2)
  5449  
  5450  	bucket.DeleteObject(objectName)
  5451  	ForceDeleteBucket(client, bucketName, c)
  5452  }
  5453  
  5454  func (s *OssBucketSuite) TestVersioningObjectTagging(c *C) {
  5455  	// create a bucket with default proprety
  5456  	client, err := New(endpoint, accessID, accessKey)
  5457  	c.Assert(err, IsNil)
  5458  
  5459  	bucketName := bucketNamePrefix + RandLowStr(6)
  5460  	err = client.CreateBucket(bucketName, StorageClass(StorageArchive))
  5461  	c.Assert(err, IsNil)
  5462  
  5463  	bucket, err := client.Bucket(bucketName)
  5464  
  5465  	// put bucket version:enabled
  5466  	var versioningConfig VersioningConfig
  5467  	versioningConfig.Status = string(VersionEnabled)
  5468  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5469  	c.Assert(err, IsNil)
  5470  	time.Sleep(timeoutInOperation)
  5471  
  5472  	// put object v1
  5473  	objectName := objectNamePrefix + RandStr(8)
  5474  	contextV1 := RandStr(100)
  5475  	versionIdV1 := ""
  5476  
  5477  	var respHeader http.Header
  5478  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  5479  	c.Assert(err, IsNil)
  5480  	versionIdV1 = GetVersionId(respHeader)
  5481  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5482  
  5483  	// put object v2
  5484  	contextV2 := RandStr(200)
  5485  	versionIdV2 := ""
  5486  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  5487  	c.Assert(err, IsNil)
  5488  	versionIdV2 = GetVersionId(respHeader)
  5489  	c.Assert(len(versionIdV2) > 0, Equals, true)
  5490  
  5491  	// ObjectTagging v1
  5492  	var tagging1 Tagging
  5493  	tagging1.Tags = []Tag{{Key: "testkey1", Value: "testvalue1"}}
  5494  	err = bucket.PutObjectTagging(objectName, tagging1, VersionId(versionIdV1))
  5495  	c.Assert(err, IsNil)
  5496  	getResult, err := bucket.GetObjectTagging(objectName, VersionId(versionIdV1))
  5497  	c.Assert(err, IsNil)
  5498  	c.Assert(getResult.Tags[0].Key, Equals, tagging1.Tags[0].Key)
  5499  	c.Assert(getResult.Tags[0].Value, Equals, tagging1.Tags[0].Value)
  5500  
  5501  	// ObjectTagging v2
  5502  	var tagging2 Tagging
  5503  	tagging2.Tags = []Tag{{Key: "testkey2", Value: "testvalue2"}}
  5504  	err = bucket.PutObjectTagging(objectName, tagging2, VersionId(versionIdV2))
  5505  	c.Assert(err, IsNil)
  5506  	getResult, err = bucket.GetObjectTagging(objectName, VersionId(versionIdV2))
  5507  	c.Assert(err, IsNil)
  5508  	c.Assert(getResult.Tags[0].Key, Equals, tagging2.Tags[0].Key)
  5509  	c.Assert(getResult.Tags[0].Value, Equals, tagging2.Tags[0].Value)
  5510  
  5511  	// delete ObjectTagging v2
  5512  	err = bucket.DeleteObjectTagging(objectName, VersionId(versionIdV2))
  5513  	c.Assert(err, IsNil)
  5514  
  5515  	getResult, err = bucket.GetObjectTagging(objectName, VersionId(versionIdV2))
  5516  	c.Assert(err, IsNil)
  5517  	c.Assert(len(getResult.Tags), Equals, 0)
  5518  
  5519  	bucket.DeleteObject(objectName)
  5520  	ForceDeleteBucket(client, bucketName, c)
  5521  }
  5522  
  5523  func (s *OssBucketSuite) TestVersioningIsObjectExist(c *C) {
  5524  	// create a bucket with default proprety
  5525  	client, err := New(endpoint, accessID, accessKey)
  5526  	c.Assert(err, IsNil)
  5527  
  5528  	bucketName := bucketNamePrefix + RandLowStr(6)
  5529  	err = client.CreateBucket(bucketName)
  5530  	c.Assert(err, IsNil)
  5531  	bucket, err := client.Bucket(bucketName)
  5532  
  5533  	// put bucket version:enabled
  5534  	var versioningConfig VersioningConfig
  5535  	versioningConfig.Status = string(VersionEnabled)
  5536  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  5537  	c.Assert(err, IsNil)
  5538  	time.Sleep(timeoutInOperation)
  5539  
  5540  	// put object v1
  5541  	objectName := objectNamePrefix + RandStr(8)
  5542  	contextV1 := RandStr(100)
  5543  	versionIdV1 := ""
  5544  
  5545  	var respHeader http.Header
  5546  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  5547  	c.Assert(err, IsNil)
  5548  	versionIdV1 = GetVersionId(respHeader)
  5549  	c.Assert(len(versionIdV1) > 0, Equals, true)
  5550  
  5551  	// put object v2
  5552  	contextV2 := RandStr(200)
  5553  	versionIdV2 := ""
  5554  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  5555  	c.Assert(err, IsNil)
  5556  	versionIdV2 = GetVersionId(respHeader)
  5557  	c.Assert(len(versionIdV2) > 0, Equals, true)
  5558  
  5559  	// check v1 and v2
  5560  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  5561  
  5562  	// check default exist
  5563  	exist, err := bucket.IsObjectExist(objectName)
  5564  	c.Assert(err, IsNil)
  5565  	c.Assert(exist, Equals, true)
  5566  
  5567  	// check object v1 exist
  5568  	exist, err = bucket.IsObjectExist(objectName, VersionId(versionIdV1))
  5569  	c.Assert(err, IsNil)
  5570  	c.Assert(exist, Equals, true)
  5571  
  5572  	// check object v2 exist
  5573  	exist, err = bucket.IsObjectExist(objectName, VersionId(versionIdV2))
  5574  	c.Assert(err, IsNil)
  5575  	c.Assert(exist, Equals, true)
  5576  
  5577  	// rm v2
  5578  	err = bucket.DeleteObject(objectName, VersionId(versionIdV2))
  5579  	c.Assert(err, IsNil)
  5580  
  5581  	// check object v2 not exist
  5582  	exist, err = bucket.IsObjectExist(objectName, VersionId(versionIdV2))
  5583  	c.Assert(err, IsNil)
  5584  	c.Assert(exist, Equals, false)
  5585  
  5586  	// rm default
  5587  	err = bucket.DeleteObject(objectName)
  5588  	c.Assert(err, IsNil)
  5589  
  5590  	// check default exist
  5591  	exist, err = bucket.IsObjectExist(objectName)
  5592  	c.Assert(err, IsNil)
  5593  	c.Assert(exist, Equals, false)
  5594  
  5595  	// check v1 exist
  5596  	exist, err = bucket.IsObjectExist(objectName, VersionId(versionIdV1))
  5597  	c.Assert(err, IsNil)
  5598  	c.Assert(exist, Equals, true)
  5599  
  5600  	ForceDeleteBucket(client, bucketName, c)
  5601  }
  5602  
  5603  func (s *OssBucketSuite) TestOptionsMethod(c *C) {
  5604  	// create a bucket with default proprety
  5605  	client, err := New(endpoint, accessID, accessKey)
  5606  	c.Assert(err, IsNil)
  5607  
  5608  	bucketName := bucketNamePrefix + RandLowStr(6)
  5609  	err = client.CreateBucket(bucketName)
  5610  	c.Assert(err, IsNil)
  5611  
  5612  	bucket, err := client.Bucket(bucketName)
  5613  
  5614  	// put bucket cors
  5615  	var rule = CORSRule{
  5616  		AllowedOrigin: []string{"www.aliyun.com"},
  5617  		AllowedMethod: []string{"PUT", "GET", "POST"},
  5618  		AllowedHeader: []string{"x-oss-meta-author"},
  5619  		ExposeHeader:  []string{"x-oss-meta-name"},
  5620  		MaxAgeSeconds: 100,
  5621  	}
  5622  
  5623  	// set cors
  5624  	err = client.SetBucketCORS(bucketName, []CORSRule{rule})
  5625  	c.Assert(err, IsNil)
  5626  
  5627  	// bucket options success
  5628  	options := []Option{}
  5629  	originOption := Origin("www.aliyun.com")
  5630  	acMethodOption := ACReqMethod("PUT")
  5631  	acHeadersOption := ACReqHeaders("x-oss-meta-author")
  5632  	options = append(options, originOption)
  5633  	options = append(options, acMethodOption)
  5634  	options = append(options, acHeadersOption)
  5635  	_, err = bucket.OptionsMethod("", options...)
  5636  	c.Assert(err, IsNil)
  5637  
  5638  	// options failure
  5639  	options = []Option{}
  5640  	originOption = Origin("www.aliyun.com")
  5641  	acMethodOption = ACReqMethod("PUT")
  5642  	acHeadersOption = ACReqHeaders("x-oss-meta-author-1")
  5643  	options = append(options, originOption)
  5644  	options = append(options, acMethodOption)
  5645  	options = append(options, acHeadersOption)
  5646  	_, err = bucket.OptionsMethod("", options...)
  5647  	c.Assert(err, NotNil)
  5648  
  5649  	// put object
  5650  	objectName := objectNamePrefix + RandStr(8)
  5651  	context := RandStr(100)
  5652  	err = bucket.PutObject(objectName, strings.NewReader(context))
  5653  	c.Assert(err, IsNil)
  5654  
  5655  	// object options success
  5656  	options = []Option{}
  5657  	originOption = Origin("www.aliyun.com")
  5658  	acMethodOption = ACReqMethod("PUT")
  5659  	acHeadersOption = ACReqHeaders("x-oss-meta-author")
  5660  	options = append(options, originOption)
  5661  	options = append(options, acMethodOption)
  5662  	options = append(options, acHeadersOption)
  5663  	_, err = bucket.OptionsMethod("", options...)
  5664  	c.Assert(err, IsNil)
  5665  
  5666  	// options failure
  5667  	options = []Option{}
  5668  	originOption = Origin("www.aliyun.com")
  5669  	acMethodOption = ACReqMethod("PUT")
  5670  	acHeadersOption = ACReqHeaders("x-oss-meta-author-1")
  5671  	options = append(options, originOption)
  5672  	options = append(options, acMethodOption)
  5673  	options = append(options, acHeadersOption)
  5674  	_, err = bucket.OptionsMethod("", options...)
  5675  	c.Assert(err, NotNil)
  5676  
  5677  	bucket.DeleteObject(objectName)
  5678  	ForceDeleteBucket(client, bucketName, c)
  5679  }
  5680  
  5681  func (s *OssBucketSuite) TestBucketTrafficLimitObject1(c *C) {
  5682  	// create a bucket with default proprety
  5683  	client, err := New(endpoint, accessID, accessKey)
  5684  	c.Assert(err, IsNil)
  5685  
  5686  	bucketName := bucketNamePrefix + RandLowStr(6)
  5687  	err = client.CreateBucket(bucketName)
  5688  	c.Assert(err, IsNil)
  5689  
  5690  	bucket, err := client.Bucket(bucketName)
  5691  
  5692  	var respHeader http.Header
  5693  	var qosDelayTime string
  5694  	var traffic int64 = 819220 // 100KB
  5695  	maxTraffic := traffic * 120 / 100
  5696  
  5697  	objectName := objectNamePrefix + RandStr(8)
  5698  	localFile := "../sample/BingWallpaper-2015-11-07.jpg"
  5699  	fd, err := os.Open(localFile)
  5700  	c.Assert(err, IsNil)
  5701  	defer fd.Close()
  5702  
  5703  	tryGetFileSize := func(f *os.File) int64 {
  5704  		fInfo, _ := f.Stat()
  5705  		return fInfo.Size()
  5706  	}
  5707  	contentLength := tryGetFileSize(fd) * 8
  5708  
  5709  	// put object
  5710  	start := time.Now().UnixNano() / 1000 / 1000
  5711  	err = bucket.PutObject(objectName, fd, TrafficLimitHeader(traffic), GetResponseHeader(&respHeader))
  5712  	c.Assert(err, IsNil)
  5713  	endingTime := time.Now().UnixNano() / 1000 / 1000
  5714  	costT := endingTime - start
  5715  	costV := contentLength * 1000 / costT // bit * 1000 / Millisecond = bit/s
  5716  	c.Assert((costV < maxTraffic), Equals, true)
  5717  	qosDelayTime = GetQosDelayTime(respHeader)
  5718  	c.Assert(len(qosDelayTime) > 0, Equals, true)
  5719  
  5720  	// putobject without TrafficLimit
  5721  	//
  5722  	// fd, err = os.Open(localFile)
  5723  	// c.Assert(err, IsNil)
  5724  	// defer fd.Close()
  5725  	// start = time.Now().UnixNano() / 1000 / 1000
  5726  	// err = bucket.PutObject(objectName, fd)
  5727  	// c.Assert(err, IsNil)
  5728  	// endingTime = time.Now().UnixNano() / 1000 / 1000
  5729  	// costT = endingTime - start
  5730  	// costV = contentLength * 1000 / costT  // bit * 1000 / Millisecond = bit/s
  5731  	// testLogger.Println(traffic, maxTraffic, contentLength, costT, costV)
  5732  	// c.Assert((costV < maxTraffic), Equals, true)
  5733  
  5734  	// get object to file
  5735  	newFile := "test-file-" + RandStr(10)
  5736  	start = time.Now().UnixNano() / 1000 / 1000
  5737  	err = bucket.GetObjectToFile(objectName, newFile, TrafficLimitHeader(traffic))
  5738  	c.Assert(err, IsNil)
  5739  	endingTime = time.Now().UnixNano() / 1000 / 1000
  5740  	costT = endingTime - start
  5741  	costV = contentLength * 1000 / costT // bit * 1000 / Millisecond = bit/s
  5742  	c.Assert((costV < maxTraffic), Equals, true)
  5743  	os.Remove(newFile)
  5744  
  5745  	// append object
  5746  	newFile = "test-file-" + RandStr(10)
  5747  	objectKey := objectNamePrefix + RandStr(8)
  5748  	var nextPos int64
  5749  	fd, err = os.Open(localFile)
  5750  	c.Assert(err, IsNil)
  5751  	defer fd.Close()
  5752  	start = time.Now().UnixNano() / 1000 / 1000
  5753  	nextPos, err = bucket.AppendObject(objectKey, strings.NewReader(RandStr(18)), nextPos)
  5754  	c.Assert(err, IsNil)
  5755  
  5756  	var respAppendHeader http.Header
  5757  	nextPos, err = bucket.AppendObject(objectKey, fd, nextPos, TrafficLimitHeader(traffic), GetResponseHeader(&respAppendHeader))
  5758  	c.Assert(err, IsNil)
  5759  	endingTime = time.Now().UnixNano() / 1000 / 1000
  5760  	costT = endingTime - start
  5761  	costV = contentLength * 1000 / costT // bit * 1000 / Millisecond = bit/s
  5762  	c.Assert((costV < maxTraffic), Equals, true)
  5763  	qosDelayTime = GetQosDelayTime(respAppendHeader)
  5764  	c.Assert(len(qosDelayTime) > 0, Equals, true)
  5765  
  5766  	err = bucket.GetObjectToFile(objectKey, newFile, TrafficLimitHeader(traffic))
  5767  	c.Assert(err, IsNil)
  5768  	err = bucket.DeleteObject(objectKey)
  5769  	c.Assert(err, IsNil)
  5770  	os.Remove(newFile)
  5771  
  5772  	// put object with url
  5773  	fd, err = os.Open(localFile)
  5774  	c.Assert(err, IsNil)
  5775  	defer fd.Close()
  5776  	strURL, err := bucket.SignURL(objectName, HTTPPut, 60, TrafficLimitParam(traffic))
  5777  	start = time.Now().UnixNano() / 1000 / 1000
  5778  	err = bucket.PutObjectWithURL(strURL, fd)
  5779  	c.Assert(err, IsNil)
  5780  	endingTime = time.Now().UnixNano() / 1000 / 1000
  5781  	costT = endingTime - start
  5782  	costV = contentLength * 1000 / costT // bit * 1000 / Millisecond = bit/s
  5783  	c.Assert((costV < maxTraffic), Equals, true)
  5784  
  5785  	// get object with url
  5786  	newFile = "test-file-" + RandStr(10)
  5787  	strURL, err = bucket.SignURL(objectName, HTTPGet, 60, TrafficLimitParam(traffic))
  5788  	c.Assert(err, IsNil)
  5789  	start = time.Now().UnixNano() / 1000 / 1000
  5790  	err = bucket.GetObjectToFileWithURL(strURL, newFile)
  5791  	c.Assert(err, IsNil)
  5792  	endingTime = time.Now().UnixNano() / 1000 / 1000
  5793  	costT = endingTime - start
  5794  	costV = contentLength * 1000 / costT // bit * 1000 / Millisecond = bit/s
  5795  	c.Assert((costV < maxTraffic), Equals, true)
  5796  	os.Remove(newFile)
  5797  
  5798  	// copy object
  5799  	destObjectName := objectNamePrefix + RandStr(8)
  5800  	_, err = bucket.CopyObject(objectName, destObjectName, TrafficLimitHeader(traffic))
  5801  	c.Assert(err, IsNil)
  5802  	err = bucket.DeleteObject(destObjectName)
  5803  	c.Assert(err, IsNil)
  5804  
  5805  	ForceDeleteBucket(client, bucketName, c)
  5806  }
  5807  
  5808  func (s *OssBucketSuite) TestBucketTrafficLimitUpload(c *C) {
  5809  	// create a bucket with default proprety
  5810  	client, err := New(endpoint, accessID, accessKey)
  5811  	c.Assert(err, IsNil)
  5812  
  5813  	bucketName := bucketNamePrefix + RandLowStr(6)
  5814  	err = client.CreateBucket(bucketName)
  5815  	c.Assert(err, IsNil)
  5816  
  5817  	bucket, err := client.Bucket(bucketName)
  5818  
  5819  	var traffic int64 = 819220 // 100KB
  5820  	maxTraffic := traffic * 120 / 100
  5821  	contentLength := 500 * 1024
  5822  
  5823  	var fileName = "test-file-" + RandStr(8)
  5824  	objectName := objectNamePrefix + RandStr(8)
  5825  	content := RandStr(contentLength)
  5826  	CreateFile(fileName, content, c)
  5827  
  5828  	chunks, err := SplitFileByPartNum(fileName, 3)
  5829  	c.Assert(err, IsNil)
  5830  
  5831  	options := []Option{
  5832  		Expires(futureDate), Meta("my", "myprop"),
  5833  	}
  5834  
  5835  	fd, err := os.Open(fileName)
  5836  	c.Assert(err, IsNil)
  5837  	defer fd.Close()
  5838  
  5839  	imur, err := bucket.InitiateMultipartUpload(objectName, options...)
  5840  	c.Assert(err, IsNil)
  5841  	var parts []UploadPart
  5842  	start := time.Now().UnixNano() / 1000 / 1000
  5843  	for _, chunk := range chunks {
  5844  		fd.Seek(chunk.Offset, os.SEEK_SET)
  5845  		part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number, TrafficLimitHeader(traffic))
  5846  		c.Assert(err, IsNil)
  5847  		parts = append(parts, part)
  5848  	}
  5849  	_, err = bucket.CompleteMultipartUpload(imur, parts)
  5850  	c.Assert(err, IsNil)
  5851  	endingTime := time.Now().UnixNano() / 1000 / 1000
  5852  	costT := endingTime - start
  5853  	costV := int64(contentLength) * 8 * 1000 / costT // B * 8 * 1000 / Millisecond = bit/s
  5854  	c.Assert((costV < maxTraffic), Equals, true)
  5855  	os.Remove(fileName)
  5856  
  5857  	ForceDeleteBucket(client, bucketName, c)
  5858  }
  5859  
  5860  func (s *OssBucketSuite) TestPutObjectWithForbidOverWrite(c *C) {
  5861  	// create a bucket with default proprety
  5862  	client, err := New(endpoint, accessID, accessKey)
  5863  	c.Assert(err, IsNil)
  5864  
  5865  	bucketName := bucketNamePrefix + RandLowStr(6)
  5866  	err = client.CreateBucket(bucketName)
  5867  	c.Assert(err, IsNil)
  5868  	bucket, err := client.Bucket(bucketName)
  5869  
  5870  	contentLength := 1024
  5871  	objectName := objectNamePrefix + RandStr(8)
  5872  	content := RandStr(contentLength)
  5873  
  5874  	// first put success
  5875  	err = bucket.PutObject(objectName, strings.NewReader(content), ForbidOverWrite(true))
  5876  	c.Assert(err, IsNil)
  5877  
  5878  	// second put failure with ForbidOverWrite true
  5879  	var respHeader http.Header
  5880  	err = bucket.PutObject(objectName, strings.NewReader(content), ForbidOverWrite(true), GetResponseHeader(&respHeader))
  5881  	c.Assert(err, NotNil)
  5882  
  5883  	// third  put success with ForbidOverWrite false
  5884  	err = bucket.PutObject(objectName, strings.NewReader(content), ForbidOverWrite(false))
  5885  	c.Assert(err, IsNil)
  5886  
  5887  	ForceDeleteBucket(client, bucketName, c)
  5888  }
  5889  
  5890  func (s *OssBucketSuite) TestCopyObjectWithForbidOverWrite(c *C) {
  5891  	// create a bucket with default proprety
  5892  	client, err := New(endpoint, accessID, accessKey)
  5893  	c.Assert(err, IsNil)
  5894  
  5895  	bucketName := bucketNamePrefix + RandLowStr(6)
  5896  	err = client.CreateBucket(bucketName)
  5897  	c.Assert(err, IsNil)
  5898  	bucket, err := client.Bucket(bucketName)
  5899  
  5900  	contentLength := 1024
  5901  	objectName := objectNamePrefix + RandStr(8)
  5902  	content := RandStr(contentLength)
  5903  
  5904  	err = bucket.PutObject(objectName, strings.NewReader(content))
  5905  	c.Assert(err, IsNil)
  5906  
  5907  	// first copy success
  5908  	copyObjectName := objectName + "-copy"
  5909  	_, err = bucket.CopyObject(objectName, copyObjectName, ForbidOverWrite(true))
  5910  	c.Assert(err, IsNil)
  5911  
  5912  	// second copy failure with ForbidOverWrite true
  5913  	var respHeader http.Header
  5914  	_, err = bucket.CopyObject(objectName, copyObjectName, ForbidOverWrite(true), GetResponseHeader(&respHeader))
  5915  	c.Assert(err, NotNil)
  5916  
  5917  	// third  copy success with ForbidOverWrite false
  5918  	_, err = bucket.CopyObject(objectName, copyObjectName, ForbidOverWrite(false))
  5919  	c.Assert(err, IsNil)
  5920  
  5921  	ForceDeleteBucket(client, bucketName, c)
  5922  }
  5923  
  5924  func (s *OssBucketSuite) TestDeleteObjectsWithSpecialCharacter(c *C) {
  5925  	// create a bucket with default proprety
  5926  	client, err := New(endpoint, accessID, accessKey)
  5927  	c.Assert(err, IsNil)
  5928  
  5929  	bucketName := bucketNamePrefix + RandLowStr(6)
  5930  	err = client.CreateBucket(bucketName)
  5931  	c.Assert(err, IsNil)
  5932  	bucket, err := client.Bucket(bucketName)
  5933  
  5934  	contentLength := 100
  5935  	objectName1 := objectNamePrefix + RandStr(8) + "<-->+&*\r%%"
  5936  	objectName2 := objectNamePrefix + RandStr(8) + "\r&*\r%%"
  5937  	//objectName2 := objectNamePrefix + RandStr(8) + "%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2F%C0%AE%C0%AE%2Fetc%2Fprofile"
  5938  	//objectName2, err = url.QueryUnescape(objectName2)
  5939  
  5940  	c.Assert(err, IsNil)
  5941  	content := RandStr(contentLength)
  5942  
  5943  	err = bucket.PutObject(objectName1, strings.NewReader(content))
  5944  	c.Assert(err, IsNil)
  5945  
  5946  	err = bucket.PutObject(objectName2, strings.NewReader(content))
  5947  	c.Assert(err, IsNil)
  5948  
  5949  	// delete objectName1 objectName2
  5950  	objectKeys := []string{objectName1, objectName2}
  5951  	_, err = bucket.DeleteObjects(objectKeys)
  5952  	c.Assert(err, IsNil)
  5953  
  5954  	// objectName1 is not exist
  5955  	exist, err := bucket.IsObjectExist(objectName1)
  5956  	c.Assert(err, IsNil)
  5957  	c.Assert(exist, Equals, false)
  5958  
  5959  	// objectName2 is not exist
  5960  	exist, err = bucket.IsObjectExist(objectName2)
  5961  	c.Assert(err, IsNil)
  5962  	c.Assert(exist, Equals, false)
  5963  
  5964  	ForceDeleteBucket(client, bucketName, c)
  5965  }
  5966  
  5967  // TestGetObjectRangeBehavior
  5968  func (s *OssBucketSuite) TestGetObjectRangeBehavior(c *C) {
  5969  	// create a bucket with default proprety
  5970  	client, err := New(endpoint, accessID, accessKey)
  5971  	c.Assert(err, IsNil)
  5972  
  5973  	bucketName := bucketNamePrefix + RandLowStr(6)
  5974  	err = client.CreateBucket(bucketName)
  5975  	c.Assert(err, IsNil)
  5976  	bucket, err := client.Bucket(bucketName)
  5977  
  5978  	objectName := objectNamePrefix + RandStr(8)
  5979  	objectLen := 1000
  5980  	objectValue := RandStr(objectLen)
  5981  
  5982  	// Put
  5983  	err = bucket.PutObject(objectName, strings.NewReader(objectValue))
  5984  	c.Assert(err, IsNil)
  5985  
  5986  	// Range 1
  5987  	options := []Option{
  5988  		RangeBehavior("standard"),
  5989  		Range(1000, 2000),
  5990  	}
  5991  	resp, err := bucket.GetObject(objectName, options...)
  5992  	c.Assert(resp, IsNil)
  5993  	c.Assert(err.(ServiceError).StatusCode, Equals, 416)
  5994  
  5995  	// Range 2
  5996  	options = []Option{
  5997  		RangeBehavior("standard"),
  5998  		Range(0, 2000),
  5999  	}
  6000  	resp, err = bucket.GetObject(objectName, options...)
  6001  	c.Assert(err, IsNil)
  6002  	data, err := ioutil.ReadAll(resp)
  6003  	resp.Close()
  6004  	str := string(data)
  6005  	c.Assert(len(str), Equals, 1000)
  6006  	c.Assert(resp.(*Response).StatusCode, Equals, 206)
  6007  
  6008  	// Range 3
  6009  	options = []Option{
  6010  		RangeBehavior("standard"),
  6011  		Range(500, 2000),
  6012  	}
  6013  	resp, err = bucket.GetObject(objectName, options...)
  6014  	c.Assert(err, IsNil)
  6015  	data, err = ioutil.ReadAll(resp)
  6016  	resp.Close()
  6017  	str = string(data)
  6018  	c.Assert(len(str), Equals, 500)
  6019  	c.Assert(resp.(*Response).StatusCode, Equals, 206)
  6020  
  6021  	ForceDeleteBucket(client, bucketName, c)
  6022  }
  6023  
  6024  // RangeBehavior  is an option to set Range value, such as "standard"
  6025  func MyRangeBehavior(value string) Option {
  6026  	return SetHeader(HTTPHeaderOssRangeBehavior, value)
  6027  }
  6028  
  6029  // TestUserSetHeader
  6030  func (s *OssBucketSuite) TestSupportUserSetHeader(c *C) {
  6031  	// create a bucket with default proprety
  6032  	client, err := New(endpoint, accessID, accessKey)
  6033  	c.Assert(err, IsNil)
  6034  
  6035  	bucketName := bucketNamePrefix + RandLowStr(6)
  6036  	err = client.CreateBucket(bucketName)
  6037  	c.Assert(err, IsNil)
  6038  	bucket, err := client.Bucket(bucketName)
  6039  
  6040  	objectName := objectNamePrefix + RandStr(8)
  6041  	objectLen := 1000
  6042  	objectValue := RandStr(objectLen)
  6043  
  6044  	// Put
  6045  	err = bucket.PutObject(objectName, strings.NewReader(objectValue))
  6046  	c.Assert(err, IsNil)
  6047  
  6048  	// Range 1
  6049  	options := []Option{
  6050  		MyRangeBehavior("standard"),
  6051  		Range(1000, 2000),
  6052  	}
  6053  	resp, err := bucket.GetObject(objectName, options...)
  6054  	c.Assert(resp, IsNil)
  6055  	c.Assert(err.(ServiceError).StatusCode, Equals, 416)
  6056  
  6057  	// Range 2
  6058  	options = []Option{
  6059  		MyRangeBehavior("standard"),
  6060  		Range(0, 2000),
  6061  	}
  6062  	resp, err = bucket.GetObject(objectName, options...)
  6063  	c.Assert(err, IsNil)
  6064  	data, err := ioutil.ReadAll(resp)
  6065  	resp.Close()
  6066  	str := string(data)
  6067  	c.Assert(len(str), Equals, 1000)
  6068  	c.Assert(resp.(*Response).StatusCode, Equals, 206)
  6069  
  6070  	// Range 3
  6071  	options = []Option{
  6072  		MyRangeBehavior("standard"),
  6073  		Range(500, 2000),
  6074  	}
  6075  	resp, err = bucket.GetObject(objectName, options...)
  6076  	c.Assert(err, IsNil)
  6077  	data, err = ioutil.ReadAll(resp)
  6078  	resp.Close()
  6079  	str = string(data)
  6080  	c.Assert(len(str), Equals, 500)
  6081  	c.Assert(resp.(*Response).StatusCode, Equals, 206)
  6082  
  6083  	ForceDeleteBucket(client, bucketName, c)
  6084  }
  6085  
  6086  // user can set param
  6087  func MyVersionId(value string) Option {
  6088  	return AddParam("versionId", value)
  6089  }
  6090  
  6091  func (s *OssBucketSuite) TestSupportUserSetParam(c *C) {
  6092  	// create a bucket with default proprety
  6093  	client, err := New(endpoint, accessID, accessKey)
  6094  	c.Assert(err, IsNil)
  6095  
  6096  	bucketName := bucketNamePrefix + RandLowStr(6)
  6097  	err = client.CreateBucket(bucketName)
  6098  	c.Assert(err, IsNil)
  6099  
  6100  	bucket, err := client.Bucket(bucketName)
  6101  
  6102  	// put bucket version:enabled
  6103  	var versioningConfig VersioningConfig
  6104  	versioningConfig.Status = string(VersionEnabled)
  6105  	err = client.SetBucketVersioning(bucketName, versioningConfig)
  6106  	c.Assert(err, IsNil)
  6107  	time.Sleep(timeoutInOperation)
  6108  
  6109  	bucketResult, err := client.GetBucketInfo(bucketName)
  6110  	c.Assert(err, IsNil)
  6111  	c.Assert(bucketResult.BucketInfo.Versioning, Equals, string(VersionEnabled))
  6112  
  6113  	// put object v1
  6114  	objectName := objectNamePrefix + RandStr(8)
  6115  	contextV1 := RandStr(100)
  6116  	versionIdV1 := ""
  6117  
  6118  	var respHeader http.Header
  6119  	err = bucket.PutObject(objectName, strings.NewReader(contextV1), GetResponseHeader(&respHeader))
  6120  	c.Assert(err, IsNil)
  6121  	versionIdV1 = GetVersionId(respHeader)
  6122  	c.Assert(len(versionIdV1) > 0, Equals, true)
  6123  
  6124  	// put object v2
  6125  	contextV2 := RandStr(200)
  6126  	versionIdV2 := ""
  6127  	err = bucket.PutObject(objectName, strings.NewReader(contextV2), GetResponseHeader(&respHeader))
  6128  	c.Assert(err, IsNil)
  6129  	versionIdV2 = GetVersionId(respHeader)
  6130  	c.Assert(len(versionIdV2) > 0, Equals, true)
  6131  
  6132  	// check v1 and v2
  6133  	c.Assert(versionIdV1 != versionIdV2, Equals, true)
  6134  
  6135  	// get object v1
  6136  	body, err := bucket.GetObject(objectName, MyVersionId(versionIdV1))
  6137  	c.Assert(err, IsNil)
  6138  	str, err := readBody(body)
  6139  	c.Assert(err, IsNil)
  6140  	body.Close()
  6141  	c.Assert(str, Equals, contextV1)
  6142  
  6143  	// get object v2
  6144  	body, err = bucket.GetObject(objectName, MyVersionId(versionIdV2))
  6145  	c.Assert(err, IsNil)
  6146  	str, err = readBody(body)
  6147  	c.Assert(err, IsNil)
  6148  	body.Close()
  6149  	c.Assert(str, Equals, contextV2)
  6150  	ForceDeleteBucket(client, bucketName, c)
  6151  }
  6152  
  6153  func (s *OssBucketSuite) TestPutObjectWithKmsSm4(c *C) {
  6154  	// create a bucket with default proprety
  6155  	client, err := New(endpoint, accessID, accessKey)
  6156  	c.Assert(err, IsNil)
  6157  
  6158  	objectName := objectNamePrefix + RandStr(8)
  6159  	objectValue := RandStr(1024)
  6160  	bucketName := bucketNamePrefix + RandLowStr(6)
  6161  	err = client.CreateBucket(bucketName)
  6162  	c.Assert(err, IsNil)
  6163  	bucket, err := client.Bucket(bucketName)
  6164  
  6165  	err = bucket.PutObject(objectName, strings.NewReader(objectValue), ServerSideEncryption("KMS"), ServerSideDataEncryption("SM4"))
  6166  	headers, err := bucket.GetObjectDetailedMeta(objectName)
  6167  	c.Assert(err, IsNil)
  6168  	c.Assert(headers.Get(HTTPHeaderOssServerSideEncryption), Equals, "KMS")
  6169  	c.Assert(headers.Get(HTTPHeaderOssServerSideDataEncryption), Equals, "SM4")
  6170  	c.Assert(err, IsNil)
  6171  	ForceDeleteBucket(client, bucketName, c)
  6172  }
  6173  
  6174  func (s *OssBucketSuite) TestGetSingleObjectLimitSpeed(c *C) {
  6175  	// create client and bucket
  6176  	client, err := New(endpoint, accessID, accessKey)
  6177  	c.Assert(err, IsNil)
  6178  
  6179  	err = client.LimitDownloadSpeed(1)
  6180  	if err != nil {
  6181  		// go version is less than go1.7,not support limit download speed
  6182  		// doesn't run this test
  6183  		return
  6184  	}
  6185  
  6186  	// set limit download speed as 100KB/s
  6187  	limitSpeed := 100
  6188  	client.LimitDownloadSpeed(limitSpeed)
  6189  
  6190  	bucketName := bucketNamePrefix + RandLowStr(6)
  6191  	err = client.CreateBucket(bucketName)
  6192  	c.Assert(err, IsNil)
  6193  
  6194  	bucket, err := client.Bucket(bucketName)
  6195  	c.Assert(err, IsNil)
  6196  
  6197  	objectName := objectNamePrefix + RandStr(8)
  6198  
  6199  	// 1M byte
  6200  	textBuffer := RandStr(1024 * 1024)
  6201  
  6202  	// Put body
  6203  	err = bucket.PutObject(objectName, strings.NewReader(textBuffer))
  6204  	c.Assert(err, IsNil)
  6205  
  6206  	// get object to file
  6207  	tempFile := "test-go-sdk-" + RandStr(8)
  6208  	startT := time.Now()
  6209  	err = bucket.GetObjectToFile(objectName, tempFile)
  6210  	endT := time.Now()
  6211  	c.Assert(err, IsNil)
  6212  
  6213  	realSpeed := int64(len(textBuffer)) / (endT.UnixNano()/1000/1000/1000 - startT.UnixNano()/1000/1000/1000)
  6214  	c.Assert(float64(realSpeed/1024) < float64(limitSpeed)*1.15, Equals, true)
  6215  	c.Assert(float64(realSpeed/1024) > float64(limitSpeed)*0.85, Equals, true)
  6216  
  6217  	// Get object and compare content
  6218  	fileBody, err := ioutil.ReadFile(tempFile)
  6219  	c.Assert(err, IsNil)
  6220  	c.Assert(textBuffer, Equals, string(fileBody))
  6221  
  6222  	bucket.DeleteObject(objectName)
  6223  	client.DeleteBucket(bucketName)
  6224  	c.Assert(err, IsNil)
  6225  	os.Remove(tempFile)
  6226  }
  6227  
  6228  // TestPutObject
  6229  func (s *OssBucketSuite) TestCloudBoxObject(c *C) {
  6230  
  6231  	c.Assert(len(cloudboxControlEndpoint) > 0, Equals, true)
  6232  
  6233  	var bucketName = bucketNamePrefix + "cloudbox-" + RandLowStr(6)
  6234  
  6235  	// control client
  6236  	clientControl, err := New(cloudboxControlEndpoint, accessID, accessKey)
  6237  	c.Assert(err, IsNil)
  6238  
  6239  	// Create bucket
  6240  	xmlBody := ""
  6241  	err = clientControl.CreateBucketXml(bucketName, xmlBody)
  6242  	c.Assert(err, IsNil)
  6243  
  6244  	// data client
  6245  	options := []ClientOption{
  6246  		Region(envRegion),
  6247  		AuthVersion(AuthV4),
  6248  		CloudBoxId(cloudBoxID),
  6249  	}
  6250  
  6251  	client, _ := New(endpoint, accessID, accessKey, options...)
  6252  
  6253  	bucket, err := client.Bucket(bucketName)
  6254  	c.Assert(err, IsNil)
  6255  
  6256  	objectName := objectNamePrefix + RandStr(8)
  6257  	objectValue := RandStr(1024 * 10)
  6258  
  6259  	// put object
  6260  	var respHeader http.Header
  6261  	err = bucket.PutObject(objectName, strings.NewReader(objectValue), GetResponseHeader(&respHeader))
  6262  	c.Assert(err, IsNil)
  6263  
  6264  	// check equal
  6265  	body, err := bucket.GetObject(objectName)
  6266  	c.Assert(err, IsNil)
  6267  	str, err := readBody(body)
  6268  	c.Assert(err, IsNil)
  6269  	c.Assert(str, Equals, objectValue)
  6270  
  6271  	// delete object
  6272  	err = bucket.DeleteObject(objectName)
  6273  	c.Assert(err, IsNil)
  6274  
  6275  	// check not exist
  6276  	_, err = bucket.GetObject(objectName)
  6277  	c.Assert(err, NotNil)
  6278  
  6279  	clientControl.DeleteBucket(bucketName)
  6280  }
  6281  
  6282  type CredentialsForSts struct {
  6283  	AccessKeyId     string
  6284  	AccessKeySecret string
  6285  	Expiration      time.Time
  6286  	SecurityToken   string
  6287  }
  6288  
  6289  type AssumedRoleUserForSts struct {
  6290  	Arn           string
  6291  	AssumedRoleId string
  6292  }
  6293  
  6294  type ResponseForSts struct {
  6295  	Credentials     CredentialsForSts
  6296  	AssumedRoleUser AssumedRoleUserForSts
  6297  	RequestId       string
  6298  }
  6299  
  6300  func stsAssumeRole(accessKeyId string, accessKeySecret string, roleArn string, sessionName string, expiredTime uint) (*ResponseForSts, error) {
  6301  	// StsSignVersion sts sign version
  6302  	StsSignVersion := "1.0"
  6303  	// StsAPIVersion sts api version
  6304  	StsAPIVersion := "2015-04-01"
  6305  	// StsHost sts host
  6306  	StsHost := "https://sts.aliyuncs.com/"
  6307  	// TimeFormat time fomrat
  6308  	TimeFormat := "2006-01-02T15:04:05Z"
  6309  	// RespBodyFormat  respone body format
  6310  	RespBodyFormat := "JSON"
  6311  	// PercentEncode '/'
  6312  	PercentEncode := "%2F"
  6313  	// HTTPGet http get method
  6314  	HTTPGet := "GET"
  6315  	rand.Seed(time.Now().UnixNano())
  6316  	uuid := fmt.Sprintf("Nonce-%d", rand.Intn(10000))
  6317  	queryStr := "SignatureVersion=" + StsSignVersion
  6318  	queryStr += "&Format=" + RespBodyFormat
  6319  	queryStr += "&Timestamp=" + url.QueryEscape(time.Now().UTC().Format(TimeFormat))
  6320  	queryStr += "&RoleArn=" + url.QueryEscape(roleArn)
  6321  	queryStr += "&RoleSessionName=" + sessionName
  6322  	queryStr += "&AccessKeyId=" + accessKeyId
  6323  	queryStr += "&SignatureMethod=HMAC-SHA1"
  6324  	queryStr += "&Version=" + StsAPIVersion
  6325  	queryStr += "&Action=AssumeRole"
  6326  	queryStr += "&SignatureNonce=" + uuid
  6327  	queryStr += "&DurationSeconds=" + strconv.FormatUint((uint64)(expiredTime), 10)
  6328  
  6329  	// Sort query string
  6330  	queryParams, err := url.ParseQuery(queryStr)
  6331  	if err != nil {
  6332  		return nil, err
  6333  	}
  6334  
  6335  	strToSign := HTTPGet + "&" + PercentEncode + "&" + url.QueryEscape(queryParams.Encode())
  6336  
  6337  	// Generate signature
  6338  	hashSign := hmac.New(sha1.New, []byte(accessKeySecret+"&"))
  6339  	hashSign.Write([]byte(strToSign))
  6340  	signature := base64.StdEncoding.EncodeToString(hashSign.Sum(nil))
  6341  
  6342  	// Build url
  6343  	assumeURL := StsHost + "?" + queryStr + "&Signature=" + url.QueryEscape(signature)
  6344  
  6345  	// Send Request
  6346  	tr := &http.Transport{
  6347  		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  6348  	}
  6349  	client := &http.Client{Transport: tr}
  6350  
  6351  	resp, err := client.Get(assumeURL)
  6352  	if err != nil {
  6353  		return nil, err
  6354  	}
  6355  	defer resp.Body.Close()
  6356  
  6357  	body, err := ioutil.ReadAll(resp.Body)
  6358  
  6359  	// Handle Response
  6360  	if resp.StatusCode != http.StatusOK {
  6361  		return nil, err
  6362  	}
  6363  
  6364  	result := ResponseForSts{}
  6365  	err = json.Unmarshal(body, &result)
  6366  	if err != nil {
  6367  		return nil, err
  6368  	}
  6369  	return &result, nil
  6370  }
  6371  
  6372  func (s *OssBucketSuite) TestPutObjectWithCallbackResult(c *C) {
  6373  	objectName := objectNamePrefix + RandStr(8)
  6374  	objectValue := "大江东去,浪淘尽,千古风流人物。 故垒西边,人道是、三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。" +
  6375  		"遥想公谨当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间、樯橹灰飞烟灭。故国神游,多情应笑我,早生华发,人生如梦,一尊还酹江月。"
  6376  	callbackMap := map[string]string{}
  6377  	callbackMap["callbackUrl"] = "www.aliyuncs.com"
  6378  	callbackMap["callbackBody"] = "filename=${object}&size=${size}&mimeType=${mimeType}"
  6379  	callbackMap["callbackBodyType"] = "application/x-www-form-urlencoded"
  6380  	callbackBuffer := bytes.NewBuffer([]byte{})
  6381  	callbackEncoder := json.NewEncoder(callbackBuffer)
  6382  	callbackEncoder.SetEscapeHTML(false)
  6383  	err := callbackEncoder.Encode(callbackMap)
  6384  	c.Assert(err, IsNil)
  6385  
  6386  	callbackVal := base64.StdEncoding.EncodeToString(callbackBuffer.Bytes())
  6387  	var pBody []byte
  6388  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue), Callback(callbackVal), CallbackResult(&pBody))
  6389  	e, ok := err.(ServiceError)
  6390  	c.Assert(ok, Equals, true)
  6391  	c.Assert(e.StatusCode, Equals, 203)
  6392  	c.Assert(e.Code, Equals, "CallbackFailed")
  6393  	c.Assert(pBody, IsNil)
  6394  
  6395  	//Check
  6396  	body, err := s.bucket.GetObject(objectName)
  6397  	c.Assert(err, IsNil)
  6398  	str, err := readBody(body)
  6399  	c.Assert(err, IsNil)
  6400  	c.Assert(str, Equals, objectValue)
  6401  }
  6402  
  6403  type TestCredentialsProviderError struct {
  6404  	AccessKeyId     string
  6405  	AccessKeySecret string
  6406  	SecurityToken   string
  6407  }
  6408  
  6409  func (testInfBuild *TestCredentialsProviderError) GetCredentials() Credentials {
  6410  	cred, _ := testInfBuild.GetCredentialsE()
  6411  	return cred
  6412  }
  6413  
  6414  func (testInfBuild *TestCredentialsProviderError) GetCredentialsE() (Credentials, error) {
  6415  	var provider *TestCredentials
  6416  	keyId := testInfBuild.AccessKeyId
  6417  	if keyId == "" {
  6418  		return provider, fmt.Errorf("access key id is empty!")
  6419  	}
  6420  	secret := testInfBuild.AccessKeySecret
  6421  	if secret == "" {
  6422  		return provider, fmt.Errorf("access key secret is empty!")
  6423  	}
  6424  	return &envCredentials{
  6425  		AccessKeyId:     keyId,
  6426  		AccessKeySecret: secret,
  6427  		SecurityToken:   "",
  6428  	}, nil
  6429  }
  6430  
  6431  func (s *OssBucketSuite) TestCredentialsProviderError(c *C) {
  6432  	var bucketNameTest = bucketNamePrefix + RandLowStr(6)
  6433  	client, err := New(endpoint, accessID, accessKey)
  6434  	c.Assert(err, IsNil)
  6435  	// Create
  6436  	err = client.CreateBucket(bucketNameTest)
  6437  	c.Assert(err, IsNil)
  6438  
  6439  	bucket, err := client.Bucket(bucketNameTest)
  6440  	c.Assert(err, IsNil)
  6441  
  6442  	objectName := objectNamePrefix + RandStr(8)
  6443  	objectValue := "大江东去,浪淘尽,千古风流人物。 故垒西边,人道是、三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。" +
  6444  		"遥想公谨当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间、樯橹灰飞烟灭。故国神游,多情应笑我,早生华发,人生如梦,一尊还酹江月。"
  6445  
  6446  	// Put string
  6447  	var respHeader http.Header
  6448  	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue), GetResponseHeader(&respHeader))
  6449  	c.Assert(err, IsNil)
  6450  
  6451  	var defaultBuild TestCredentialsProviderError
  6452  	defaultBuild.AccessKeyId = ""
  6453  	defaultBuild.AccessKeySecret = accessKey
  6454  	client, err = New(endpoint, "", "", SetCredentialsProvider(&defaultBuild))
  6455  	c.Assert(err, IsNil)
  6456  	err = client.DeleteBucket(bucketNameTest)
  6457  	c.Assert(err, NotNil)
  6458  	c.Assert(err.Error(), Equals, "access key id is empty!")
  6459  
  6460  	bucket, err = client.Bucket(bucketNameTest)
  6461  	c.Assert(err, IsNil)
  6462  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6463  	c.Assert(err, NotNil)
  6464  	c.Assert(err.Error(), Equals, "access key id is empty!")
  6465  
  6466  	channelName := "test-sign-rtmp-url"
  6467  	playlistName := "playlist.m3u8"
  6468  	_, err = bucket.SignRtmpURL(channelName, playlistName, 3600)
  6469  	c.Assert(err, IsNil)
  6470  
  6471  	defaultBuild.AccessKeyId = accessID
  6472  	defaultBuild.AccessKeySecret = ""
  6473  	client, err = New(endpoint, "", "", SetCredentialsProvider(&defaultBuild))
  6474  	c.Assert(err, IsNil)
  6475  	err = client.DeleteBucket(bucketNameTest)
  6476  	c.Assert(err, NotNil)
  6477  	c.Assert(err.Error(), Equals, "access key secret is empty!")
  6478  
  6479  	bucket, err = client.Bucket(bucketNameTest)
  6480  	c.Assert(err, IsNil)
  6481  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6482  	c.Assert(err, NotNil)
  6483  	c.Assert(err.Error(), Equals, "access key secret is empty!")
  6484  
  6485  	_, err = bucket.SignRtmpURL(channelName, playlistName, 3600)
  6486  	c.Assert(err, IsNil)
  6487  
  6488  	defaultBuild.AccessKeyId = accessID
  6489  	defaultBuild.AccessKeySecret = accessKey
  6490  	client, err = New(endpoint, "", "", SetCredentialsProvider(&defaultBuild))
  6491  	c.Assert(err, IsNil)
  6492  	err = client.DeleteBucket(bucketNameTest)
  6493  	c.Assert(err, IsNil)
  6494  
  6495  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6496  	c.Assert(err, IsNil)
  6497  
  6498  	_, err = bucket.SignRtmpURL(channelName, playlistName, 3600)
  6499  	c.Assert(err, IsNil)
  6500  }
  6501  
  6502  func (s *OssBucketSuite) TestVerifyObjectStrictAuthV1(c *C) {
  6503  	var bucketNameTest = bucketNamePrefix + RandLowStr(6)
  6504  	client, err := New(endpoint, accessID, accessKey)
  6505  	c.Assert(err, IsNil)
  6506  
  6507  	bucket, err := client.Bucket(bucketNameTest)
  6508  	c.Assert(err, IsNil)
  6509  
  6510  	objectName := "?" + objectNamePrefix + RandStr(8)
  6511  
  6512  	// Sign
  6513  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6514  	c.Assert(err, NotNil)
  6515  	c.Assert(err.Error(), Equals, "object name is invalid, can't start with '?'")
  6516  
  6517  	//
  6518  	objectName = ""
  6519  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6520  	c.Assert(err, NotNil)
  6521  	c.Assert(err.Error(), Equals, "object name is empty")
  6522  
  6523  	//Disable VerifyObjectStrictFlag
  6524  	client, err = New(endpoint, accessID, accessKey, VerifyObjectStrict(false))
  6525  	c.Assert(err, IsNil)
  6526  
  6527  	bucket, err = client.Bucket(bucketNameTest)
  6528  	c.Assert(err, IsNil)
  6529  
  6530  	objectName = "?"
  6531  	url, err := bucket.SignURL(objectName, http.MethodGet, 3600)
  6532  	c.Assert(err, IsNil)
  6533  	c.Assert(strings.Contains(url, "/%3F?Expires="), Equals, true)
  6534  
  6535  	objectName = "?123"
  6536  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6537  	c.Assert(err, IsNil)
  6538  	c.Assert(strings.Contains(url, "/%3F123?Expires="), Equals, true)
  6539  
  6540  	objectName = "123?"
  6541  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6542  	c.Assert(err, IsNil)
  6543  	c.Assert(strings.Contains(url, "/123%3F?Expires="), Equals, true)
  6544  }
  6545  
  6546  func (s *OssBucketSuite) TestVerifyObjectStrictAuthV2(c *C) {
  6547  	var bucketNameTest = bucketNamePrefix + RandLowStr(6)
  6548  	client, err := New(endpoint, accessID, accessKey, AuthVersion(AuthV2))
  6549  	c.Assert(err, IsNil)
  6550  
  6551  	bucket, err := client.Bucket(bucketNameTest)
  6552  	c.Assert(err, IsNil)
  6553  
  6554  	//
  6555  	objectName := ""
  6556  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6557  	c.Assert(err, NotNil)
  6558  	c.Assert(err.Error(), Equals, "object name is empty")
  6559  
  6560  	// Sign
  6561  	objectName = "?" + objectNamePrefix + RandStr(8)
  6562  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6563  	c.Assert(err, IsNil)
  6564  
  6565  	objectName = "?"
  6566  	url, err := bucket.SignURL(objectName, http.MethodGet, 3600)
  6567  	c.Assert(err, IsNil)
  6568  	c.Assert(strings.Contains(url, "/%3F?x-oss-access-key-id="), Equals, true)
  6569  
  6570  	objectName = "?123"
  6571  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6572  	c.Assert(err, IsNil)
  6573  	c.Assert(strings.Contains(url, "/%3F123?x-oss-access-key-id="), Equals, true)
  6574  
  6575  	//Disable VerifyObjectStrictFlag
  6576  	client, err = New(endpoint, accessID, accessKey, AuthVersion(AuthV2), VerifyObjectStrict(false))
  6577  	c.Assert(err, IsNil)
  6578  
  6579  	bucket, err = client.Bucket(bucketNameTest)
  6580  	c.Assert(err, IsNil)
  6581  
  6582  	objectName = "?"
  6583  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6584  	c.Assert(err, IsNil)
  6585  	c.Assert(strings.Contains(url, "/%3F?x-oss-access-key-id="), Equals, true)
  6586  
  6587  	objectName = "?123"
  6588  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6589  	c.Assert(err, IsNil)
  6590  	c.Assert(strings.Contains(url, "/%3F123?x-oss-access-key-id="), Equals, true)
  6591  
  6592  	objectName = "123?"
  6593  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6594  	c.Assert(err, IsNil)
  6595  	c.Assert(strings.Contains(url, "/123%3F?x-oss-access-key-id="), Equals, true)
  6596  }
  6597  
  6598  func (s *OssBucketSuite) TestVerifyObjectStrictAuthV4(c *C) {
  6599  	var bucketNameTest = bucketNamePrefix + RandLowStr(6)
  6600  	client, err := New(endpoint, accessID, accessKey, AuthVersion(AuthV4))
  6601  	c.Assert(err, IsNil)
  6602  
  6603  	bucket, err := client.Bucket(bucketNameTest)
  6604  	c.Assert(err, IsNil)
  6605  
  6606  	//
  6607  	objectName := ""
  6608  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6609  	c.Assert(err, NotNil)
  6610  	c.Assert(err.Error(), Equals, "object name is empty")
  6611  
  6612  	// Sign
  6613  	objectName = "?" + objectNamePrefix + RandStr(8)
  6614  	_, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6615  	c.Assert(err, IsNil)
  6616  
  6617  	objectName = "?"
  6618  	url, err := bucket.SignURL(objectName, http.MethodGet, 3600)
  6619  	c.Assert(err, IsNil)
  6620  	c.Assert(strings.Contains(url, "/%3F?x-oss-credential="), Equals, true)
  6621  
  6622  	objectName = "?123"
  6623  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6624  	c.Assert(err, IsNil)
  6625  	c.Assert(strings.Contains(url, "/%3F123?x-oss-credential="), Equals, true)
  6626  
  6627  	//Disable VerifyObjectStrictFlag
  6628  	client, err = New(endpoint, accessID, accessKey, AuthVersion(AuthV4), VerifyObjectStrict(false))
  6629  	c.Assert(err, IsNil)
  6630  
  6631  	bucket, err = client.Bucket(bucketNameTest)
  6632  	c.Assert(err, IsNil)
  6633  
  6634  	objectName = "?"
  6635  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6636  	c.Assert(err, IsNil)
  6637  	c.Assert(strings.Contains(url, "/%3F?x-oss-credential="), Equals, true)
  6638  
  6639  	objectName = "?123"
  6640  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6641  	c.Assert(err, IsNil)
  6642  	c.Assert(strings.Contains(url, "/%3F123?x-oss-credential="), Equals, true)
  6643  
  6644  	objectName = "123?"
  6645  	url, err = bucket.SignURL(objectName, http.MethodGet, 3600)
  6646  	c.Assert(err, IsNil)
  6647  	c.Assert(strings.Contains(url, "/123%3F?x-oss-credential="), Equals, true)
  6648  }
  6649  
  6650  type readerLenStub struct {
  6651  	r io.Reader
  6652  	n int
  6653  }
  6654  
  6655  func (r *readerLenStub) Read(p []byte) (n int, err error) {
  6656  	return r.r.Read(p)
  6657  }
  6658  
  6659  func (r *readerLenStub) Len() int {
  6660  	return r.n
  6661  }
  6662  
  6663  func (s *OssBucketSuite) TestPutObjectWithLimitReaderLen(c *C) {
  6664  	objectName := objectNamePrefix + RandStr(8)
  6665  	objectValue := RandStr(1023)
  6666  	sr := strings.NewReader(objectValue)
  6667  	rlen := &readerLenStub{
  6668  		r: sr,
  6669  		n: 100,
  6670  	}
  6671  	err := s.bucket.PutObject(objectName, rlen)
  6672  	c.Assert(err, NotNil)
  6673  	c.Assert(strings.Contains(err.Error(), " transport connection broken"), Equals, true)
  6674  	header, err := s.bucket.GetObjectMeta(objectName)
  6675  	c.Assert(err, NotNil)
  6676  	c.Assert(err.(ServiceError).Code, Equals, "NoSuchKey")
  6677  
  6678  	rlen.n = 1023
  6679  	sr.Seek(0, io.SeekStart)
  6680  	err = s.bucket.PutObject(objectName, rlen)
  6681  	c.Assert(err, IsNil)
  6682  	header, err = s.bucket.GetObjectMeta(objectName)
  6683  	c.Assert(err, IsNil)
  6684  	c.Assert("1023", Equals, header.Get("Content-Length"))
  6685  }