OSDN Git Service

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