client.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. // Package oss implements functions for access oss service.
  2. // It has two main struct Client and Bucket.
  3. package oss
  4. import (
  5. "bytes"
  6. "encoding/xml"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "log"
  11. "net/http"
  12. "strings"
  13. "time"
  14. )
  15. // 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).
  16. // Object related operations are done by Bucket class.
  17. // Users use oss.New to create Client instance.
  18. //
  19. type (
  20. // Client OSS client
  21. Client struct {
  22. Config *Config // OSS client configuration
  23. Conn *Conn // Send HTTP request
  24. HTTPClient *http.Client //http.Client to use - if nil will make its own
  25. }
  26. // ClientOption client option such as UseCname, Timeout, SecurityToken.
  27. ClientOption func(*Client)
  28. )
  29. // New creates a new client.
  30. //
  31. // endpoint the OSS datacenter endpoint such as http://oss-cn-hangzhou.aliyuncs.com .
  32. // accessKeyId access key Id.
  33. // accessKeySecret access key secret.
  34. //
  35. // Client creates the new client instance, the returned value is valid when error is nil.
  36. // error it's nil if no error, otherwise it's an error object.
  37. //
  38. func New(endpoint, accessKeyID, accessKeySecret string, options ...ClientOption) (*Client, error) {
  39. // Configuration
  40. config := getDefaultOssConfig()
  41. config.Endpoint = endpoint
  42. config.AccessKeyID = accessKeyID
  43. config.AccessKeySecret = accessKeySecret
  44. defAkBuild := &defaultCredentialInfBuild{config: config}
  45. config.UserAKBuild = defAkBuild
  46. // URL parse
  47. url := &urlMaker{}
  48. url.Init(config.Endpoint, config.IsCname, config.IsUseProxy)
  49. // HTTP connect
  50. conn := &Conn{config: config, url: url}
  51. // OSS client
  52. client := &Client{
  53. Config: config,
  54. Conn: conn,
  55. }
  56. // Client options parse
  57. for _, option := range options {
  58. option(client)
  59. }
  60. // Create HTTP connection
  61. err := conn.init(config, url, client.HTTPClient)
  62. return client, err
  63. }
  64. // Bucket gets the bucket instance.
  65. //
  66. // bucketName the bucket name.
  67. // Bucket the bucket object, when error is nil.
  68. //
  69. // error it's nil if no error, otherwise it's an error object.
  70. //
  71. func (client Client) Bucket(bucketName string) (*Bucket, error) {
  72. return &Bucket{
  73. client,
  74. bucketName,
  75. }, nil
  76. }
  77. // CreateBucket creates a bucket.
  78. //
  79. // bucketName the bucket name, it's globably unique and immutable. The bucket name can only consist of lowercase letters, numbers and dash ('-').
  80. // It must start with lowercase letter or number and the length can only be between 3 and 255.
  81. // options options for creating the bucket, with optional ACL. The ACL could be ACLPrivate, ACLPublicRead, and ACLPublicReadWrite. By default it's ACLPrivate.
  82. // It could also be specified with StorageClass option, which supports StorageStandard, StorageIA(infrequent access), StorageArchive.
  83. //
  84. // error it's nil if no error, otherwise it's an error object.
  85. //
  86. func (client Client) CreateBucket(bucketName string, options ...Option) error {
  87. headers := make(map[string]string)
  88. handleOptions(headers, options)
  89. buffer := new(bytes.Buffer)
  90. isOptSet, val, _ := isOptionSet(options, storageClass)
  91. if isOptSet {
  92. cbConfig := createBucketConfiguration{StorageClass: val.(StorageClassType)}
  93. bs, err := xml.Marshal(cbConfig)
  94. if err != nil {
  95. return err
  96. }
  97. buffer.Write(bs)
  98. contentType := http.DetectContentType(buffer.Bytes())
  99. headers[HTTPHeaderContentType] = contentType
  100. }
  101. params := map[string]interface{}{}
  102. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  103. if err != nil {
  104. return err
  105. }
  106. defer resp.Body.Close()
  107. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  108. }
  109. // ListBuckets lists buckets of the current account under the given endpoint, with optional filters.
  110. //
  111. // options specifies the filters such as Prefix, Marker and MaxKeys. Prefix is the bucket name's prefix filter.
  112. // And marker makes sure the returned buckets' name are greater than it in lexicographic order.
  113. // Maxkeys limits the max keys to return, and by default it's 100 and up to 1000.
  114. // For the common usage scenario, please check out list_bucket.go in the sample.
  115. // ListBucketsResponse the response object if error is nil.
  116. //
  117. // error it's nil if no error, otherwise it's an error object.
  118. //
  119. func (client Client) ListBuckets(options ...Option) (ListBucketsResult, error) {
  120. var out ListBucketsResult
  121. params, err := getRawParams(options)
  122. if err != nil {
  123. return out, err
  124. }
  125. resp, err := client.do("GET", "", params, nil, nil, options...)
  126. if err != nil {
  127. return out, err
  128. }
  129. defer resp.Body.Close()
  130. err = xmlUnmarshal(resp.Body, &out)
  131. return out, err
  132. }
  133. // IsBucketExist checks if the bucket exists
  134. //
  135. // bucketName the bucket name.
  136. //
  137. // bool true if it exists, and it's only valid when error is nil.
  138. // error it's nil if no error, otherwise it's an error object.
  139. //
  140. func (client Client) IsBucketExist(bucketName string) (bool, error) {
  141. listRes, err := client.ListBuckets(Prefix(bucketName), MaxKeys(1))
  142. if err != nil {
  143. return false, err
  144. }
  145. if len(listRes.Buckets) == 1 && listRes.Buckets[0].Name == bucketName {
  146. return true, nil
  147. }
  148. return false, nil
  149. }
  150. // DeleteBucket deletes the bucket. Only empty bucket can be deleted (no object and parts).
  151. //
  152. // bucketName the bucket name.
  153. //
  154. // error it's nil if no error, otherwise it's an error object.
  155. //
  156. func (client Client) DeleteBucket(bucketName string) error {
  157. params := map[string]interface{}{}
  158. resp, err := client.do("DELETE", bucketName, params, nil, nil)
  159. if err != nil {
  160. return err
  161. }
  162. defer resp.Body.Close()
  163. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  164. }
  165. // GetBucketLocation gets the bucket location.
  166. //
  167. // Checks out the following link for more information :
  168. // https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html
  169. //
  170. // bucketName the bucket name
  171. //
  172. // string bucket's datacenter location
  173. // error it's nil if no error, otherwise it's an error object.
  174. //
  175. func (client Client) GetBucketLocation(bucketName string) (string, error) {
  176. params := map[string]interface{}{}
  177. params["location"] = nil
  178. resp, err := client.do("GET", bucketName, params, nil, nil)
  179. if err != nil {
  180. return "", err
  181. }
  182. defer resp.Body.Close()
  183. var LocationConstraint string
  184. err = xmlUnmarshal(resp.Body, &LocationConstraint)
  185. return LocationConstraint, err
  186. }
  187. // SetBucketACL sets bucket's ACL.
  188. //
  189. // bucketName the bucket name
  190. // bucketAcl the bucket ACL: ACLPrivate, ACLPublicRead and ACLPublicReadWrite.
  191. //
  192. // error it's nil if no error, otherwise it's an error object.
  193. //
  194. func (client Client) SetBucketACL(bucketName string, bucketACL ACLType) error {
  195. headers := map[string]string{HTTPHeaderOssACL: string(bucketACL)}
  196. params := map[string]interface{}{}
  197. params["acl"] = nil
  198. resp, err := client.do("PUT", bucketName, params, headers, nil)
  199. if err != nil {
  200. return err
  201. }
  202. defer resp.Body.Close()
  203. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  204. }
  205. // GetBucketACL gets the bucket ACL.
  206. //
  207. // bucketName the bucket name.
  208. //
  209. // GetBucketAclResponse the result object, and it's only valid when error is nil.
  210. // error it's nil if no error, otherwise it's an error object.
  211. //
  212. func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error) {
  213. var out GetBucketACLResult
  214. params := map[string]interface{}{}
  215. params["acl"] = nil
  216. resp, err := client.do("GET", bucketName, params, nil, nil)
  217. if err != nil {
  218. return out, err
  219. }
  220. defer resp.Body.Close()
  221. err = xmlUnmarshal(resp.Body, &out)
  222. return out, err
  223. }
  224. // SetBucketLifecycle sets the bucket's lifecycle.
  225. //
  226. // For more information, checks out following link:
  227. // https://help.aliyun.com/document_detail/oss/user_guide/manage_object/object_lifecycle.html
  228. //
  229. // bucketName the bucket name.
  230. // rules the lifecycle rules. There're two kind of rules: absolute time expiration and relative time expiration in days and day/month/year respectively.
  231. // Check out sample/bucket_lifecycle.go for more details.
  232. //
  233. // error it's nil if no error, otherwise it's an error object.
  234. //
  235. func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule) error {
  236. err := verifyLifecycleRules(rules)
  237. if err != nil {
  238. return err
  239. }
  240. lifecycleCfg := LifecycleConfiguration{Rules: rules}
  241. bs, err := xml.Marshal(lifecycleCfg)
  242. if err != nil {
  243. return err
  244. }
  245. buffer := new(bytes.Buffer)
  246. buffer.Write(bs)
  247. contentType := http.DetectContentType(buffer.Bytes())
  248. headers := map[string]string{}
  249. headers[HTTPHeaderContentType] = contentType
  250. params := map[string]interface{}{}
  251. params["lifecycle"] = nil
  252. resp, err := client.do("PUT", bucketName, params, headers, buffer)
  253. if err != nil {
  254. return err
  255. }
  256. defer resp.Body.Close()
  257. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  258. }
  259. // DeleteBucketLifecycle deletes the bucket's lifecycle.
  260. //
  261. //
  262. // bucketName the bucket name.
  263. //
  264. // error it's nil if no error, otherwise it's an error object.
  265. //
  266. func (client Client) DeleteBucketLifecycle(bucketName string) error {
  267. params := map[string]interface{}{}
  268. params["lifecycle"] = nil
  269. resp, err := client.do("DELETE", bucketName, params, nil, nil)
  270. if err != nil {
  271. return err
  272. }
  273. defer resp.Body.Close()
  274. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  275. }
  276. // GetBucketLifecycle gets the bucket's lifecycle settings.
  277. //
  278. // bucketName the bucket name.
  279. //
  280. // GetBucketLifecycleResponse the result object upon successful request. It's only valid when error is nil.
  281. // error it's nil if no error, otherwise it's an error object.
  282. //
  283. func (client Client) GetBucketLifecycle(bucketName string) (GetBucketLifecycleResult, error) {
  284. var out GetBucketLifecycleResult
  285. params := map[string]interface{}{}
  286. params["lifecycle"] = nil
  287. resp, err := client.do("GET", bucketName, params, nil, nil)
  288. if err != nil {
  289. return out, err
  290. }
  291. defer resp.Body.Close()
  292. err = xmlUnmarshal(resp.Body, &out)
  293. return out, err
  294. }
  295. // SetBucketReferer sets the bucket's referer whitelist and the flag if allowing empty referrer.
  296. //
  297. // 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
  298. // the allowing empty referrer flag. Note that this applies to requests from webbrowser only.
  299. // For example, for a bucket os-example and its referrer http://www.aliyun.com, all requests from this URL could access the bucket.
  300. // For more information, please check out this link :
  301. // https://help.aliyun.com/document_detail/oss/user_guide/security_management/referer.html
  302. //
  303. // bucketName the bucket name.
  304. // referers the referrer white list. A bucket could have a referrer list and each referrer supports one '*' and multiple '?' as wildcards.
  305. // The sample could be found in sample/bucket_referer.go
  306. // allowEmptyReferer the flag of allowing empty referrer. By default it's true.
  307. //
  308. // error it's nil if no error, otherwise it's an error object.
  309. //
  310. func (client Client) SetBucketReferer(bucketName string, referers []string, allowEmptyReferer bool) error {
  311. rxml := RefererXML{}
  312. rxml.AllowEmptyReferer = allowEmptyReferer
  313. if referers == nil {
  314. rxml.RefererList = append(rxml.RefererList, "")
  315. } else {
  316. for _, referer := range referers {
  317. rxml.RefererList = append(rxml.RefererList, referer)
  318. }
  319. }
  320. bs, err := xml.Marshal(rxml)
  321. if err != nil {
  322. return err
  323. }
  324. buffer := new(bytes.Buffer)
  325. buffer.Write(bs)
  326. contentType := http.DetectContentType(buffer.Bytes())
  327. headers := map[string]string{}
  328. headers[HTTPHeaderContentType] = contentType
  329. params := map[string]interface{}{}
  330. params["referer"] = nil
  331. resp, err := client.do("PUT", bucketName, params, headers, buffer)
  332. if err != nil {
  333. return err
  334. }
  335. defer resp.Body.Close()
  336. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  337. }
  338. // GetBucketReferer gets the bucket's referrer white list.
  339. //
  340. // bucketName the bucket name.
  341. //
  342. // GetBucketRefererResponse the result object upon successful request. It's only valid when error is nil.
  343. // error it's nil if no error, otherwise it's an error object.
  344. //
  345. func (client Client) GetBucketReferer(bucketName string) (GetBucketRefererResult, error) {
  346. var out GetBucketRefererResult
  347. params := map[string]interface{}{}
  348. params["referer"] = nil
  349. resp, err := client.do("GET", bucketName, params, nil, nil)
  350. if err != nil {
  351. return out, err
  352. }
  353. defer resp.Body.Close()
  354. err = xmlUnmarshal(resp.Body, &out)
  355. return out, err
  356. }
  357. // SetBucketLogging sets the bucket logging settings.
  358. //
  359. // OSS could automatically store the access log. Only the bucket owner could enable the logging.
  360. // Once enabled, OSS would save all the access log into hourly log files in a specified bucket.
  361. // For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/logging.html
  362. //
  363. // bucketName bucket name to enable the log.
  364. // targetBucket the target bucket name to store the log files.
  365. // targetPrefix the log files' prefix.
  366. //
  367. // error it's nil if no error, otherwise it's an error object.
  368. //
  369. func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix string,
  370. isEnable bool) error {
  371. var err error
  372. var bs []byte
  373. if isEnable {
  374. lxml := LoggingXML{}
  375. lxml.LoggingEnabled.TargetBucket = targetBucket
  376. lxml.LoggingEnabled.TargetPrefix = targetPrefix
  377. bs, err = xml.Marshal(lxml)
  378. } else {
  379. lxml := loggingXMLEmpty{}
  380. bs, err = xml.Marshal(lxml)
  381. }
  382. if err != nil {
  383. return err
  384. }
  385. buffer := new(bytes.Buffer)
  386. buffer.Write(bs)
  387. contentType := http.DetectContentType(buffer.Bytes())
  388. headers := map[string]string{}
  389. headers[HTTPHeaderContentType] = contentType
  390. params := map[string]interface{}{}
  391. params["logging"] = nil
  392. resp, err := client.do("PUT", bucketName, params, headers, buffer)
  393. if err != nil {
  394. return err
  395. }
  396. defer resp.Body.Close()
  397. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  398. }
  399. // DeleteBucketLogging deletes the logging configuration to disable the logging on the bucket.
  400. //
  401. // bucketName the bucket name to disable the logging.
  402. //
  403. // error it's nil if no error, otherwise it's an error object.
  404. //
  405. func (client Client) DeleteBucketLogging(bucketName string) error {
  406. params := map[string]interface{}{}
  407. params["logging"] = nil
  408. resp, err := client.do("DELETE", bucketName, params, nil, nil)
  409. if err != nil {
  410. return err
  411. }
  412. defer resp.Body.Close()
  413. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  414. }
  415. // GetBucketLogging gets the bucket's logging settings
  416. //
  417. // bucketName the bucket name
  418. // GetBucketLoggingResponse the result object upon successful request. It's only valid when error is nil.
  419. //
  420. // error it's nil if no error, otherwise it's an error object.
  421. //
  422. func (client Client) GetBucketLogging(bucketName string) (GetBucketLoggingResult, error) {
  423. var out GetBucketLoggingResult
  424. params := map[string]interface{}{}
  425. params["logging"] = nil
  426. resp, err := client.do("GET", bucketName, params, nil, nil)
  427. if err != nil {
  428. return out, err
  429. }
  430. defer resp.Body.Close()
  431. err = xmlUnmarshal(resp.Body, &out)
  432. return out, err
  433. }
  434. // SetBucketWebsite sets the bucket's static website's index and error page.
  435. //
  436. // 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.
  437. // For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
  438. //
  439. // bucketName the bucket name to enable static web site.
  440. // indexDocument index page.
  441. // errorDocument error page.
  442. //
  443. // error it's nil if no error, otherwise it's an error object.
  444. //
  445. func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument string) error {
  446. wxml := WebsiteXML{}
  447. wxml.IndexDocument.Suffix = indexDocument
  448. wxml.ErrorDocument.Key = errorDocument
  449. bs, err := xml.Marshal(wxml)
  450. if err != nil {
  451. return err
  452. }
  453. buffer := new(bytes.Buffer)
  454. buffer.Write(bs)
  455. contentType := http.DetectContentType(buffer.Bytes())
  456. headers := make(map[string]string)
  457. headers[HTTPHeaderContentType] = contentType
  458. params := map[string]interface{}{}
  459. params["website"] = nil
  460. resp, err := client.do("PUT", bucketName, params, headers, buffer)
  461. if err != nil {
  462. return err
  463. }
  464. defer resp.Body.Close()
  465. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  466. }
  467. // SetBucketWebsiteDetail sets the bucket's static website's detail
  468. //
  469. // 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.
  470. // For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
  471. //
  472. // bucketName the bucket name to enable static web site.
  473. //
  474. // wxml the website's detail
  475. //
  476. // error it's nil if no error, otherwise it's an error object.
  477. //
  478. func (client Client) SetBucketWebsiteDetail(bucketName string, wxml WebsiteXML, options ...Option) error {
  479. bs, err := xml.Marshal(wxml)
  480. if err != nil {
  481. return err
  482. }
  483. buffer := new(bytes.Buffer)
  484. buffer.Write(bs)
  485. contentType := http.DetectContentType(buffer.Bytes())
  486. headers := make(map[string]string)
  487. headers[HTTPHeaderContentType] = contentType
  488. params := map[string]interface{}{}
  489. params["website"] = nil
  490. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  491. if err != nil {
  492. return err
  493. }
  494. defer resp.Body.Close()
  495. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  496. }
  497. // DeleteBucketWebsite deletes the bucket's static web site settings.
  498. //
  499. // bucketName the bucket name.
  500. //
  501. // error it's nil if no error, otherwise it's an error object.
  502. //
  503. func (client Client) DeleteBucketWebsite(bucketName string) error {
  504. params := map[string]interface{}{}
  505. params["website"] = nil
  506. resp, err := client.do("DELETE", bucketName, params, nil, nil)
  507. if err != nil {
  508. return err
  509. }
  510. defer resp.Body.Close()
  511. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  512. }
  513. // GetBucketWebsite gets the bucket's default page (index page) and the error page.
  514. //
  515. // bucketName the bucket name
  516. //
  517. // GetBucketWebsiteResponse the result object upon successful request. It's only valid when error is nil.
  518. // error it's nil if no error, otherwise it's an error object.
  519. //
  520. func (client Client) GetBucketWebsite(bucketName string) (GetBucketWebsiteResult, error) {
  521. var out GetBucketWebsiteResult
  522. params := map[string]interface{}{}
  523. params["website"] = nil
  524. resp, err := client.do("GET", bucketName, params, nil, nil)
  525. if err != nil {
  526. return out, err
  527. }
  528. defer resp.Body.Close()
  529. err = xmlUnmarshal(resp.Body, &out)
  530. return out, err
  531. }
  532. // SetBucketCORS sets the bucket's CORS rules
  533. //
  534. // For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/cors.html
  535. //
  536. // bucketName the bucket name
  537. // corsRules the CORS rules to set. The related sample code is in sample/bucket_cors.go.
  538. //
  539. // error it's nil if no error, otherwise it's an error object.
  540. //
  541. func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) error {
  542. corsxml := CORSXML{}
  543. for _, v := range corsRules {
  544. cr := CORSRule{}
  545. cr.AllowedMethod = v.AllowedMethod
  546. cr.AllowedOrigin = v.AllowedOrigin
  547. cr.AllowedHeader = v.AllowedHeader
  548. cr.ExposeHeader = v.ExposeHeader
  549. cr.MaxAgeSeconds = v.MaxAgeSeconds
  550. corsxml.CORSRules = append(corsxml.CORSRules, cr)
  551. }
  552. bs, err := xml.Marshal(corsxml)
  553. if err != nil {
  554. return err
  555. }
  556. buffer := new(bytes.Buffer)
  557. buffer.Write(bs)
  558. contentType := http.DetectContentType(buffer.Bytes())
  559. headers := map[string]string{}
  560. headers[HTTPHeaderContentType] = contentType
  561. params := map[string]interface{}{}
  562. params["cors"] = nil
  563. resp, err := client.do("PUT", bucketName, params, headers, buffer)
  564. if err != nil {
  565. return err
  566. }
  567. defer resp.Body.Close()
  568. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  569. }
  570. // DeleteBucketCORS deletes the bucket's static website settings.
  571. //
  572. // bucketName the bucket name.
  573. //
  574. // error it's nil if no error, otherwise it's an error object.
  575. //
  576. func (client Client) DeleteBucketCORS(bucketName string) error {
  577. params := map[string]interface{}{}
  578. params["cors"] = nil
  579. resp, err := client.do("DELETE", bucketName, params, nil, nil)
  580. if err != nil {
  581. return err
  582. }
  583. defer resp.Body.Close()
  584. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  585. }
  586. // GetBucketCORS gets the bucket's CORS settings.
  587. //
  588. // bucketName the bucket name.
  589. // GetBucketCORSResult the result object upon successful request. It's only valid when error is nil.
  590. //
  591. // error it's nil if no error, otherwise it's an error object.
  592. //
  593. func (client Client) GetBucketCORS(bucketName string) (GetBucketCORSResult, error) {
  594. var out GetBucketCORSResult
  595. params := map[string]interface{}{}
  596. params["cors"] = nil
  597. resp, err := client.do("GET", bucketName, params, nil, nil)
  598. if err != nil {
  599. return out, err
  600. }
  601. defer resp.Body.Close()
  602. err = xmlUnmarshal(resp.Body, &out)
  603. return out, err
  604. }
  605. // GetBucketInfo gets the bucket information.
  606. //
  607. // bucketName the bucket name.
  608. // GetBucketInfoResult the result object upon successful request. It's only valid when error is nil.
  609. //
  610. // error it's nil if no error, otherwise it's an error object.
  611. //
  612. func (client Client) GetBucketInfo(bucketName string) (GetBucketInfoResult, error) {
  613. var out GetBucketInfoResult
  614. params := map[string]interface{}{}
  615. params["bucketInfo"] = nil
  616. resp, err := client.do("GET", bucketName, params, nil, nil)
  617. if err != nil {
  618. return out, err
  619. }
  620. defer resp.Body.Close()
  621. err = xmlUnmarshal(resp.Body, &out)
  622. // convert None to ""
  623. if err == nil {
  624. if out.BucketInfo.SseRule.KMSMasterKeyID == "None" {
  625. out.BucketInfo.SseRule.KMSMasterKeyID = ""
  626. }
  627. if out.BucketInfo.SseRule.SSEAlgorithm == "None" {
  628. out.BucketInfo.SseRule.SSEAlgorithm = ""
  629. }
  630. }
  631. return out, err
  632. }
  633. // SetBucketVersioning set bucket versioning:Enabled、Suspended
  634. // bucketName the bucket name.
  635. // error it's nil if no error, otherwise it's an error object.
  636. func (client Client) SetBucketVersioning(bucketName string, versioningConfig VersioningConfig, options ...Option) error {
  637. var err error
  638. var bs []byte
  639. bs, err = xml.Marshal(versioningConfig)
  640. if err != nil {
  641. return err
  642. }
  643. buffer := new(bytes.Buffer)
  644. buffer.Write(bs)
  645. contentType := http.DetectContentType(buffer.Bytes())
  646. headers := map[string]string{}
  647. headers[HTTPHeaderContentType] = contentType
  648. params := map[string]interface{}{}
  649. params["versioning"] = nil
  650. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  651. if err != nil {
  652. return err
  653. }
  654. defer resp.Body.Close()
  655. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  656. }
  657. // GetBucketVersioning get bucket versioning status:Enabled、Suspended
  658. // bucketName the bucket name.
  659. // error it's nil if no error, otherwise it's an error object.
  660. func (client Client) GetBucketVersioning(bucketName string, options ...Option) (GetBucketVersioningResult, error) {
  661. var out GetBucketVersioningResult
  662. params := map[string]interface{}{}
  663. params["versioning"] = nil
  664. resp, err := client.do("GET", bucketName, params, nil, nil, options...)
  665. if err != nil {
  666. return out, err
  667. }
  668. defer resp.Body.Close()
  669. err = xmlUnmarshal(resp.Body, &out)
  670. return out, err
  671. }
  672. // SetBucketEncryption set bucket encryption config
  673. // bucketName the bucket name.
  674. // error it's nil if no error, otherwise it's an error object.
  675. func (client Client) SetBucketEncryption(bucketName string, encryptionRule ServerEncryptionRule, options ...Option) error {
  676. var err error
  677. var bs []byte
  678. bs, err = xml.Marshal(encryptionRule)
  679. if err != nil {
  680. return err
  681. }
  682. buffer := new(bytes.Buffer)
  683. buffer.Write(bs)
  684. contentType := http.DetectContentType(buffer.Bytes())
  685. headers := map[string]string{}
  686. headers[HTTPHeaderContentType] = contentType
  687. params := map[string]interface{}{}
  688. params["encryption"] = nil
  689. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  690. if err != nil {
  691. return err
  692. }
  693. defer resp.Body.Close()
  694. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  695. }
  696. // GetBucketEncryption get bucket encryption
  697. // bucketName the bucket name.
  698. // error it's nil if no error, otherwise it's an error object.
  699. func (client Client) GetBucketEncryption(bucketName string, options ...Option) (GetBucketEncryptionResult, error) {
  700. var out GetBucketEncryptionResult
  701. params := map[string]interface{}{}
  702. params["encryption"] = nil
  703. resp, err := client.do("GET", bucketName, params, nil, nil, options...)
  704. if err != nil {
  705. return out, err
  706. }
  707. defer resp.Body.Close()
  708. err = xmlUnmarshal(resp.Body, &out)
  709. return out, err
  710. }
  711. // DeleteBucketEncryption delete bucket encryption config
  712. // bucketName the bucket name.
  713. // error it's nil if no error, otherwise it's an error bucket
  714. func (client Client) DeleteBucketEncryption(bucketName string, options ...Option) error {
  715. params := map[string]interface{}{}
  716. params["encryption"] = nil
  717. resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
  718. if err != nil {
  719. return err
  720. }
  721. defer resp.Body.Close()
  722. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  723. }
  724. //
  725. // SetBucketTagging add tagging to bucket
  726. // bucketName name of bucket
  727. // tagging tagging to be added
  728. // error nil if success, otherwise error
  729. func (client Client) SetBucketTagging(bucketName string, tagging Tagging, options ...Option) error {
  730. var err error
  731. var bs []byte
  732. bs, err = xml.Marshal(tagging)
  733. if err != nil {
  734. return err
  735. }
  736. buffer := new(bytes.Buffer)
  737. buffer.Write(bs)
  738. contentType := http.DetectContentType(buffer.Bytes())
  739. headers := map[string]string{}
  740. headers[HTTPHeaderContentType] = contentType
  741. params := map[string]interface{}{}
  742. params["tagging"] = nil
  743. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  744. if err != nil {
  745. return err
  746. }
  747. defer resp.Body.Close()
  748. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  749. }
  750. // GetBucketTagging get tagging of the bucket
  751. // bucketName name of bucket
  752. // error nil if success, otherwise error
  753. func (client Client) GetBucketTagging(bucketName string, options ...Option) (GetBucketTaggingResult, error) {
  754. var out GetBucketTaggingResult
  755. params := map[string]interface{}{}
  756. params["tagging"] = nil
  757. resp, err := client.do("GET", bucketName, params, nil, nil, options...)
  758. if err != nil {
  759. return out, err
  760. }
  761. defer resp.Body.Close()
  762. err = xmlUnmarshal(resp.Body, &out)
  763. return out, err
  764. }
  765. //
  766. // DeleteBucketTagging delete bucket tagging
  767. // bucketName name of bucket
  768. // error nil if success, otherwise error
  769. //
  770. func (client Client) DeleteBucketTagging(bucketName string, options ...Option) error {
  771. params := map[string]interface{}{}
  772. params["tagging"] = nil
  773. resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
  774. if err != nil {
  775. return err
  776. }
  777. defer resp.Body.Close()
  778. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  779. }
  780. // GetBucketStat get bucket stat
  781. // bucketName the bucket name.
  782. // error it's nil if no error, otherwise it's an error object.
  783. func (client Client) GetBucketStat(bucketName string) (GetBucketStatResult, error) {
  784. var out GetBucketStatResult
  785. params := map[string]interface{}{}
  786. params["stat"] = nil
  787. resp, err := client.do("GET", bucketName, params, nil, nil)
  788. if err != nil {
  789. return out, err
  790. }
  791. defer resp.Body.Close()
  792. err = xmlUnmarshal(resp.Body, &out)
  793. return out, err
  794. }
  795. // GetBucketPolicy API operation for Object Storage Service.
  796. //
  797. // Get the policy from the bucket.
  798. //
  799. // bucketName the bucket name.
  800. //
  801. // string return the bucket's policy, and it's only valid when error is nil.
  802. //
  803. // error it's nil if no error, otherwise it's an error object.
  804. //
  805. func (client Client) GetBucketPolicy(bucketName string, options ...Option) (string, error) {
  806. params := map[string]interface{}{}
  807. params["policy"] = nil
  808. resp, err := client.do("GET", bucketName, params, nil, nil, options...)
  809. if err != nil {
  810. return "", err
  811. }
  812. defer resp.Body.Close()
  813. body, err := ioutil.ReadAll(resp.Body)
  814. out := string(body)
  815. return out, err
  816. }
  817. // SetBucketPolicy API operation for Object Storage Service.
  818. //
  819. // Set the policy from the bucket.
  820. //
  821. // bucketName the bucket name.
  822. //
  823. // policy the bucket policy.
  824. //
  825. // error it's nil if no error, otherwise it's an error object.
  826. //
  827. func (client Client) SetBucketPolicy(bucketName string, policy string, options ...Option) error {
  828. params := map[string]interface{}{}
  829. params["policy"] = nil
  830. buffer := strings.NewReader(policy)
  831. resp, err := client.do("PUT", bucketName, params, nil, buffer, options...)
  832. if err != nil {
  833. return err
  834. }
  835. defer resp.Body.Close()
  836. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  837. }
  838. // DeleteBucketPolicy API operation for Object Storage Service.
  839. //
  840. // Deletes the policy from the bucket.
  841. //
  842. // bucketName the bucket name.
  843. //
  844. // error it's nil if no error, otherwise it's an error object.
  845. //
  846. func (client Client) DeleteBucketPolicy(bucketName string, options ...Option) error {
  847. params := map[string]interface{}{}
  848. params["policy"] = nil
  849. resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
  850. if err != nil {
  851. return err
  852. }
  853. defer resp.Body.Close()
  854. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  855. }
  856. // SetBucketRequestPayment API operation for Object Storage Service.
  857. //
  858. // Set the requestPayment of bucket
  859. //
  860. // bucketName the bucket name.
  861. //
  862. // paymentConfig the payment configuration
  863. //
  864. // error it's nil if no error, otherwise it's an error object.
  865. //
  866. func (client Client) SetBucketRequestPayment(bucketName string, paymentConfig RequestPaymentConfiguration, options ...Option) error {
  867. params := map[string]interface{}{}
  868. params["requestPayment"] = nil
  869. var bs []byte
  870. bs, err := xml.Marshal(paymentConfig)
  871. if err != nil {
  872. return err
  873. }
  874. buffer := new(bytes.Buffer)
  875. buffer.Write(bs)
  876. contentType := http.DetectContentType(buffer.Bytes())
  877. headers := map[string]string{}
  878. headers[HTTPHeaderContentType] = contentType
  879. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  880. if err != nil {
  881. return err
  882. }
  883. defer resp.Body.Close()
  884. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  885. }
  886. // GetBucketRequestPayment API operation for Object Storage Service.
  887. //
  888. // Get bucket requestPayment
  889. //
  890. // bucketName the bucket name.
  891. //
  892. // RequestPaymentConfiguration the payment configuration
  893. //
  894. // error it's nil if no error, otherwise it's an error object.
  895. //
  896. func (client Client) GetBucketRequestPayment(bucketName string, options ...Option) (RequestPaymentConfiguration, error) {
  897. var out RequestPaymentConfiguration
  898. params := map[string]interface{}{}
  899. params["requestPayment"] = nil
  900. resp, err := client.do("GET", bucketName, params, nil, nil, options...)
  901. if err != nil {
  902. return out, err
  903. }
  904. defer resp.Body.Close()
  905. err = xmlUnmarshal(resp.Body, &out)
  906. return out, err
  907. }
  908. // GetUserQoSInfo API operation for Object Storage Service.
  909. //
  910. // Get user qos.
  911. //
  912. // UserQoSConfiguration the User Qos and range Information.
  913. //
  914. // error it's nil if no error, otherwise it's an error object.
  915. //
  916. func (client Client) GetUserQoSInfo(options ...Option) (UserQoSConfiguration, error) {
  917. var out UserQoSConfiguration
  918. params := map[string]interface{}{}
  919. params["qosInfo"] = nil
  920. resp, err := client.do("GET", "", params, nil, nil, options...)
  921. if err != nil {
  922. return out, err
  923. }
  924. defer resp.Body.Close()
  925. err = xmlUnmarshal(resp.Body, &out)
  926. return out, err
  927. }
  928. // SetBucketQoSInfo API operation for Object Storage Service.
  929. //
  930. // Set Bucket Qos information.
  931. //
  932. // bucketName tht bucket name.
  933. //
  934. // qosConf the qos configuration.
  935. //
  936. // error it's nil if no error, otherwise it's an error object.
  937. //
  938. func (client Client) SetBucketQoSInfo(bucketName string, qosConf BucketQoSConfiguration, options ...Option) error {
  939. params := map[string]interface{}{}
  940. params["qosInfo"] = nil
  941. var bs []byte
  942. bs, err := xml.Marshal(qosConf)
  943. if err != nil {
  944. return err
  945. }
  946. buffer := new(bytes.Buffer)
  947. buffer.Write(bs)
  948. contentTpye := http.DetectContentType(buffer.Bytes())
  949. headers := map[string]string{}
  950. headers[HTTPHeaderContentType] = contentTpye
  951. resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
  952. if err != nil {
  953. return err
  954. }
  955. defer resp.Body.Close()
  956. return checkRespCode(resp.StatusCode, []int{http.StatusOK})
  957. }
  958. // GetBucketQosInfo API operation for Object Storage Service.
  959. //
  960. // Get Bucket Qos information.
  961. //
  962. // bucketName tht bucket name.
  963. //
  964. // BucketQoSConfiguration the return qos configuration.
  965. //
  966. // error it's nil if no error, otherwise it's an error object.
  967. //
  968. func (client Client) GetBucketQosInfo(bucketName string, options ...Option) (BucketQoSConfiguration, error) {
  969. var out BucketQoSConfiguration
  970. params := map[string]interface{}{}
  971. params["qosInfo"] = nil
  972. resp, err := client.do("GET", bucketName, params, nil, nil, options...)
  973. if err != nil {
  974. return out, err
  975. }
  976. defer resp.Body.Close()
  977. err = xmlUnmarshal(resp.Body, &out)
  978. return out, err
  979. }
  980. // DeleteBucketQosInfo API operation for Object Storage Service.
  981. //
  982. // Delete Bucket QoS information.
  983. //
  984. // bucketName tht bucket name.
  985. //
  986. // error it's nil if no error, otherwise it's an error object.
  987. //
  988. func (client Client) DeleteBucketQosInfo(bucketName string, options ...Option) error {
  989. params := map[string]interface{}{}
  990. params["qosInfo"] = nil
  991. resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
  992. if err != nil {
  993. return err
  994. }
  995. defer resp.Body.Close()
  996. return checkRespCode(resp.StatusCode, []int{http.StatusNoContent})
  997. }
  998. // LimitUploadSpeed set upload bandwidth limit speed,default is 0,unlimited
  999. // upSpeed KB/s, 0 is unlimited,default is 0
  1000. // error it's nil if success, otherwise failure
  1001. func (client Client) LimitUploadSpeed(upSpeed int) error {
  1002. if client.Config == nil {
  1003. return fmt.Errorf("client config is nil")
  1004. }
  1005. return client.Config.LimitUploadSpeed(upSpeed)
  1006. }
  1007. // UseCname sets the flag of using CName. By default it's false.
  1008. //
  1009. // isUseCname true: the endpoint has the CName, false: the endpoint does not have cname. Default is false.
  1010. //
  1011. func UseCname(isUseCname bool) ClientOption {
  1012. return func(client *Client) {
  1013. client.Config.IsCname = isUseCname
  1014. client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
  1015. }
  1016. }
  1017. // Timeout sets the HTTP timeout in seconds.
  1018. //
  1019. // connectTimeoutSec HTTP timeout in seconds. Default is 10 seconds. 0 means infinite (not recommended)
  1020. // readWriteTimeout HTTP read or write's timeout in seconds. Default is 20 seconds. 0 means infinite.
  1021. //
  1022. func Timeout(connectTimeoutSec, readWriteTimeout int64) ClientOption {
  1023. return func(client *Client) {
  1024. client.Config.HTTPTimeout.ConnectTimeout =
  1025. time.Second * time.Duration(connectTimeoutSec)
  1026. client.Config.HTTPTimeout.ReadWriteTimeout =
  1027. time.Second * time.Duration(readWriteTimeout)
  1028. client.Config.HTTPTimeout.HeaderTimeout =
  1029. time.Second * time.Duration(readWriteTimeout)
  1030. client.Config.HTTPTimeout.IdleConnTimeout =
  1031. time.Second * time.Duration(readWriteTimeout)
  1032. client.Config.HTTPTimeout.LongTimeout =
  1033. time.Second * time.Duration(readWriteTimeout*10)
  1034. }
  1035. }
  1036. // SecurityToken sets the temporary user's SecurityToken.
  1037. //
  1038. // token STS token
  1039. //
  1040. func SecurityToken(token string) ClientOption {
  1041. return func(client *Client) {
  1042. client.Config.SecurityToken = strings.TrimSpace(token)
  1043. }
  1044. }
  1045. // EnableMD5 enables MD5 validation.
  1046. //
  1047. // isEnableMD5 true: enable MD5 validation; false: disable MD5 validation.
  1048. //
  1049. func EnableMD5(isEnableMD5 bool) ClientOption {
  1050. return func(client *Client) {
  1051. client.Config.IsEnableMD5 = isEnableMD5
  1052. }
  1053. }
  1054. // MD5ThresholdCalcInMemory sets the memory usage threshold for computing the MD5, default is 16MB.
  1055. //
  1056. // threshold the memory threshold in bytes. When the uploaded content is more than 16MB, the temp file is used for computing the MD5.
  1057. //
  1058. func MD5ThresholdCalcInMemory(threshold int64) ClientOption {
  1059. return func(client *Client) {
  1060. client.Config.MD5Threshold = threshold
  1061. }
  1062. }
  1063. // EnableCRC enables the CRC checksum. Default is true.
  1064. //
  1065. // isEnableCRC true: enable CRC checksum; false: disable the CRC checksum.
  1066. //
  1067. func EnableCRC(isEnableCRC bool) ClientOption {
  1068. return func(client *Client) {
  1069. client.Config.IsEnableCRC = isEnableCRC
  1070. }
  1071. }
  1072. // UserAgent specifies UserAgent. The default is aliyun-sdk-go/1.2.0 (windows/-/amd64;go1.5.2).
  1073. //
  1074. // userAgent the user agent string.
  1075. //
  1076. func UserAgent(userAgent string) ClientOption {
  1077. return func(client *Client) {
  1078. client.Config.UserAgent = userAgent
  1079. }
  1080. }
  1081. // Proxy sets the proxy (optional). The default is not using proxy.
  1082. //
  1083. // proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
  1084. //
  1085. func Proxy(proxyHost string) ClientOption {
  1086. return func(client *Client) {
  1087. client.Config.IsUseProxy = true
  1088. client.Config.ProxyHost = proxyHost
  1089. client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
  1090. }
  1091. }
  1092. // AuthProxy sets the proxy information with user name and password.
  1093. //
  1094. // proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
  1095. // proxyUser the proxy user name.
  1096. // proxyPassword the proxy password.
  1097. //
  1098. func AuthProxy(proxyHost, proxyUser, proxyPassword string) ClientOption {
  1099. return func(client *Client) {
  1100. client.Config.IsUseProxy = true
  1101. client.Config.ProxyHost = proxyHost
  1102. client.Config.IsAuthProxy = true
  1103. client.Config.ProxyUser = proxyUser
  1104. client.Config.ProxyPassword = proxyPassword
  1105. client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
  1106. }
  1107. }
  1108. //
  1109. // HTTPClient sets the http.Client in use to the one passed in
  1110. //
  1111. func HTTPClient(HTTPClient *http.Client) ClientOption {
  1112. return func(client *Client) {
  1113. client.HTTPClient = HTTPClient
  1114. }
  1115. }
  1116. //
  1117. // SetLogLevel sets the oss sdk log level
  1118. //
  1119. func SetLogLevel(LogLevel int) ClientOption {
  1120. return func(client *Client) {
  1121. client.Config.LogLevel = LogLevel
  1122. }
  1123. }
  1124. //
  1125. // SetLogger sets the oss sdk logger
  1126. //
  1127. func SetLogger(Logger *log.Logger) ClientOption {
  1128. return func(client *Client) {
  1129. client.Config.Logger = Logger
  1130. }
  1131. }
  1132. // SetAKInterface sets funciton for get the user's ak
  1133. //
  1134. func SetCredentialInfBuild(akBuild CredentialInfBuild) ClientOption {
  1135. return func(client *Client) {
  1136. client.Config.UserAKBuild = akBuild
  1137. }
  1138. }
  1139. // Private
  1140. func (client Client) do(method, bucketName string, params map[string]interface{},
  1141. headers map[string]string, data io.Reader, options ...Option) (*Response, error) {
  1142. resp, err := client.Conn.Do(method, bucketName, "", params,
  1143. headers, data, 0, nil)
  1144. // get response header
  1145. respHeader, _ := findOption(options, responseHeader, nil)
  1146. if respHeader != nil {
  1147. pRespHeader := respHeader.(*http.Header)
  1148. *pRespHeader = resp.Headers
  1149. }
  1150. return resp, err
  1151. }