2017-03-04 05:06:32 -05:00
// Package oss implements functions for access oss service.
// It has two main struct Client and Bucket.
package oss
import (
"bytes"
"encoding/xml"
"io"
"net/http"
"strings"
"time"
)
2019-10-14 10:21:52 -04:00
// 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).
// Object related operations are done by Bucket class.
// Users use oss.New to create Client instance.
2017-03-04 05:06:32 -05:00
//
type (
2019-10-14 10:21:52 -04:00
// Client OSS client
2017-03-04 05:06:32 -05:00
Client struct {
2019-10-14 10:21:52 -04:00
Config * Config // OSS client configuration
Conn * Conn // Send HTTP request
HTTPClient * http . Client //http.Client to use - if nil will make its own
2017-03-04 05:06:32 -05:00
}
// ClientOption client option such as UseCname, Timeout, SecurityToken.
ClientOption func ( * Client )
)
2019-10-14 10:21:52 -04:00
// New creates a new client.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// endpoint the OSS datacenter endpoint such as http://oss-cn-hangzhou.aliyuncs.com .
// accessKeyId access key Id.
// accessKeySecret access key secret.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// Client creates the new client instance, the returned value is valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func New ( endpoint , accessKeyID , accessKeySecret string , options ... ClientOption ) ( * Client , error ) {
2019-10-14 10:21:52 -04:00
// Configuration
2017-03-04 05:06:32 -05:00
config := getDefaultOssConfig ( )
config . Endpoint = endpoint
config . AccessKeyID = accessKeyID
config . AccessKeySecret = accessKeySecret
2019-10-14 10:21:52 -04:00
// URL parse
2017-03-04 05:06:32 -05:00
url := & urlMaker { }
url . Init ( config . Endpoint , config . IsCname , config . IsUseProxy )
2019-10-14 10:21:52 -04:00
// HTTP connect
2017-03-04 05:06:32 -05:00
conn := & Conn { config : config , url : url }
2019-10-14 10:21:52 -04:00
// OSS client
2017-03-04 05:06:32 -05:00
client := & Client {
2019-10-14 10:21:52 -04:00
Config : config ,
Conn : conn ,
2017-03-04 05:06:32 -05:00
}
2019-10-14 10:21:52 -04:00
// Client options parse
2017-03-04 05:06:32 -05:00
for _ , option := range options {
option ( client )
}
2019-10-14 10:21:52 -04:00
// Create HTTP connection
err := conn . init ( config , url , client . HTTPClient )
2017-03-04 05:06:32 -05:00
return client , err
}
2019-10-14 10:21:52 -04:00
// Bucket gets the bucket instance.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
// Bucket the bucket object, when error is nil.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) Bucket ( bucketName string ) ( * Bucket , error ) {
return & Bucket {
client ,
bucketName ,
} , nil
}
2019-10-14 10:21:52 -04:00
// CreateBucket creates a bucket.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name, it's globably unique and immutable. The bucket name can only consist of lowercase letters, numbers and dash ('-').
// It must start with lowercase letter or number and the length can only be between 3 and 255.
// options options for creating the bucket, with optional ACL. The ACL could be ACLPrivate, ACLPublicRead, and ACLPublicReadWrite. By default it's ACLPrivate.
// It could also be specified with StorageClass option, which supports StorageStandard, StorageIA(infrequent access), StorageArchive.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) CreateBucket ( bucketName string , options ... Option ) error {
headers := make ( map [ string ] string )
handleOptions ( headers , options )
2019-10-14 10:21:52 -04:00
buffer := new ( bytes . Buffer )
isOptSet , val , _ := isOptionSet ( options , storageClass )
if isOptSet {
cbConfig := createBucketConfiguration { StorageClass : val . ( StorageClassType ) }
bs , err := xml . Marshal ( cbConfig )
if err != nil {
return err
}
buffer . Write ( bs )
contentType := http . DetectContentType ( buffer . Bytes ( ) )
headers [ HTTPHeaderContentType ] = contentType
}
params := map [ string ] interface { } { }
resp , err := client . do ( "PUT" , bucketName , params , headers , buffer )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// ListBuckets lists buckets of the current account under the given endpoint, with optional filters.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// options specifies the filters such as Prefix, Marker and MaxKeys. Prefix is the bucket name's prefix filter.
// And marker makes sure the returned buckets' name are greater than it in lexicographic order.
// Maxkeys limits the max keys to return, and by default it's 100 and up to 1000.
// For the common usage scenario, please check out list_bucket.go in the sample.
// ListBucketsResponse the response object if error is nil.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) ListBuckets ( options ... Option ) ( ListBucketsResult , error ) {
var out ListBucketsResult
2019-10-14 10:21:52 -04:00
params , err := getRawParams ( options )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
2019-10-14 10:21:52 -04:00
resp , err := client . do ( "GET" , "" , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// IsBucketExist checks if the bucket exists
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bool true if it exists, and it's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) IsBucketExist ( bucketName string ) ( bool , error ) {
listRes , err := client . ListBuckets ( Prefix ( bucketName ) , MaxKeys ( 1 ) )
if err != nil {
return false , err
}
if len ( listRes . Buckets ) == 1 && listRes . Buckets [ 0 ] . Name == bucketName {
return true , nil
}
return false , nil
}
2019-10-14 10:21:52 -04:00
// DeleteBucket deletes the bucket. Only empty bucket can be deleted (no object and parts).
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) DeleteBucket ( bucketName string ) error {
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
resp , err := client . do ( "DELETE" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusNoContent } )
}
2019-10-14 10:21:52 -04:00
// GetBucketLocation gets the bucket location.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// Checks out the following link for more information :
2017-03-04 05:06:32 -05:00
// https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// string bucket's datacenter location
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketLocation ( bucketName string ) ( string , error ) {
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "location" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return "" , err
}
defer resp . Body . Close ( )
var LocationConstraint string
err = xmlUnmarshal ( resp . Body , & LocationConstraint )
return LocationConstraint , err
}
2019-10-14 10:21:52 -04:00
// SetBucketACL sets bucket's ACL.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name
// bucketAcl the bucket ACL: ACLPrivate, ACLPublicRead and ACLPublicReadWrite.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) SetBucketACL ( bucketName string , bucketACL ACLType ) error {
headers := map [ string ] string { HTTPHeaderOssACL : string ( bucketACL ) }
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
resp , err := client . do ( "PUT" , bucketName , params , headers , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// GetBucketACL gets the bucket ACL.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// GetBucketAclResponse the result object, and it's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketACL ( bucketName string ) ( GetBucketACLResult , error ) {
var out GetBucketACLResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "acl" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// SetBucketLifecycle sets the bucket's lifecycle.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// For more information, checks out following link:
2017-03-04 05:06:32 -05:00
// https://help.aliyun.com/document_detail/oss/user_guide/manage_object/object_lifecycle.html
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
// rules the lifecycle rules. There're two kind of rules: absolute time expiration and relative time expiration in days and day/month/year respectively.
// Check out sample/bucket_lifecycle.go for more details.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) SetBucketLifecycle ( bucketName string , rules [ ] LifecycleRule ) error {
lxml := lifecycleXML { Rules : convLifecycleRule ( rules ) }
bs , err := xml . Marshal ( lxml )
if err != nil {
return err
}
buffer := new ( bytes . Buffer )
buffer . Write ( bs )
contentType := http . DetectContentType ( buffer . Bytes ( ) )
headers := map [ string ] string { }
headers [ HTTPHeaderContentType ] = contentType
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "lifecycle" ] = nil
resp , err := client . do ( "PUT" , bucketName , params , headers , buffer )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// DeleteBucketLifecycle deletes the bucket's lifecycle.
2017-03-04 05:06:32 -05:00
//
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) DeleteBucketLifecycle ( bucketName string ) error {
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "lifecycle" ] = nil
resp , err := client . do ( "DELETE" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusNoContent } )
}
2019-10-14 10:21:52 -04:00
// GetBucketLifecycle gets the bucket's lifecycle settings.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// GetBucketLifecycleResponse the result object upon successful request. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketLifecycle ( bucketName string ) ( GetBucketLifecycleResult , error ) {
var out GetBucketLifecycleResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "lifecycle" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// SetBucketReferer sets the bucket's referer whitelist and the flag if allowing empty referrer.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// 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
// the allowing empty referrer flag. Note that this applies to requests from webbrowser only.
// For example, for a bucket os-example and its referrer http://www.aliyun.com, all requests from this URL could access the bucket.
// For more information, please check out this link :
2017-03-04 05:06:32 -05:00
// https://help.aliyun.com/document_detail/oss/user_guide/security_management/referer.html
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
// referers the referrer white list. A bucket could have a referrer list and each referrer supports one '*' and multiple '?' as wildcards.
// The sample could be found in sample/bucket_referer.go
// allowEmptyReferer the flag of allowing empty referrer. By default it's true.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) SetBucketReferer ( bucketName string , referers [ ] string , allowEmptyReferer bool ) error {
rxml := RefererXML { }
rxml . AllowEmptyReferer = allowEmptyReferer
if referers == nil {
rxml . RefererList = append ( rxml . RefererList , "" )
} else {
for _ , referer := range referers {
rxml . RefererList = append ( rxml . RefererList , referer )
}
}
bs , err := xml . Marshal ( rxml )
if err != nil {
return err
}
buffer := new ( bytes . Buffer )
buffer . Write ( bs )
contentType := http . DetectContentType ( buffer . Bytes ( ) )
headers := map [ string ] string { }
headers [ HTTPHeaderContentType ] = contentType
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "referer" ] = nil
resp , err := client . do ( "PUT" , bucketName , params , headers , buffer )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// GetBucketReferer gets the bucket's referrer white list.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// GetBucketRefererResponse the result object upon successful request. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketReferer ( bucketName string ) ( GetBucketRefererResult , error ) {
var out GetBucketRefererResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "referer" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// SetBucketLogging sets the bucket logging settings.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// OSS could automatically store the access log. Only the bucket owner could enable the logging.
// Once enabled, OSS would save all the access log into hourly log files in a specified bucket.
// For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/logging.html
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName bucket name to enable the log.
// targetBucket the target bucket name to store the log files.
// targetPrefix the log files' prefix.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) SetBucketLogging ( bucketName , targetBucket , targetPrefix string ,
isEnable bool ) error {
var err error
var bs [ ] byte
if isEnable {
lxml := LoggingXML { }
lxml . LoggingEnabled . TargetBucket = targetBucket
lxml . LoggingEnabled . TargetPrefix = targetPrefix
bs , err = xml . Marshal ( lxml )
} else {
lxml := loggingXMLEmpty { }
bs , err = xml . Marshal ( lxml )
}
if err != nil {
return err
}
buffer := new ( bytes . Buffer )
buffer . Write ( bs )
contentType := http . DetectContentType ( buffer . Bytes ( ) )
headers := map [ string ] string { }
headers [ HTTPHeaderContentType ] = contentType
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "logging" ] = nil
resp , err := client . do ( "PUT" , bucketName , params , headers , buffer )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// DeleteBucketLogging deletes the logging configuration to disable the logging on the bucket.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name to disable the logging.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) DeleteBucketLogging ( bucketName string ) error {
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "logging" ] = nil
resp , err := client . do ( "DELETE" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusNoContent } )
}
2019-10-14 10:21:52 -04:00
// GetBucketLogging gets the bucket's logging settings
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name
// GetBucketLoggingResponse the result object upon successful request. It's only valid when error is nil.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketLogging ( bucketName string ) ( GetBucketLoggingResult , error ) {
var out GetBucketLoggingResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "logging" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// SetBucketWebsite sets the bucket's static website's index and error page.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// 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.
// For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name to enable static web site.
// indexDocument index page.
// errorDocument error page.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) SetBucketWebsite ( bucketName , indexDocument , errorDocument string ) error {
wxml := WebsiteXML { }
wxml . IndexDocument . Suffix = indexDocument
wxml . ErrorDocument . Key = errorDocument
bs , err := xml . Marshal ( wxml )
if err != nil {
return err
}
buffer := new ( bytes . Buffer )
buffer . Write ( bs )
contentType := http . DetectContentType ( buffer . Bytes ( ) )
headers := make ( map [ string ] string )
headers [ HTTPHeaderContentType ] = contentType
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "website" ] = nil
resp , err := client . do ( "PUT" , bucketName , params , headers , buffer )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// DeleteBucketWebsite deletes the bucket's static web site settings.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) DeleteBucketWebsite ( bucketName string ) error {
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "website" ] = nil
resp , err := client . do ( "DELETE" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusNoContent } )
}
2019-10-14 10:21:52 -04:00
// GetBucketWebsite gets the bucket's default page (index page) and the error page.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// GetBucketWebsiteResponse the result object upon successful request. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketWebsite ( bucketName string ) ( GetBucketWebsiteResult , error ) {
var out GetBucketWebsiteResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "website" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// SetBucketCORS sets the bucket's CORS rules
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/cors.html
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name
// corsRules the CORS rules to set. The related sample code is in sample/bucket_cors.go.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) SetBucketCORS ( bucketName string , corsRules [ ] CORSRule ) error {
corsxml := CORSXML { }
for _ , v := range corsRules {
cr := CORSRule { }
cr . AllowedMethod = v . AllowedMethod
cr . AllowedOrigin = v . AllowedOrigin
cr . AllowedHeader = v . AllowedHeader
cr . ExposeHeader = v . ExposeHeader
cr . MaxAgeSeconds = v . MaxAgeSeconds
corsxml . CORSRules = append ( corsxml . CORSRules , cr )
}
bs , err := xml . Marshal ( corsxml )
if err != nil {
return err
}
buffer := new ( bytes . Buffer )
buffer . Write ( bs )
contentType := http . DetectContentType ( buffer . Bytes ( ) )
headers := map [ string ] string { }
headers [ HTTPHeaderContentType ] = contentType
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "cors" ] = nil
resp , err := client . do ( "PUT" , bucketName , params , headers , buffer )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusOK } )
}
2019-10-14 10:21:52 -04:00
// DeleteBucketCORS deletes the bucket's static website settings.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) DeleteBucketCORS ( bucketName string ) error {
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "cors" ] = nil
resp , err := client . do ( "DELETE" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return err
}
defer resp . Body . Close ( )
return checkRespCode ( resp . StatusCode , [ ] int { http . StatusNoContent } )
}
2019-10-14 10:21:52 -04:00
// GetBucketCORS gets the bucket's CORS settings.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
// GetBucketCORSResult the result object upon successful request. It's only valid when error is nil.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketCORS ( bucketName string ) ( GetBucketCORSResult , error ) {
var out GetBucketCORSResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "cors" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// GetBucketInfo gets the bucket information.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// bucketName the bucket name.
// GetBucketInfoResult the result object upon successful request. It's only valid when error is nil.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// error it's nil if no error, otherwise it's an error object.
2017-03-04 05:06:32 -05:00
//
func ( client Client ) GetBucketInfo ( bucketName string ) ( GetBucketInfoResult , error ) {
var out GetBucketInfoResult
2019-10-14 10:21:52 -04:00
params := map [ string ] interface { } { }
params [ "bucketInfo" ] = nil
resp , err := client . do ( "GET" , bucketName , params , nil , nil )
2017-03-04 05:06:32 -05:00
if err != nil {
return out , err
}
defer resp . Body . Close ( )
err = xmlUnmarshal ( resp . Body , & out )
return out , err
}
2019-10-14 10:21:52 -04:00
// UseCname sets the flag of using CName. By default it's false.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// isUseCname true: the endpoint has the CName, false: the endpoint does not have cname. Default is false.
2017-03-04 05:06:32 -05:00
//
func UseCname ( isUseCname bool ) ClientOption {
return func ( client * Client ) {
client . Config . IsCname = isUseCname
client . Conn . url . Init ( client . Config . Endpoint , client . Config . IsCname , client . Config . IsUseProxy )
}
}
2019-10-14 10:21:52 -04:00
// Timeout sets the HTTP timeout in seconds.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// connectTimeoutSec HTTP timeout in seconds. Default is 10 seconds. 0 means infinite (not recommended)
// readWriteTimeout HTTP read or write's timeout in seconds. Default is 20 seconds. 0 means infinite.
2017-03-04 05:06:32 -05:00
//
func Timeout ( connectTimeoutSec , readWriteTimeout int64 ) ClientOption {
return func ( client * Client ) {
client . Config . HTTPTimeout . ConnectTimeout =
time . Second * time . Duration ( connectTimeoutSec )
client . Config . HTTPTimeout . ReadWriteTimeout =
time . Second * time . Duration ( readWriteTimeout )
client . Config . HTTPTimeout . HeaderTimeout =
time . Second * time . Duration ( readWriteTimeout )
2019-10-14 10:21:52 -04:00
client . Config . HTTPTimeout . IdleConnTimeout =
time . Second * time . Duration ( readWriteTimeout )
2017-03-04 05:06:32 -05:00
client . Config . HTTPTimeout . LongTimeout =
time . Second * time . Duration ( readWriteTimeout * 10 )
}
}
2019-10-14 10:21:52 -04:00
// SecurityToken sets the temporary user's SecurityToken.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// token STS token
2017-03-04 05:06:32 -05:00
//
func SecurityToken ( token string ) ClientOption {
return func ( client * Client ) {
client . Config . SecurityToken = strings . TrimSpace ( token )
}
}
2019-10-14 10:21:52 -04:00
// EnableMD5 enables MD5 validation.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// isEnableMD5 true: enable MD5 validation; false: disable MD5 validation.
2017-03-04 05:06:32 -05:00
//
func EnableMD5 ( isEnableMD5 bool ) ClientOption {
return func ( client * Client ) {
client . Config . IsEnableMD5 = isEnableMD5
}
}
2019-10-14 10:21:52 -04:00
// MD5ThresholdCalcInMemory sets the memory usage threshold for computing the MD5, default is 16MB.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// threshold the memory threshold in bytes. When the uploaded content is more than 16MB, the temp file is used for computing the MD5.
2017-03-04 05:06:32 -05:00
//
func MD5ThresholdCalcInMemory ( threshold int64 ) ClientOption {
return func ( client * Client ) {
client . Config . MD5Threshold = threshold
}
}
2019-10-14 10:21:52 -04:00
// EnableCRC enables the CRC checksum. Default is true.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// isEnableCRC true: enable CRC checksum; false: disable the CRC checksum.
2017-03-04 05:06:32 -05:00
//
func EnableCRC ( isEnableCRC bool ) ClientOption {
return func ( client * Client ) {
client . Config . IsEnableCRC = isEnableCRC
}
}
2019-10-14 10:21:52 -04:00
// UserAgent specifies UserAgent. The default is aliyun-sdk-go/1.2.0 (windows/-/amd64;go1.5.2).
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// userAgent the user agent string.
2017-03-04 05:06:32 -05:00
//
func UserAgent ( userAgent string ) ClientOption {
return func ( client * Client ) {
client . Config . UserAgent = userAgent
}
}
2019-10-14 10:21:52 -04:00
// Proxy sets the proxy (optional). The default is not using proxy.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
2017-03-04 05:06:32 -05:00
//
func Proxy ( proxyHost string ) ClientOption {
return func ( client * Client ) {
client . Config . IsUseProxy = true
client . Config . ProxyHost = proxyHost
client . Conn . url . Init ( client . Config . Endpoint , client . Config . IsCname , client . Config . IsUseProxy )
}
}
2019-10-14 10:21:52 -04:00
// AuthProxy sets the proxy information with user name and password.
2017-03-04 05:06:32 -05:00
//
2019-10-14 10:21:52 -04:00
// proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
// proxyUser the proxy user name.
// proxyPassword the proxy password.
2017-03-04 05:06:32 -05:00
//
func AuthProxy ( proxyHost , proxyUser , proxyPassword string ) ClientOption {
return func ( client * Client ) {
client . Config . IsUseProxy = true
client . Config . ProxyHost = proxyHost
client . Config . IsAuthProxy = true
client . Config . ProxyUser = proxyUser
client . Config . ProxyPassword = proxyPassword
client . Conn . url . Init ( client . Config . Endpoint , client . Config . IsCname , client . Config . IsUseProxy )
}
}
2019-10-14 10:21:52 -04:00
//
// HTTPClient sets the http.Client in use to the one passed in
//
func HTTPClient ( HTTPClient * http . Client ) ClientOption {
return func ( client * Client ) {
client . HTTPClient = HTTPClient
}
}
2017-03-04 05:06:32 -05:00
// Private
2019-10-14 10:21:52 -04:00
func ( client Client ) do ( method , bucketName string , params map [ string ] interface { } ,
2017-03-04 05:06:32 -05:00
headers map [ string ] string , data io . Reader ) ( * Response , error ) {
2019-10-14 10:21:52 -04:00
return client . Conn . Do ( method , bucketName , "" , params ,
headers , data , 0 , nil )
2017-03-04 05:06:32 -05:00
}