OSDN Git Service

Create ossClient.go (#574)
[bytom/vapor.git] / vendor / github.com / aliyun / aliyun-oss-go-sdk / oss / client.go
1 // Package oss implements functions for access oss service.
2 // It has two main struct Client and Bucket.
3 package oss
4
5 import (
6         "bytes"
7         "encoding/xml"
8         "fmt"
9         "io"
10         "io/ioutil"
11         "log"
12         "net"
13         "net/http"
14         "strings"
15         "time"
16 )
17
18 // Client SDK's entry point. It's for bucket related options such as create/delete/set bucket (such as set/get ACL/lifecycle/referer/logging/website).
19 // Object related operations are done by Bucket class.
20 // Users use oss.New to create Client instance.
21 //
22 type (
23         // Client OSS client
24         Client struct {
25                 Config     *Config      // OSS client configuration
26                 Conn       *Conn        // Send HTTP request
27                 HTTPClient *http.Client //http.Client to use - if nil will make its own
28         }
29
30         // ClientOption client option such as UseCname, Timeout, SecurityToken.
31         ClientOption func(*Client)
32 )
33
34 // New creates a new client.
35 //
36 // endpoint    the OSS datacenter endpoint such as http://oss-cn-hangzhou.aliyuncs.com .
37 // accessKeyId    access key Id.
38 // accessKeySecret    access key secret.
39 //
40 // Client    creates the new client instance, the returned value is valid when error is nil.
41 // error    it's nil if no error, otherwise it's an error object.
42 //
43 func New(endpoint, accessKeyID, accessKeySecret string, options ...ClientOption) (*Client, error) {
44         // Configuration
45         config := getDefaultOssConfig()
46         config.Endpoint = endpoint
47         config.AccessKeyID = accessKeyID
48         config.AccessKeySecret = accessKeySecret
49
50         // URL parse
51         url := &urlMaker{}
52         err := url.Init(config.Endpoint, config.IsCname, config.IsUseProxy)
53         if err != nil {
54                 return nil, err
55         }
56
57         // HTTP connect
58         conn := &Conn{config: config, url: url}
59
60         // OSS client
61         client := &Client{
62                 Config: config,
63                 Conn:   conn,
64         }
65
66         // Client options parse
67         for _, option := range options {
68                 option(client)
69         }
70
71         if config.AuthVersion != AuthV1 && config.AuthVersion != AuthV2 {
72                 return nil, fmt.Errorf("Init client Error, invalid Auth version: %v", config.AuthVersion)
73         }
74
75         // Create HTTP connection
76         err = conn.init(config, url, client.HTTPClient)
77
78         return client, err
79 }
80
81 // Bucket gets the bucket instance.
82 //
83 // bucketName    the bucket name.
84 // Bucket    the bucket object, when error is nil.
85 //
86 // error    it's nil if no error, otherwise it's an error object.
87 //
88 func (client Client) Bucket(bucketName string) (*Bucket, error) {
89         err := CheckBucketName(bucketName)
90         if err != nil {
91                 return nil, err
92         }
93
94         return &Bucket{
95                 client,
96                 bucketName,
97         }, nil
98 }
99
100 // CreateBucket creates a bucket.
101 //
102 // bucketName    the bucket name, it's globably unique and immutable. The bucket name can only consist of lowercase letters, numbers and dash ('-').
103 //               It must start with lowercase letter or number and the length can only be between 3 and 255.
104 // options    options for creating the bucket, with optional ACL. The ACL could be ACLPrivate, ACLPublicRead, and ACLPublicReadWrite. By default it's ACLPrivate.
105 //            It could also be specified with StorageClass option, which supports StorageStandard, StorageIA(infrequent access), StorageArchive.
106 //
107 // error    it's nil if no error, otherwise it's an error object.
108 //
109 func (client Client) CreateBucket(bucketName string, options ...Option) error {
110         headers := make(map[string]string)
111         handleOptions(headers, options)
112
113         buffer := new(bytes.Buffer)
114
115         var cbConfig createBucketConfiguration
116         cbConfig.StorageClass = StorageStandard
117
118         isStorageSet, valStroage, _ := IsOptionSet(options, storageClass)
119         isRedundancySet, valRedundancy, _ := IsOptionSet(options, redundancyType)
120         if isStorageSet {
121                 cbConfig.StorageClass = valStroage.(StorageClassType)
122         }
123
124         if isRedundancySet {
125                 cbConfig.DataRedundancyType = valRedundancy.(DataRedundancyType)
126         }
127
128         bs, err := xml.Marshal(cbConfig)
129         if err != nil {
130                 return err
131         }
132         buffer.Write(bs)
133         contentType := http.DetectContentType(buffer.Bytes())
134         headers[HTTPHeaderContentType] = contentType
135
136         params := map[string]interface{}{}
137         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
138         if err != nil {
139                 return err
140         }
141
142         defer resp.Body.Close()
143         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
144 }
145
146 // ListBuckets lists buckets of the current account under the given endpoint, with optional filters.
147 //
148 // options    specifies the filters such as Prefix, Marker and MaxKeys. Prefix is the bucket name's prefix filter.
149 //            And marker makes sure the returned buckets' name are greater than it in lexicographic order.
150 //            Maxkeys limits the max keys to return, and by default it's 100 and up to 1000.
151 //            For the common usage scenario, please check out list_bucket.go in the sample.
152 // ListBucketsResponse    the response object if error is nil.
153 //
154 // error    it's nil if no error, otherwise it's an error object.
155 //
156 func (client Client) ListBuckets(options ...Option) (ListBucketsResult, error) {
157         var out ListBucketsResult
158
159         params, err := GetRawParams(options)
160         if err != nil {
161                 return out, err
162         }
163
164         resp, err := client.do("GET", "", params, nil, nil, options...)
165         if err != nil {
166                 return out, err
167         }
168         defer resp.Body.Close()
169
170         err = xmlUnmarshal(resp.Body, &out)
171         return out, err
172 }
173
174 // IsBucketExist checks if the bucket exists
175 //
176 // bucketName    the bucket name.
177 //
178 // bool    true if it exists, and it's only valid when error is nil.
179 // error    it's nil if no error, otherwise it's an error object.
180 //
181 func (client Client) IsBucketExist(bucketName string) (bool, error) {
182         listRes, err := client.ListBuckets(Prefix(bucketName), MaxKeys(1))
183         if err != nil {
184                 return false, err
185         }
186
187         if len(listRes.Buckets) == 1 && listRes.Buckets[0].Name == bucketName {
188                 return true, nil
189         }
190         return false, nil
191 }
192
193 // DeleteBucket deletes the bucket. Only empty bucket can be deleted (no object and parts).
194 //
195 // bucketName    the bucket name.
196 //
197 // error    it's nil if no error, otherwise it's an error object.
198 //
199 func (client Client) DeleteBucket(bucketName string, options ...Option) error {
200         params := map[string]interface{}{}
201         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
202         if err != nil {
203                 return err
204         }
205
206         defer resp.Body.Close()
207         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
208 }
209
210 // GetBucketLocation gets the bucket location.
211 //
212 // Checks out the following link for more information :
213 // https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html
214 //
215 // bucketName    the bucket name
216 //
217 // string    bucket's datacenter location
218 // error    it's nil if no error, otherwise it's an error object.
219 //
220 func (client Client) GetBucketLocation(bucketName string) (string, error) {
221         params := map[string]interface{}{}
222         params["location"] = nil
223         resp, err := client.do("GET", bucketName, params, nil, nil)
224         if err != nil {
225                 return "", err
226         }
227         defer resp.Body.Close()
228
229         var LocationConstraint string
230         err = xmlUnmarshal(resp.Body, &LocationConstraint)
231         return LocationConstraint, err
232 }
233
234 // SetBucketACL sets bucket's ACL.
235 //
236 // bucketName    the bucket name
237 // bucketAcl    the bucket ACL: ACLPrivate, ACLPublicRead and ACLPublicReadWrite.
238 //
239 // error    it's nil if no error, otherwise it's an error object.
240 //
241 func (client Client) SetBucketACL(bucketName string, bucketACL ACLType) error {
242         headers := map[string]string{HTTPHeaderOssACL: string(bucketACL)}
243         params := map[string]interface{}{}
244         params["acl"] = nil
245         resp, err := client.do("PUT", bucketName, params, headers, nil)
246         if err != nil {
247                 return err
248         }
249         defer resp.Body.Close()
250         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
251 }
252
253 // GetBucketACL gets the bucket ACL.
254 //
255 // bucketName    the bucket name.
256 //
257 // GetBucketAclResponse    the result object, and it's only valid when error is nil.
258 // error    it's nil if no error, otherwise it's an error object.
259 //
260 func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error) {
261         var out GetBucketACLResult
262         params := map[string]interface{}{}
263         params["acl"] = nil
264         resp, err := client.do("GET", bucketName, params, nil, nil)
265         if err != nil {
266                 return out, err
267         }
268         defer resp.Body.Close()
269
270         err = xmlUnmarshal(resp.Body, &out)
271         return out, err
272 }
273
274 // SetBucketLifecycle sets the bucket's lifecycle.
275 //
276 // For more information, checks out following link:
277 // https://help.aliyun.com/document_detail/oss/user_guide/manage_object/object_lifecycle.html
278 //
279 // bucketName    the bucket name.
280 // rules    the lifecycle rules. There're two kind of rules: absolute time expiration and relative time expiration in days and day/month/year respectively.
281 //          Check out sample/bucket_lifecycle.go for more details.
282 //
283 // error    it's nil if no error, otherwise it's an error object.
284 //
285 func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule) error {
286         err := verifyLifecycleRules(rules)
287         if err != nil {
288                 return err
289         }
290         lifecycleCfg := LifecycleConfiguration{Rules: rules}
291         bs, err := xml.Marshal(lifecycleCfg)
292         if err != nil {
293                 return err
294         }
295         buffer := new(bytes.Buffer)
296         buffer.Write(bs)
297
298         contentType := http.DetectContentType(buffer.Bytes())
299         headers := map[string]string{}
300         headers[HTTPHeaderContentType] = contentType
301
302         params := map[string]interface{}{}
303         params["lifecycle"] = nil
304         resp, err := client.do("PUT", bucketName, params, headers, buffer)
305         if err != nil {
306                 return err
307         }
308         defer resp.Body.Close()
309         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
310 }
311
312 // DeleteBucketLifecycle deletes the bucket's lifecycle.
313 //
314 //
315 // bucketName    the bucket name.
316 //
317 // error    it's nil if no error, otherwise it's an error object.
318 //
319 func (client Client) DeleteBucketLifecycle(bucketName string) error {
320         params := map[string]interface{}{}
321         params["lifecycle"] = nil
322         resp, err := client.do("DELETE", bucketName, params, nil, nil)
323         if err != nil {
324                 return err
325         }
326         defer resp.Body.Close()
327         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
328 }
329
330 // GetBucketLifecycle gets the bucket's lifecycle settings.
331 //
332 // bucketName    the bucket name.
333 //
334 // GetBucketLifecycleResponse    the result object upon successful request. It's only valid when error is nil.
335 // error    it's nil if no error, otherwise it's an error object.
336 //
337 func (client Client) GetBucketLifecycle(bucketName string) (GetBucketLifecycleResult, error) {
338         var out GetBucketLifecycleResult
339         params := map[string]interface{}{}
340         params["lifecycle"] = nil
341         resp, err := client.do("GET", bucketName, params, nil, nil)
342         if err != nil {
343                 return out, err
344         }
345         defer resp.Body.Close()
346
347         err = xmlUnmarshal(resp.Body, &out)
348
349         // NonVersionTransition is not suggested to use
350         // to keep compatible
351         for k, rule := range out.Rules {
352                 if len(rule.NonVersionTransitions) > 0 {
353                         out.Rules[k].NonVersionTransition = &(out.Rules[k].NonVersionTransitions[0])
354                 }
355         }
356         return out, err
357 }
358
359 // SetBucketReferer sets the bucket's referer whitelist and the flag if allowing empty referrer.
360 //
361 // To avoid stealing link on OSS data, OSS supports the HTTP referrer header. A whitelist referrer could be set either by API or web console, as well as
362 // the allowing empty referrer flag. Note that this applies to requests from webbrowser only.
363 // For example, for a bucket os-example and its referrer http://www.aliyun.com, all requests from this URL could access the bucket.
364 // For more information, please check out this link :
365 // https://help.aliyun.com/document_detail/oss/user_guide/security_management/referer.html
366 //
367 // bucketName    the bucket name.
368 // referers    the referrer white list. A bucket could have a referrer list and each referrer supports one '*' and multiple '?' as wildcards.
369 //             The sample could be found in sample/bucket_referer.go
370 // allowEmptyReferer    the flag of allowing empty referrer. By default it's true.
371 //
372 // error    it's nil if no error, otherwise it's an error object.
373 //
374 func (client Client) SetBucketReferer(bucketName string, referers []string, allowEmptyReferer bool) error {
375         rxml := RefererXML{}
376         rxml.AllowEmptyReferer = allowEmptyReferer
377         if referers == nil {
378                 rxml.RefererList = append(rxml.RefererList, "")
379         } else {
380                 for _, referer := range referers {
381                         rxml.RefererList = append(rxml.RefererList, referer)
382                 }
383         }
384
385         bs, err := xml.Marshal(rxml)
386         if err != nil {
387                 return err
388         }
389         buffer := new(bytes.Buffer)
390         buffer.Write(bs)
391
392         contentType := http.DetectContentType(buffer.Bytes())
393         headers := map[string]string{}
394         headers[HTTPHeaderContentType] = contentType
395
396         params := map[string]interface{}{}
397         params["referer"] = nil
398         resp, err := client.do("PUT", bucketName, params, headers, buffer)
399         if err != nil {
400                 return err
401         }
402         defer resp.Body.Close()
403         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
404 }
405
406 // GetBucketReferer gets the bucket's referrer white list.
407 //
408 // bucketName    the bucket name.
409 //
410 // GetBucketRefererResponse    the result object upon successful request. It's only valid when error is nil.
411 // error    it's nil if no error, otherwise it's an error object.
412 //
413 func (client Client) GetBucketReferer(bucketName string) (GetBucketRefererResult, error) {
414         var out GetBucketRefererResult
415         params := map[string]interface{}{}
416         params["referer"] = nil
417         resp, err := client.do("GET", bucketName, params, nil, nil)
418         if err != nil {
419                 return out, err
420         }
421         defer resp.Body.Close()
422
423         err = xmlUnmarshal(resp.Body, &out)
424         return out, err
425 }
426
427 // SetBucketLogging sets the bucket logging settings.
428 //
429 // OSS could automatically store the access log. Only the bucket owner could enable the logging.
430 // Once enabled, OSS would save all the access log into hourly log files in a specified bucket.
431 // For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/logging.html
432 //
433 // bucketName    bucket name to enable the log.
434 // targetBucket    the target bucket name to store the log files.
435 // targetPrefix    the log files' prefix.
436 //
437 // error    it's nil if no error, otherwise it's an error object.
438 //
439 func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix string,
440         isEnable bool) error {
441         var err error
442         var bs []byte
443         if isEnable {
444                 lxml := LoggingXML{}
445                 lxml.LoggingEnabled.TargetBucket = targetBucket
446                 lxml.LoggingEnabled.TargetPrefix = targetPrefix
447                 bs, err = xml.Marshal(lxml)
448         } else {
449                 lxml := loggingXMLEmpty{}
450                 bs, err = xml.Marshal(lxml)
451         }
452
453         if err != nil {
454                 return err
455         }
456
457         buffer := new(bytes.Buffer)
458         buffer.Write(bs)
459
460         contentType := http.DetectContentType(buffer.Bytes())
461         headers := map[string]string{}
462         headers[HTTPHeaderContentType] = contentType
463
464         params := map[string]interface{}{}
465         params["logging"] = nil
466         resp, err := client.do("PUT", bucketName, params, headers, buffer)
467         if err != nil {
468                 return err
469         }
470         defer resp.Body.Close()
471         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
472 }
473
474 // DeleteBucketLogging deletes the logging configuration to disable the logging on the bucket.
475 //
476 // bucketName    the bucket name to disable the logging.
477 //
478 // error    it's nil if no error, otherwise it's an error object.
479 //
480 func (client Client) DeleteBucketLogging(bucketName string) error {
481         params := map[string]interface{}{}
482         params["logging"] = nil
483         resp, err := client.do("DELETE", bucketName, params, nil, nil)
484         if err != nil {
485                 return err
486         }
487         defer resp.Body.Close()
488         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
489 }
490
491 // GetBucketLogging gets the bucket's logging settings
492 //
493 // bucketName    the bucket name
494 // GetBucketLoggingResponse    the result object upon successful request. It's only valid when error is nil.
495 //
496 // error    it's nil if no error, otherwise it's an error object.
497 //
498 func (client Client) GetBucketLogging(bucketName string) (GetBucketLoggingResult, error) {
499         var out GetBucketLoggingResult
500         params := map[string]interface{}{}
501         params["logging"] = nil
502         resp, err := client.do("GET", bucketName, params, nil, nil)
503         if err != nil {
504                 return out, err
505         }
506         defer resp.Body.Close()
507
508         err = xmlUnmarshal(resp.Body, &out)
509         return out, err
510 }
511
512 // SetBucketWebsite sets the bucket's static website's index and error page.
513 //
514 // OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
515 // For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
516 //
517 // bucketName    the bucket name to enable static web site.
518 // indexDocument    index page.
519 // errorDocument    error page.
520 //
521 // error    it's nil if no error, otherwise it's an error object.
522 //
523 func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument string) error {
524         wxml := WebsiteXML{}
525         wxml.IndexDocument.Suffix = indexDocument
526         wxml.ErrorDocument.Key = errorDocument
527
528         bs, err := xml.Marshal(wxml)
529         if err != nil {
530                 return err
531         }
532         buffer := new(bytes.Buffer)
533         buffer.Write(bs)
534
535         contentType := http.DetectContentType(buffer.Bytes())
536         headers := make(map[string]string)
537         headers[HTTPHeaderContentType] = contentType
538
539         params := map[string]interface{}{}
540         params["website"] = nil
541         resp, err := client.do("PUT", bucketName, params, headers, buffer)
542         if err != nil {
543                 return err
544         }
545         defer resp.Body.Close()
546         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
547 }
548
549 // SetBucketWebsiteDetail sets the bucket's static website's detail
550 //
551 // OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
552 // For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
553 //
554 // bucketName the bucket name to enable static web site.
555 //
556 // wxml the website's detail
557 //
558 // error    it's nil if no error, otherwise it's an error object.
559 //
560 func (client Client) SetBucketWebsiteDetail(bucketName string, wxml WebsiteXML, options ...Option) error {
561         bs, err := xml.Marshal(wxml)
562         if err != nil {
563                 return err
564         }
565         buffer := new(bytes.Buffer)
566         buffer.Write(bs)
567
568         contentType := http.DetectContentType(buffer.Bytes())
569         headers := make(map[string]string)
570         headers[HTTPHeaderContentType] = contentType
571
572         params := map[string]interface{}{}
573         params["website"] = nil
574         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
575         if err != nil {
576                 return err
577         }
578         defer resp.Body.Close()
579         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
580 }
581
582 // SetBucketWebsiteXml sets the bucket's static website's rule
583 //
584 // OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
585 // For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
586 //
587 // bucketName the bucket name to enable static web site.
588 //
589 // wxml the website's detail
590 //
591 // error    it's nil if no error, otherwise it's an error object.
592 //
593 func (client Client) SetBucketWebsiteXml(bucketName string, webXml string, options ...Option) error {
594         buffer := new(bytes.Buffer)
595         buffer.Write([]byte(webXml))
596
597         contentType := http.DetectContentType(buffer.Bytes())
598         headers := make(map[string]string)
599         headers[HTTPHeaderContentType] = contentType
600
601         params := map[string]interface{}{}
602         params["website"] = nil
603         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
604         if err != nil {
605                 return err
606         }
607         defer resp.Body.Close()
608         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
609 }
610
611 // DeleteBucketWebsite deletes the bucket's static web site settings.
612 //
613 // bucketName    the bucket name.
614 //
615 // error    it's nil if no error, otherwise it's an error object.
616 //
617 func (client Client) DeleteBucketWebsite(bucketName string) error {
618         params := map[string]interface{}{}
619         params["website"] = nil
620         resp, err := client.do("DELETE", bucketName, params, nil, nil)
621         if err != nil {
622                 return err
623         }
624         defer resp.Body.Close()
625         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
626 }
627
628 // GetBucketWebsite gets the bucket's default page (index page) and the error page.
629 //
630 // bucketName    the bucket name
631 //
632 // GetBucketWebsiteResponse    the result object upon successful request. It's only valid when error is nil.
633 // error    it's nil if no error, otherwise it's an error object.
634 //
635 func (client Client) GetBucketWebsite(bucketName string) (GetBucketWebsiteResult, error) {
636         var out GetBucketWebsiteResult
637         params := map[string]interface{}{}
638         params["website"] = nil
639         resp, err := client.do("GET", bucketName, params, nil, nil)
640         if err != nil {
641                 return out, err
642         }
643         defer resp.Body.Close()
644
645         err = xmlUnmarshal(resp.Body, &out)
646         return out, err
647 }
648
649 // SetBucketCORS sets the bucket's CORS rules
650 //
651 // For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/cors.html
652 //
653 // bucketName    the bucket name
654 // corsRules    the CORS rules to set. The related sample code is in sample/bucket_cors.go.
655 //
656 // error    it's nil if no error, otherwise it's an error object.
657 //
658 func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) error {
659         corsxml := CORSXML{}
660         for _, v := range corsRules {
661                 cr := CORSRule{}
662                 cr.AllowedMethod = v.AllowedMethod
663                 cr.AllowedOrigin = v.AllowedOrigin
664                 cr.AllowedHeader = v.AllowedHeader
665                 cr.ExposeHeader = v.ExposeHeader
666                 cr.MaxAgeSeconds = v.MaxAgeSeconds
667                 corsxml.CORSRules = append(corsxml.CORSRules, cr)
668         }
669
670         bs, err := xml.Marshal(corsxml)
671         if err != nil {
672                 return err
673         }
674         buffer := new(bytes.Buffer)
675         buffer.Write(bs)
676
677         contentType := http.DetectContentType(buffer.Bytes())
678         headers := map[string]string{}
679         headers[HTTPHeaderContentType] = contentType
680
681         params := map[string]interface{}{}
682         params["cors"] = nil
683         resp, err := client.do("PUT", bucketName, params, headers, buffer)
684         if err != nil {
685                 return err
686         }
687         defer resp.Body.Close()
688         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
689 }
690
691 // DeleteBucketCORS deletes the bucket's static website settings.
692 //
693 // bucketName    the bucket name.
694 //
695 // error    it's nil if no error, otherwise it's an error object.
696 //
697 func (client Client) DeleteBucketCORS(bucketName string) error {
698         params := map[string]interface{}{}
699         params["cors"] = nil
700         resp, err := client.do("DELETE", bucketName, params, nil, nil)
701         if err != nil {
702                 return err
703         }
704         defer resp.Body.Close()
705         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
706 }
707
708 // GetBucketCORS gets the bucket's CORS settings.
709 //
710 // bucketName    the bucket name.
711 // GetBucketCORSResult    the result object upon successful request. It's only valid when error is nil.
712 //
713 // error    it's nil if no error, otherwise it's an error object.
714 //
715 func (client Client) GetBucketCORS(bucketName string) (GetBucketCORSResult, error) {
716         var out GetBucketCORSResult
717         params := map[string]interface{}{}
718         params["cors"] = nil
719         resp, err := client.do("GET", bucketName, params, nil, nil)
720         if err != nil {
721                 return out, err
722         }
723         defer resp.Body.Close()
724
725         err = xmlUnmarshal(resp.Body, &out)
726         return out, err
727 }
728
729 // GetBucketInfo gets the bucket information.
730 //
731 // bucketName    the bucket name.
732 // GetBucketInfoResult    the result object upon successful request. It's only valid when error is nil.
733 //
734 // error    it's nil if no error, otherwise it's an error object.
735 //
736 func (client Client) GetBucketInfo(bucketName string, options ...Option) (GetBucketInfoResult, error) {
737         var out GetBucketInfoResult
738         params := map[string]interface{}{}
739         params["bucketInfo"] = nil
740         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
741         if err != nil {
742                 return out, err
743         }
744         defer resp.Body.Close()
745
746         err = xmlUnmarshal(resp.Body, &out)
747
748         // convert None to ""
749         if err == nil {
750                 if out.BucketInfo.SseRule.KMSMasterKeyID == "None" {
751                         out.BucketInfo.SseRule.KMSMasterKeyID = ""
752                 }
753
754                 if out.BucketInfo.SseRule.SSEAlgorithm == "None" {
755                         out.BucketInfo.SseRule.SSEAlgorithm = ""
756                 }
757
758                 if out.BucketInfo.SseRule.KMSDataEncryption == "None" {
759                         out.BucketInfo.SseRule.KMSDataEncryption = ""
760                 }
761         }
762         return out, err
763 }
764
765 // SetBucketVersioning set bucket versioning:Enabled、Suspended
766 // bucketName    the bucket name.
767 // error    it's nil if no error, otherwise it's an error object.
768 func (client Client) SetBucketVersioning(bucketName string, versioningConfig VersioningConfig, options ...Option) error {
769         var err error
770         var bs []byte
771         bs, err = xml.Marshal(versioningConfig)
772
773         if err != nil {
774                 return err
775         }
776
777         buffer := new(bytes.Buffer)
778         buffer.Write(bs)
779
780         contentType := http.DetectContentType(buffer.Bytes())
781         headers := map[string]string{}
782         headers[HTTPHeaderContentType] = contentType
783
784         params := map[string]interface{}{}
785         params["versioning"] = nil
786         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
787
788         if err != nil {
789                 return err
790         }
791         defer resp.Body.Close()
792         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
793 }
794
795 // GetBucketVersioning get bucket versioning status:Enabled、Suspended
796 // bucketName    the bucket name.
797 // error    it's nil if no error, otherwise it's an error object.
798 func (client Client) GetBucketVersioning(bucketName string, options ...Option) (GetBucketVersioningResult, error) {
799         var out GetBucketVersioningResult
800         params := map[string]interface{}{}
801         params["versioning"] = nil
802         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
803
804         if err != nil {
805                 return out, err
806         }
807         defer resp.Body.Close()
808
809         err = xmlUnmarshal(resp.Body, &out)
810         return out, err
811 }
812
813 // SetBucketEncryption set bucket encryption config
814 // bucketName    the bucket name.
815 // error    it's nil if no error, otherwise it's an error object.
816 func (client Client) SetBucketEncryption(bucketName string, encryptionRule ServerEncryptionRule, options ...Option) error {
817         var err error
818         var bs []byte
819         bs, err = xml.Marshal(encryptionRule)
820
821         if err != nil {
822                 return err
823         }
824
825         buffer := new(bytes.Buffer)
826         buffer.Write(bs)
827
828         contentType := http.DetectContentType(buffer.Bytes())
829         headers := map[string]string{}
830         headers[HTTPHeaderContentType] = contentType
831
832         params := map[string]interface{}{}
833         params["encryption"] = nil
834         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
835
836         if err != nil {
837                 return err
838         }
839         defer resp.Body.Close()
840         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
841 }
842
843 // GetBucketEncryption get bucket encryption
844 // bucketName    the bucket name.
845 // error    it's nil if no error, otherwise it's an error object.
846 func (client Client) GetBucketEncryption(bucketName string, options ...Option) (GetBucketEncryptionResult, error) {
847         var out GetBucketEncryptionResult
848         params := map[string]interface{}{}
849         params["encryption"] = nil
850         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
851
852         if err != nil {
853                 return out, err
854         }
855         defer resp.Body.Close()
856
857         err = xmlUnmarshal(resp.Body, &out)
858         return out, err
859 }
860
861 // DeleteBucketEncryption delete bucket encryption config
862 // bucketName    the bucket name.
863 // error    it's nil if no error, otherwise it's an error bucket
864 func (client Client) DeleteBucketEncryption(bucketName string, options ...Option) error {
865         params := map[string]interface{}{}
866         params["encryption"] = nil
867         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
868
869         if err != nil {
870                 return err
871         }
872         defer resp.Body.Close()
873         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
874 }
875
876 //
877 // SetBucketTagging add tagging to bucket
878 // bucketName  name of bucket
879 // tagging    tagging to be added
880 // error        nil if success, otherwise error
881 func (client Client) SetBucketTagging(bucketName string, tagging Tagging, options ...Option) error {
882         var err error
883         var bs []byte
884         bs, err = xml.Marshal(tagging)
885
886         if err != nil {
887                 return err
888         }
889
890         buffer := new(bytes.Buffer)
891         buffer.Write(bs)
892
893         contentType := http.DetectContentType(buffer.Bytes())
894         headers := map[string]string{}
895         headers[HTTPHeaderContentType] = contentType
896
897         params := map[string]interface{}{}
898         params["tagging"] = nil
899         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
900         if err != nil {
901                 return err
902         }
903         defer resp.Body.Close()
904         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
905 }
906
907 // GetBucketTagging get tagging of the bucket
908 // bucketName  name of bucket
909 // error      nil if success, otherwise error
910 func (client Client) GetBucketTagging(bucketName string, options ...Option) (GetBucketTaggingResult, error) {
911         var out GetBucketTaggingResult
912         params := map[string]interface{}{}
913         params["tagging"] = nil
914         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
915         if err != nil {
916                 return out, err
917         }
918         defer resp.Body.Close()
919
920         err = xmlUnmarshal(resp.Body, &out)
921         return out, err
922 }
923
924 //
925 // DeleteBucketTagging delete bucket tagging
926 // bucketName  name of bucket
927 // error      nil if success, otherwise error
928 //
929 func (client Client) DeleteBucketTagging(bucketName string, options ...Option) error {
930         params := map[string]interface{}{}
931         params["tagging"] = nil
932         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
933         if err != nil {
934                 return err
935         }
936         defer resp.Body.Close()
937         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
938 }
939
940 // GetBucketStat get bucket stat
941 // bucketName    the bucket name.
942 // error    it's nil if no error, otherwise it's an error object.
943 func (client Client) GetBucketStat(bucketName string) (GetBucketStatResult, error) {
944         var out GetBucketStatResult
945         params := map[string]interface{}{}
946         params["stat"] = nil
947         resp, err := client.do("GET", bucketName, params, nil, nil)
948         if err != nil {
949                 return out, err
950         }
951         defer resp.Body.Close()
952
953         err = xmlUnmarshal(resp.Body, &out)
954         return out, err
955 }
956
957 // GetBucketPolicy API operation for Object Storage Service.
958 //
959 // Get the policy from the bucket.
960 //
961 // bucketName    the bucket name.
962 //
963 // string                return the bucket's policy, and it's only valid when error is nil.
964 //
965 // error                 it's nil if no error, otherwise it's an error object.
966 //
967 func (client Client) GetBucketPolicy(bucketName string, options ...Option) (string, error) {
968         params := map[string]interface{}{}
969         params["policy"] = nil
970
971         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
972         if err != nil {
973                 return "", err
974         }
975         defer resp.Body.Close()
976
977         body, err := ioutil.ReadAll(resp.Body)
978
979         out := string(body)
980         return out, err
981 }
982
983 // SetBucketPolicy API operation for Object Storage Service.
984 //
985 // Set the policy from the bucket.
986 //
987 // bucketName the bucket name.
988 //
989 // policy the bucket policy.
990 //
991 // error    it's nil if no error, otherwise it's an error object.
992 //
993 func (client Client) SetBucketPolicy(bucketName string, policy string, options ...Option) error {
994         params := map[string]interface{}{}
995         params["policy"] = nil
996
997         buffer := strings.NewReader(policy)
998
999         resp, err := client.do("PUT", bucketName, params, nil, buffer, options...)
1000         if err != nil {
1001                 return err
1002         }
1003         defer resp.Body.Close()
1004
1005         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1006 }
1007
1008 // DeleteBucketPolicy API operation for Object Storage Service.
1009 //
1010 // Deletes the policy from the bucket.
1011 //
1012 // bucketName the bucket name.
1013 //
1014 // error    it's nil if no error, otherwise it's an error object.
1015 //
1016 func (client Client) DeleteBucketPolicy(bucketName string, options ...Option) error {
1017         params := map[string]interface{}{}
1018         params["policy"] = nil
1019         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
1020         if err != nil {
1021                 return err
1022         }
1023
1024         defer resp.Body.Close()
1025         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
1026 }
1027
1028 // SetBucketRequestPayment API operation for Object Storage Service.
1029 //
1030 // Set the requestPayment of bucket
1031 //
1032 // bucketName the bucket name.
1033 //
1034 // paymentConfig the payment configuration
1035 //
1036 // error it's nil if no error, otherwise it's an error object.
1037 //
1038 func (client Client) SetBucketRequestPayment(bucketName string, paymentConfig RequestPaymentConfiguration, options ...Option) error {
1039         params := map[string]interface{}{}
1040         params["requestPayment"] = nil
1041
1042         var bs []byte
1043         bs, err := xml.Marshal(paymentConfig)
1044
1045         if err != nil {
1046                 return err
1047         }
1048
1049         buffer := new(bytes.Buffer)
1050         buffer.Write(bs)
1051
1052         contentType := http.DetectContentType(buffer.Bytes())
1053         headers := map[string]string{}
1054         headers[HTTPHeaderContentType] = contentType
1055
1056         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
1057         if err != nil {
1058                 return err
1059         }
1060         defer resp.Body.Close()
1061         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1062 }
1063
1064 // GetBucketRequestPayment API operation for Object Storage Service.
1065 //
1066 // Get bucket requestPayment
1067 //
1068 // bucketName the bucket name.
1069 //
1070 // RequestPaymentConfiguration the payment configuration
1071 //
1072 // error it's nil if no error, otherwise it's an error object.
1073 //
1074 func (client Client) GetBucketRequestPayment(bucketName string, options ...Option) (RequestPaymentConfiguration, error) {
1075         var out RequestPaymentConfiguration
1076         params := map[string]interface{}{}
1077         params["requestPayment"] = nil
1078
1079         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
1080         if err != nil {
1081                 return out, err
1082         }
1083         defer resp.Body.Close()
1084
1085         err = xmlUnmarshal(resp.Body, &out)
1086         return out, err
1087 }
1088
1089 // GetUserQoSInfo API operation for Object Storage Service.
1090 //
1091 // Get user qos.
1092 //
1093 // UserQoSConfiguration the User Qos and range Information.
1094 //
1095 // error    it's nil if no error, otherwise it's an error object.
1096 //
1097 func (client Client) GetUserQoSInfo(options ...Option) (UserQoSConfiguration, error) {
1098         var out UserQoSConfiguration
1099         params := map[string]interface{}{}
1100         params["qosInfo"] = nil
1101
1102         resp, err := client.do("GET", "", params, nil, nil, options...)
1103         if err != nil {
1104                 return out, err
1105         }
1106         defer resp.Body.Close()
1107
1108         err = xmlUnmarshal(resp.Body, &out)
1109         return out, err
1110 }
1111
1112 // SetBucketQoSInfo API operation for Object Storage Service.
1113 //
1114 // Set Bucket Qos information.
1115 //
1116 // bucketName the bucket name.
1117 //
1118 // qosConf the qos configuration.
1119 //
1120 // error    it's nil if no error, otherwise it's an error object.
1121 //
1122 func (client Client) SetBucketQoSInfo(bucketName string, qosConf BucketQoSConfiguration, options ...Option) error {
1123         params := map[string]interface{}{}
1124         params["qosInfo"] = nil
1125
1126         var bs []byte
1127         bs, err := xml.Marshal(qosConf)
1128         if err != nil {
1129                 return err
1130         }
1131         buffer := new(bytes.Buffer)
1132         buffer.Write(bs)
1133
1134         contentTpye := http.DetectContentType(buffer.Bytes())
1135         headers := map[string]string{}
1136         headers[HTTPHeaderContentType] = contentTpye
1137
1138         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
1139         if err != nil {
1140                 return err
1141         }
1142
1143         defer resp.Body.Close()
1144         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1145 }
1146
1147 // GetBucketQosInfo API operation for Object Storage Service.
1148 //
1149 // Get Bucket Qos information.
1150 //
1151 // bucketName the bucket name.
1152 //
1153 // BucketQoSConfiguration the  return qos configuration.
1154 //
1155 // error    it's nil if no error, otherwise it's an error object.
1156 //
1157 func (client Client) GetBucketQosInfo(bucketName string, options ...Option) (BucketQoSConfiguration, error) {
1158         var out BucketQoSConfiguration
1159         params := map[string]interface{}{}
1160         params["qosInfo"] = nil
1161
1162         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
1163         if err != nil {
1164                 return out, err
1165         }
1166         defer resp.Body.Close()
1167
1168         err = xmlUnmarshal(resp.Body, &out)
1169         return out, err
1170 }
1171
1172 // DeleteBucketQosInfo API operation for Object Storage Service.
1173 //
1174 // Delete Bucket QoS information.
1175 //
1176 // bucketName the bucket name.
1177 //
1178 // error    it's nil if no error, otherwise it's an error object.
1179 //
1180 func (client Client) DeleteBucketQosInfo(bucketName string, options ...Option) error {
1181         params := map[string]interface{}{}
1182         params["qosInfo"] = nil
1183
1184         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
1185         if err != nil {
1186                 return err
1187         }
1188         defer resp.Body.Close()
1189
1190         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
1191 }
1192
1193 // SetBucketInventory API operation for Object Storage Service
1194 //
1195 // Set the Bucket inventory.
1196 //
1197 // bucketName tht bucket name.
1198 //
1199 // inventoryConfig the inventory configuration.
1200 //
1201 // error    it's nil if no error, otherwise it's an error.
1202 //
1203 func (client Client) SetBucketInventory(bucketName string, inventoryConfig InventoryConfiguration, options ...Option) error {
1204         params := map[string]interface{}{}
1205         params["inventoryId"] = inventoryConfig.Id
1206         params["inventory"] = nil
1207
1208         var bs []byte
1209         bs, err := xml.Marshal(inventoryConfig)
1210
1211         if err != nil {
1212                 return err
1213         }
1214
1215         buffer := new(bytes.Buffer)
1216         buffer.Write(bs)
1217
1218         contentType := http.DetectContentType(buffer.Bytes())
1219         headers := make(map[string]string)
1220         headers[HTTPHeaderContentType] = contentType
1221
1222         resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
1223
1224         if err != nil {
1225                 return err
1226         }
1227
1228         defer resp.Body.Close()
1229
1230         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1231 }
1232
1233 // GetBucketInventory API operation for Object Storage Service
1234 //
1235 // Get the Bucket inventory.
1236 //
1237 // bucketName tht bucket name.
1238 //
1239 // strInventoryId the inventory id.
1240 //
1241 // InventoryConfiguration the inventory configuration.
1242 //
1243 // error    it's nil if no error, otherwise it's an error.
1244 //
1245 func (client Client) GetBucketInventory(bucketName string, strInventoryId string, options ...Option) (InventoryConfiguration, error) {
1246         var out InventoryConfiguration
1247         params := map[string]interface{}{}
1248         params["inventory"] = nil
1249         params["inventoryId"] = strInventoryId
1250
1251         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
1252         if err != nil {
1253                 return out, err
1254         }
1255         defer resp.Body.Close()
1256
1257         err = xmlUnmarshal(resp.Body, &out)
1258         return out, err
1259 }
1260
1261 // ListBucketInventory API operation for Object Storage Service
1262 //
1263 // List the Bucket inventory.
1264 //
1265 // bucketName tht bucket name.
1266 //
1267 // continuationToken the users token.
1268 //
1269 // ListInventoryConfigurationsResult list all inventory configuration by .
1270 //
1271 // error    it's nil if no error, otherwise it's an error.
1272 //
1273 func (client Client) ListBucketInventory(bucketName, continuationToken string, options ...Option) (ListInventoryConfigurationsResult, error) {
1274         var out ListInventoryConfigurationsResult
1275         params := map[string]interface{}{}
1276         params["inventory"] = nil
1277         if continuationToken == "" {
1278                 params["continuation-token"] = nil
1279         } else {
1280                 params["continuation-token"] = continuationToken
1281         }
1282
1283         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
1284         if err != nil {
1285                 return out, err
1286         }
1287         defer resp.Body.Close()
1288
1289         err = xmlUnmarshal(resp.Body, &out)
1290         return out, err
1291 }
1292
1293 // DeleteBucketInventory API operation for Object Storage Service.
1294 //
1295 // Delete Bucket inventory information.
1296 //
1297 // bucketName tht bucket name.
1298 //
1299 // strInventoryId the inventory id.
1300 //
1301 // error    it's nil if no error, otherwise it's an error.
1302 //
1303 func (client Client) DeleteBucketInventory(bucketName, strInventoryId string, options ...Option) error {
1304         params := map[string]interface{}{}
1305         params["inventory"] = nil
1306         params["inventoryId"] = strInventoryId
1307
1308         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
1309         if err != nil {
1310                 return err
1311         }
1312         defer resp.Body.Close()
1313
1314         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
1315 }
1316
1317 // SetBucketAsyncTask API operation for set async fetch task
1318 //
1319 // bucketName tht bucket name.
1320 //
1321 // asynConf  configruation
1322 //
1323 // error  it's nil if success, otherwise it's an error.
1324 func (client Client) SetBucketAsyncTask(bucketName string, asynConf AsyncFetchTaskConfiguration, options ...Option) (AsyncFetchTaskResult, error) {
1325         var out AsyncFetchTaskResult
1326         params := map[string]interface{}{}
1327         params["asyncFetch"] = nil
1328
1329         var bs []byte
1330         bs, err := xml.Marshal(asynConf)
1331
1332         if err != nil {
1333                 return out, err
1334         }
1335
1336         buffer := new(bytes.Buffer)
1337         buffer.Write(bs)
1338
1339         contentType := http.DetectContentType(buffer.Bytes())
1340         headers := make(map[string]string)
1341         headers[HTTPHeaderContentType] = contentType
1342
1343         resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
1344
1345         if err != nil {
1346                 return out, err
1347         }
1348
1349         defer resp.Body.Close()
1350         err = xmlUnmarshal(resp.Body, &out)
1351         return out, err
1352 }
1353
1354 // GetBucketAsyncTask API operation for set async fetch task
1355 //
1356 // bucketName tht bucket name.
1357 //
1358 // taskid  returned by SetBucketAsyncTask
1359 //
1360 // error  it's nil if success, otherwise it's an error.
1361 func (client Client) GetBucketAsyncTask(bucketName string, taskID string, options ...Option) (AsynFetchTaskInfo, error) {
1362         var out AsynFetchTaskInfo
1363         params := map[string]interface{}{}
1364         params["asyncFetch"] = nil
1365
1366         headers := make(map[string]string)
1367         headers[HTTPHeaderOssTaskID] = taskID
1368         resp, err := client.do("GET", bucketName, params, headers, nil, options...)
1369         if err != nil {
1370                 return out, err
1371         }
1372         defer resp.Body.Close()
1373         err = xmlUnmarshal(resp.Body, &out)
1374         return out, err
1375 }
1376
1377 // InitiateBucketWorm creates bucket worm Configuration
1378 // bucketName the bucket name.
1379 // retentionDays the retention period in days
1380 // error    it's nil if no error, otherwise it's an error object.
1381 //
1382 func (client Client) InitiateBucketWorm(bucketName string, retentionDays int, options ...Option) (string, error) {
1383         var initiateWormConf InitiateWormConfiguration
1384         initiateWormConf.RetentionPeriodInDays = retentionDays
1385
1386         var respHeader http.Header
1387         isOptSet, _, _ := IsOptionSet(options, responseHeader)
1388         if !isOptSet {
1389                 options = append(options, GetResponseHeader(&respHeader))
1390         }
1391
1392         bs, err := xml.Marshal(initiateWormConf)
1393         if err != nil {
1394                 return "", err
1395         }
1396         buffer := new(bytes.Buffer)
1397         buffer.Write(bs)
1398
1399         contentType := http.DetectContentType(buffer.Bytes())
1400         headers := make(map[string]string)
1401         headers[HTTPHeaderContentType] = contentType
1402
1403         params := map[string]interface{}{}
1404         params["worm"] = nil
1405
1406         resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
1407         if err != nil {
1408                 return "", err
1409         }
1410         defer resp.Body.Close()
1411
1412         respOpt, _ := FindOption(options, responseHeader, nil)
1413         wormID := ""
1414         err = CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1415         if err == nil && respOpt != nil {
1416                 wormID = (respOpt.(*http.Header)).Get("x-oss-worm-id")
1417         }
1418         return wormID, err
1419 }
1420
1421 // AbortBucketWorm delete bucket worm Configuration
1422 // bucketName the bucket name.
1423 // error    it's nil if no error, otherwise it's an error object.
1424 //
1425 func (client Client) AbortBucketWorm(bucketName string, options ...Option) error {
1426         params := map[string]interface{}{}
1427         params["worm"] = nil
1428         resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
1429         if err != nil {
1430                 return err
1431         }
1432         defer resp.Body.Close()
1433         return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
1434 }
1435
1436 // CompleteBucketWorm complete bucket worm Configuration
1437 // bucketName the bucket name.
1438 // wormID the worm id
1439 // error    it's nil if no error, otherwise it's an error object.
1440 //
1441 func (client Client) CompleteBucketWorm(bucketName string, wormID string, options ...Option) error {
1442         params := map[string]interface{}{}
1443         params["wormId"] = wormID
1444         resp, err := client.do("POST", bucketName, params, nil, nil, options...)
1445         if err != nil {
1446                 return err
1447         }
1448         defer resp.Body.Close()
1449         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1450 }
1451
1452 // ExtendBucketWorm exetend bucket worm Configuration
1453 // bucketName the bucket name.
1454 // retentionDays the retention period in days
1455 // wormID the worm id
1456 // error    it's nil if no error, otherwise it's an error object.
1457 //
1458 func (client Client) ExtendBucketWorm(bucketName string, retentionDays int, wormID string, options ...Option) error {
1459         var extendWormConf ExtendWormConfiguration
1460         extendWormConf.RetentionPeriodInDays = retentionDays
1461
1462         bs, err := xml.Marshal(extendWormConf)
1463         if err != nil {
1464                 return err
1465         }
1466         buffer := new(bytes.Buffer)
1467         buffer.Write(bs)
1468
1469         contentType := http.DetectContentType(buffer.Bytes())
1470         headers := make(map[string]string)
1471         headers[HTTPHeaderContentType] = contentType
1472
1473         params := map[string]interface{}{}
1474         params["wormId"] = wormID
1475         params["wormExtend"] = nil
1476
1477         resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
1478         if err != nil {
1479                 return err
1480         }
1481         defer resp.Body.Close()
1482         return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
1483 }
1484
1485 // GetBucketWorm get bucket worm Configuration
1486 // bucketName the bucket name.
1487 // error    it's nil if no error, otherwise it's an error object.
1488 //
1489 func (client Client) GetBucketWorm(bucketName string, options ...Option) (WormConfiguration, error) {
1490         var out WormConfiguration
1491         params := map[string]interface{}{}
1492         params["worm"] = nil
1493
1494         resp, err := client.do("GET", bucketName, params, nil, nil, options...)
1495         if err != nil {
1496                 return out, err
1497         }
1498         defer resp.Body.Close()
1499         err = xmlUnmarshal(resp.Body, &out)
1500         return out, err
1501 }
1502
1503 // LimitUploadSpeed set upload bandwidth limit speed,default is 0,unlimited
1504 // upSpeed KB/s, 0 is unlimited,default is 0
1505 // error it's nil if success, otherwise failure
1506 func (client Client) LimitUploadSpeed(upSpeed int) error {
1507         if client.Config == nil {
1508                 return fmt.Errorf("client config is nil")
1509         }
1510         return client.Config.LimitUploadSpeed(upSpeed)
1511 }
1512
1513 // UseCname sets the flag of using CName. By default it's false.
1514 //
1515 // isUseCname    true: the endpoint has the CName, false: the endpoint does not have cname. Default is false.
1516 //
1517 func UseCname(isUseCname bool) ClientOption {
1518         return func(client *Client) {
1519                 client.Config.IsCname = isUseCname
1520                 client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
1521         }
1522 }
1523
1524 // Timeout sets the HTTP timeout in seconds.
1525 //
1526 // connectTimeoutSec    HTTP timeout in seconds. Default is 10 seconds. 0 means infinite (not recommended)
1527 // readWriteTimeout    HTTP read or write's timeout in seconds. Default is 20 seconds. 0 means infinite.
1528 //
1529 func Timeout(connectTimeoutSec, readWriteTimeout int64) ClientOption {
1530         return func(client *Client) {
1531                 client.Config.HTTPTimeout.ConnectTimeout =
1532                         time.Second * time.Duration(connectTimeoutSec)
1533                 client.Config.HTTPTimeout.ReadWriteTimeout =
1534                         time.Second * time.Duration(readWriteTimeout)
1535                 client.Config.HTTPTimeout.HeaderTimeout =
1536                         time.Second * time.Duration(readWriteTimeout)
1537                 client.Config.HTTPTimeout.IdleConnTimeout =
1538                         time.Second * time.Duration(readWriteTimeout)
1539                 client.Config.HTTPTimeout.LongTimeout =
1540                         time.Second * time.Duration(readWriteTimeout*10)
1541         }
1542 }
1543
1544 // SecurityToken sets the temporary user's SecurityToken.
1545 //
1546 // token    STS token
1547 //
1548 func SecurityToken(token string) ClientOption {
1549         return func(client *Client) {
1550                 client.Config.SecurityToken = strings.TrimSpace(token)
1551         }
1552 }
1553
1554 // EnableMD5 enables MD5 validation.
1555 //
1556 // isEnableMD5    true: enable MD5 validation; false: disable MD5 validation.
1557 //
1558 func EnableMD5(isEnableMD5 bool) ClientOption {
1559         return func(client *Client) {
1560                 client.Config.IsEnableMD5 = isEnableMD5
1561         }
1562 }
1563
1564 // MD5ThresholdCalcInMemory sets the memory usage threshold for computing the MD5, default is 16MB.
1565 //
1566 // threshold    the memory threshold in bytes. When the uploaded content is more than 16MB, the temp file is used for computing the MD5.
1567 //
1568 func MD5ThresholdCalcInMemory(threshold int64) ClientOption {
1569         return func(client *Client) {
1570                 client.Config.MD5Threshold = threshold
1571         }
1572 }
1573
1574 // EnableCRC enables the CRC checksum. Default is true.
1575 //
1576 // isEnableCRC    true: enable CRC checksum; false: disable the CRC checksum.
1577 //
1578 func EnableCRC(isEnableCRC bool) ClientOption {
1579         return func(client *Client) {
1580                 client.Config.IsEnableCRC = isEnableCRC
1581         }
1582 }
1583
1584 // UserAgent specifies UserAgent. The default is aliyun-sdk-go/1.2.0 (windows/-/amd64;go1.5.2).
1585 //
1586 // userAgent    the user agent string.
1587 //
1588 func UserAgent(userAgent string) ClientOption {
1589         return func(client *Client) {
1590                 client.Config.UserAgent = userAgent
1591                 client.Config.UserSetUa = true
1592         }
1593 }
1594
1595 // Proxy sets the proxy (optional). The default is not using proxy.
1596 //
1597 // proxyHost    the proxy host in the format "host:port". For example, proxy.com:80 .
1598 //
1599 func Proxy(proxyHost string) ClientOption {
1600         return func(client *Client) {
1601                 client.Config.IsUseProxy = true
1602                 client.Config.ProxyHost = proxyHost
1603                 client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
1604         }
1605 }
1606
1607 // AuthProxy sets the proxy information with user name and password.
1608 //
1609 // proxyHost    the proxy host in the format "host:port". For example, proxy.com:80 .
1610 // proxyUser    the proxy user name.
1611 // proxyPassword    the proxy password.
1612 //
1613 func AuthProxy(proxyHost, proxyUser, proxyPassword string) ClientOption {
1614         return func(client *Client) {
1615                 client.Config.IsUseProxy = true
1616                 client.Config.ProxyHost = proxyHost
1617                 client.Config.IsAuthProxy = true
1618                 client.Config.ProxyUser = proxyUser
1619                 client.Config.ProxyPassword = proxyPassword
1620                 client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
1621         }
1622 }
1623
1624 //
1625 // HTTPClient sets the http.Client in use to the one passed in
1626 //
1627 func HTTPClient(HTTPClient *http.Client) ClientOption {
1628         return func(client *Client) {
1629                 client.HTTPClient = HTTPClient
1630         }
1631 }
1632
1633 //
1634 // SetLogLevel sets the oss sdk log level
1635 //
1636 func SetLogLevel(LogLevel int) ClientOption {
1637         return func(client *Client) {
1638                 client.Config.LogLevel = LogLevel
1639         }
1640 }
1641
1642 //
1643 // SetLogger sets the oss sdk logger
1644 //
1645 func SetLogger(Logger *log.Logger) ClientOption {
1646         return func(client *Client) {
1647                 client.Config.Logger = Logger
1648         }
1649 }
1650
1651 // SetCredentialsProvider sets funciton for get the user's ak
1652 func SetCredentialsProvider(provider CredentialsProvider) ClientOption {
1653         return func(client *Client) {
1654                 client.Config.CredentialsProvider = provider
1655         }
1656 }
1657
1658 // SetLocalAddr sets funciton for local addr
1659 func SetLocalAddr(localAddr net.Addr) ClientOption {
1660         return func(client *Client) {
1661                 client.Config.LocalAddr = localAddr
1662         }
1663 }
1664
1665 // AuthVersion  sets auth version: v1 or v2 signature which oss_server needed
1666 func AuthVersion(authVersion AuthVersionType) ClientOption {
1667         return func(client *Client) {
1668                 client.Config.AuthVersion = authVersion
1669         }
1670 }
1671
1672 // AdditionalHeaders sets special http headers needed to be signed
1673 func AdditionalHeaders(headers []string) ClientOption {
1674         return func(client *Client) {
1675                 client.Config.AdditionalHeaders = headers
1676         }
1677 }
1678
1679 // only effective from go1.7 onward,RedirectEnabled set http redirect enabled or not
1680 func RedirectEnabled(enabled bool) ClientOption {
1681         return func(client *Client) {
1682                 client.Config.RedirectEnabled = enabled
1683         }
1684 }
1685
1686 // Private
1687 func (client Client) do(method, bucketName string, params map[string]interface{},
1688         headers map[string]string, data io.Reader, options ...Option) (*Response, error) {
1689         err := CheckBucketName(bucketName)
1690         if len(bucketName) > 0 && err != nil {
1691                 return nil, err
1692         }
1693
1694         // option headers
1695         addHeaders := make(map[string]string)
1696         err = handleOptions(addHeaders, options)
1697         if err != nil {
1698                 return nil, err
1699         }
1700
1701         // merge header
1702         if headers == nil {
1703                 headers = make(map[string]string)
1704         }
1705
1706         for k, v := range addHeaders {
1707                 if _, ok := headers[k]; !ok {
1708                         headers[k] = v
1709                 }
1710         }
1711
1712         resp, err := client.Conn.Do(method, bucketName, "", params, headers, data, 0, nil)
1713
1714         // get response header
1715         respHeader, _ := FindOption(options, responseHeader, nil)
1716         if respHeader != nil {
1717                 pRespHeader := respHeader.(*http.Header)
1718                 *pRespHeader = resp.Headers
1719         }
1720
1721         return resp, err
1722 }