github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/obs/client.go (about)

     1  // Copyright 2019 Huawei Technologies Co.,Ltd.
     2  // Licensed under the Apache License, Version 2.0 (the "License"); you may not use
     3  // this file except in compliance with the License.  You may obtain a copy of the
     4  // License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software distributed
     9  // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    10  // CONDITIONS OF ANY KIND, either express or implied.  See the License for the
    11  // specific language governing permissions and limitations under the License.
    12  
    13  package obs
    14  
    15  import (
    16  	"errors"
    17  	"fmt"
    18  	"io"
    19  	"net/http"
    20  	"os"
    21  	"sort"
    22  	"strings"
    23  )
    24  
    25  // ObsClient defines OBS client.
    26  type ObsClient struct {
    27  	conf       *config
    28  	httpClient *http.Client
    29  }
    30  
    31  // New creates a new ObsClient instance.
    32  func New(ak, sk, endpoint string, configurers ...configurer) (*ObsClient, error) {
    33  	conf := &config{endpoint: endpoint}
    34  	conf.securityProviders = make([]securityProvider, 0, 3)
    35  	conf.securityProviders = append(conf.securityProviders, NewBasicSecurityProvider(ak, sk, ""))
    36  
    37  	conf.maxRetryCount = -1
    38  	conf.maxRedirectCount = -1
    39  	for _, configurer := range configurers {
    40  		configurer(conf)
    41  	}
    42  
    43  	if err := conf.initConfigWithDefault(); err != nil {
    44  		return nil, err
    45  	}
    46  	err := conf.getTransport()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	if isWarnLogEnabled() {
    52  		info := make([]string, 3)
    53  		info[0] = fmt.Sprintf("[OBS SDK Version=%s", obsSdkVersion)
    54  		info[1] = fmt.Sprintf("Endpoint=%s", conf.endpoint)
    55  		accessMode := "Virtual Hosting"
    56  		if conf.pathStyle {
    57  			accessMode = "Path"
    58  		}
    59  		info[2] = fmt.Sprintf("Access Mode=%s]", accessMode)
    60  		doLog(LEVEL_WARN, strings.Join(info, "];["))
    61  	}
    62  	doLog(LEVEL_DEBUG, "Create obsclient with config:\n%s\n", conf)
    63  	obsClient := &ObsClient{conf: conf, httpClient: &http.Client{Transport: conf.transport, CheckRedirect: checkRedirectFunc}}
    64  	return obsClient, nil
    65  }
    66  
    67  // Refresh refreshes ak, sk and securityToken for obsClient.
    68  func (obsClient ObsClient) Refresh(ak, sk, securityToken string) {
    69  	for _, sp := range obsClient.conf.securityProviders {
    70  		if bsp, ok := sp.(*BasicSecurityProvider); ok {
    71  			bsp.refresh(strings.TrimSpace(ak), strings.TrimSpace(sk), strings.TrimSpace(securityToken))
    72  			break
    73  		}
    74  	}
    75  }
    76  
    77  func (obsClient ObsClient) getSecurity() securityHolder {
    78  	if obsClient.conf.securityProviders != nil {
    79  		for _, sp := range obsClient.conf.securityProviders {
    80  			if sp == nil {
    81  				continue
    82  			}
    83  			sh := sp.getSecurity()
    84  			if sh.ak != "" && sh.sk != "" {
    85  				return sh
    86  			}
    87  		}
    88  	}
    89  	return emptySecurityHolder
    90  }
    91  
    92  // Close closes ObsClient.
    93  func (obsClient ObsClient) Close() {
    94  	obsClient.httpClient = nil
    95  	obsClient.conf.transport.CloseIdleConnections()
    96  	obsClient.conf = nil
    97  }
    98  
    99  // ListBuckets lists buckets.
   100  //
   101  // You can use this API to obtain the bucket list. In the list, bucket names are displayed in lexicographical order.
   102  func (obsClient ObsClient) ListBuckets(input *ListBucketsInput, extensions ...extensionOptions) (output *ListBucketsOutput, err error) {
   103  	if input == nil {
   104  		input = &ListBucketsInput{}
   105  	}
   106  	output = &ListBucketsOutput{}
   107  	err = obsClient.doActionWithoutBucket("ListBuckets", HTTP_GET, input, output, extensions)
   108  	if err != nil {
   109  		output = nil
   110  	}
   111  	return
   112  }
   113  
   114  // CreateBucket creates a bucket.
   115  //
   116  // You can use this API to create a bucket and name it as you specify. The created bucket name must be unique in OBS.
   117  func (obsClient ObsClient) CreateBucket(input *CreateBucketInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   118  	if input == nil {
   119  		return nil, errors.New("CreateBucketInput is nil")
   120  	}
   121  	output = &BaseModel{}
   122  	err = obsClient.doActionWithBucket("CreateBucket", HTTP_PUT, input.Bucket, input, output, extensions)
   123  	if err != nil {
   124  		output = nil
   125  	}
   126  	return
   127  }
   128  
   129  // DeleteBucket deletes a bucket.
   130  //
   131  // You can use this API to delete a bucket. The bucket to be deleted must be empty
   132  // (containing no objects, noncurrent object versions, or part fragments).
   133  func (obsClient ObsClient) DeleteBucket(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   134  	output = &BaseModel{}
   135  	err = obsClient.doActionWithBucket("DeleteBucket", HTTP_DELETE, bucketName, defaultSerializable, output, extensions)
   136  	if err != nil {
   137  		output = nil
   138  	}
   139  	return
   140  }
   141  
   142  // SetBucketStoragePolicy sets bucket storage class.
   143  //
   144  // You can use this API to set storage class for bucket.
   145  func (obsClient ObsClient) SetBucketStoragePolicy(input *SetBucketStoragePolicyInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   146  	if input == nil {
   147  		return nil, errors.New("SetBucketStoragePolicyInput is nil")
   148  	}
   149  	output = &BaseModel{}
   150  	err = obsClient.doActionWithBucket("SetBucketStoragePolicy", HTTP_PUT, input.Bucket, input, output, extensions)
   151  	if err != nil {
   152  		output = nil
   153  	}
   154  	return
   155  }
   156  func (obsClient ObsClient) getBucketStoragePolicyS3(bucketName string, extensions []extensionOptions) (output *GetBucketStoragePolicyOutput, err error) {
   157  	output = &GetBucketStoragePolicyOutput{}
   158  	var outputS3 *getBucketStoragePolicyOutputS3
   159  	outputS3 = &getBucketStoragePolicyOutputS3{}
   160  	err = obsClient.doActionWithBucket("GetBucketStoragePolicy", HTTP_GET, bucketName, newSubResourceSerial(SubResourceStoragePolicy), outputS3, extensions)
   161  	if err != nil {
   162  		output = nil
   163  		return
   164  	}
   165  	output.BaseModel = outputS3.BaseModel
   166  	output.StorageClass = fmt.Sprintf("%s", outputS3.StorageClass)
   167  	return
   168  }
   169  
   170  func (obsClient ObsClient) getBucketStoragePolicyObs(bucketName string, extensions []extensionOptions) (output *GetBucketStoragePolicyOutput, err error) {
   171  	output = &GetBucketStoragePolicyOutput{}
   172  	var outputObs *getBucketStoragePolicyOutputObs
   173  	outputObs = &getBucketStoragePolicyOutputObs{}
   174  	err = obsClient.doActionWithBucket("GetBucketStoragePolicy", HTTP_GET, bucketName, newSubResourceSerial(SubResourceStorageClass), outputObs, extensions)
   175  	if err != nil {
   176  		output = nil
   177  		return
   178  	}
   179  	output.BaseModel = outputObs.BaseModel
   180  	output.StorageClass = outputObs.StorageClass
   181  	return
   182  }
   183  
   184  // GetBucketStoragePolicy gets bucket storage class.
   185  //
   186  // You can use this API to obtain the storage class of a bucket.
   187  func (obsClient ObsClient) GetBucketStoragePolicy(bucketName string, extensions ...extensionOptions) (output *GetBucketStoragePolicyOutput, err error) {
   188  	if obsClient.conf.signature == SignatureObs {
   189  		return obsClient.getBucketStoragePolicyObs(bucketName, extensions)
   190  	}
   191  	return obsClient.getBucketStoragePolicyS3(bucketName, extensions)
   192  }
   193  
   194  // ListObjects lists objects in a bucket.
   195  //
   196  // You can use this API to list objects in a bucket. By default, a maximum of 1000 objects are listed.
   197  func (obsClient ObsClient) ListObjects(input *ListObjectsInput, extensions ...extensionOptions) (output *ListObjectsOutput, err error) {
   198  	if input == nil {
   199  		return nil, errors.New("ListObjectsInput is nil")
   200  	}
   201  	output = &ListObjectsOutput{}
   202  	err = obsClient.doActionWithBucket("ListObjects", HTTP_GET, input.Bucket, input, output, extensions)
   203  	if err != nil {
   204  		output = nil
   205  	} else {
   206  		if location, ok := output.ResponseHeaders[HEADER_BUCKET_REGION]; ok {
   207  			output.Location = location[0]
   208  		}
   209  		if output.EncodingType == "url" {
   210  			err = decodeListObjectsOutput(output)
   211  			if err != nil {
   212  				doLog(LEVEL_ERROR, "Failed to get ListObjectsOutput with error: %v.", err)
   213  				output = nil
   214  			}
   215  		}
   216  	}
   217  	return
   218  }
   219  
   220  // ListVersions lists versioning objects in a bucket.
   221  //
   222  // You can use this API to list versioning objects in a bucket. By default, a maximum of 1000 versioning objects are listed.
   223  func (obsClient ObsClient) ListVersions(input *ListVersionsInput, extensions ...extensionOptions) (output *ListVersionsOutput, err error) {
   224  	if input == nil {
   225  		return nil, errors.New("ListVersionsInput is nil")
   226  	}
   227  	output = &ListVersionsOutput{}
   228  	err = obsClient.doActionWithBucket("ListVersions", HTTP_GET, input.Bucket, input, output, extensions)
   229  	if err != nil {
   230  		output = nil
   231  	} else {
   232  		if location, ok := output.ResponseHeaders[HEADER_BUCKET_REGION]; ok {
   233  			output.Location = location[0]
   234  		}
   235  		if output.EncodingType == "url" {
   236  			err = decodeListVersionsOutput(output)
   237  			if err != nil {
   238  				doLog(LEVEL_ERROR, "Failed to get ListVersionsOutput with error: %v.", err)
   239  				output = nil
   240  			}
   241  		}
   242  	}
   243  	return
   244  }
   245  
   246  // ListMultipartUploads lists the multipart uploads.
   247  //
   248  // You can use this API to list the multipart uploads that are initialized but not combined or aborted in a specified bucket.
   249  func (obsClient ObsClient) ListMultipartUploads(input *ListMultipartUploadsInput, extensions ...extensionOptions) (output *ListMultipartUploadsOutput, err error) {
   250  	if input == nil {
   251  		return nil, errors.New("ListMultipartUploadsInput is nil")
   252  	}
   253  	output = &ListMultipartUploadsOutput{}
   254  	err = obsClient.doActionWithBucket("ListMultipartUploads", HTTP_GET, input.Bucket, input, output, extensions)
   255  	if err != nil {
   256  		output = nil
   257  	} else if output.EncodingType == "url" {
   258  		err = decodeListMultipartUploadsOutput(output)
   259  		if err != nil {
   260  			doLog(LEVEL_ERROR, "Failed to get ListMultipartUploadsOutput with error: %v.", err)
   261  			output = nil
   262  		}
   263  	}
   264  	return
   265  }
   266  
   267  // SetBucketQuota sets the bucket quota.
   268  //
   269  // You can use this API to set the bucket quota. A bucket quota must be expressed in bytes and the maximum value is 2^63-1.
   270  func (obsClient ObsClient) SetBucketQuota(input *SetBucketQuotaInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   271  	if input == nil {
   272  		return nil, errors.New("SetBucketQuotaInput is nil")
   273  	}
   274  	output = &BaseModel{}
   275  	err = obsClient.doActionWithBucket("SetBucketQuota", HTTP_PUT, input.Bucket, input, output, extensions)
   276  	if err != nil {
   277  		output = nil
   278  	}
   279  	return
   280  }
   281  
   282  // GetBucketQuota gets the bucket quota.
   283  //
   284  // You can use this API to obtain the bucket quota. Value 0 indicates that no upper limit is set for the bucket quota.
   285  func (obsClient ObsClient) GetBucketQuota(bucketName string, extensions ...extensionOptions) (output *GetBucketQuotaOutput, err error) {
   286  	output = &GetBucketQuotaOutput{}
   287  	err = obsClient.doActionWithBucket("GetBucketQuota", HTTP_GET, bucketName, newSubResourceSerial(SubResourceQuota), output, extensions)
   288  	if err != nil {
   289  		output = nil
   290  	}
   291  	return
   292  }
   293  
   294  // HeadBucket checks whether a bucket exists.
   295  //
   296  // You can use this API to check whether a bucket exists.
   297  func (obsClient ObsClient) HeadBucket(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   298  	output = &BaseModel{}
   299  	err = obsClient.doActionWithBucket("HeadBucket", HTTP_HEAD, bucketName, defaultSerializable, output, extensions)
   300  	if err != nil {
   301  		output = nil
   302  	}
   303  	return
   304  }
   305  
   306  // HeadObject checks whether an object exists.
   307  //
   308  // You can use this API to check whether an object exists.
   309  func (obsClient ObsClient) HeadObject(input *HeadObjectInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   310  	if input == nil {
   311  		return nil, errors.New("HeadObjectInput is nil")
   312  	}
   313  	output = &BaseModel{}
   314  	err = obsClient.doActionWithBucketAndKey("HeadObject", HTTP_HEAD, input.Bucket, input.Key, input, output, extensions)
   315  	if err != nil {
   316  		output = nil
   317  	}
   318  	return
   319  }
   320  
   321  // GetBucketMetadata gets the metadata of a bucket.
   322  //
   323  // You can use this API to send a HEAD request to a bucket to obtain the bucket
   324  // metadata such as the storage class and CORS rules (if set).
   325  func (obsClient ObsClient) GetBucketMetadata(input *GetBucketMetadataInput, extensions ...extensionOptions) (output *GetBucketMetadataOutput, err error) {
   326  	output = &GetBucketMetadataOutput{}
   327  	err = obsClient.doActionWithBucket("GetBucketMetadata", HTTP_HEAD, input.Bucket, input, output, extensions)
   328  	if err != nil {
   329  		output = nil
   330  	} else {
   331  		ParseGetBucketMetadataOutput(output)
   332  	}
   333  	return
   334  }
   335  
   336  // SetObjectMetadata sets object metadata.
   337  func (obsClient ObsClient) SetObjectMetadata(input *SetObjectMetadataInput, extensions ...extensionOptions) (output *SetObjectMetadataOutput, err error) {
   338  	output = &SetObjectMetadataOutput{}
   339  	err = obsClient.doActionWithBucketAndKey("SetObjectMetadata", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
   340  	if err != nil {
   341  		output = nil
   342  	} else {
   343  		ParseSetObjectMetadataOutput(output)
   344  	}
   345  	return
   346  }
   347  
   348  // GetBucketStorageInfo gets storage information about a bucket.
   349  //
   350  // You can use this API to obtain storage information about a bucket, including the
   351  // bucket size and number of objects in the bucket.
   352  func (obsClient ObsClient) GetBucketStorageInfo(bucketName string, extensions ...extensionOptions) (output *GetBucketStorageInfoOutput, err error) {
   353  	output = &GetBucketStorageInfoOutput{}
   354  	err = obsClient.doActionWithBucket("GetBucketStorageInfo", HTTP_GET, bucketName, newSubResourceSerial(SubResourceStorageInfo), output, extensions)
   355  	if err != nil {
   356  		output = nil
   357  	}
   358  	return
   359  }
   360  
   361  func (obsClient ObsClient) getBucketLocationS3(bucketName string, extensions []extensionOptions) (output *GetBucketLocationOutput, err error) {
   362  	output = &GetBucketLocationOutput{}
   363  	var outputS3 *getBucketLocationOutputS3
   364  	outputS3 = &getBucketLocationOutputS3{}
   365  	err = obsClient.doActionWithBucket("GetBucketLocation", HTTP_GET, bucketName, newSubResourceSerial(SubResourceLocation), outputS3, extensions)
   366  	if err != nil {
   367  		output = nil
   368  	} else {
   369  		output.BaseModel = outputS3.BaseModel
   370  		output.Location = outputS3.Location
   371  	}
   372  	return
   373  }
   374  func (obsClient ObsClient) getBucketLocationObs(bucketName string, extensions []extensionOptions) (output *GetBucketLocationOutput, err error) {
   375  	output = &GetBucketLocationOutput{}
   376  	var outputObs *getBucketLocationOutputObs
   377  	outputObs = &getBucketLocationOutputObs{}
   378  	err = obsClient.doActionWithBucket("GetBucketLocation", HTTP_GET, bucketName, newSubResourceSerial(SubResourceLocation), outputObs, extensions)
   379  	if err != nil {
   380  		output = nil
   381  	} else {
   382  		output.BaseModel = outputObs.BaseModel
   383  		output.Location = outputObs.Location
   384  	}
   385  	return
   386  }
   387  
   388  // GetBucketLocation gets the location of a bucket.
   389  //
   390  // You can use this API to obtain the bucket location.
   391  func (obsClient ObsClient) GetBucketLocation(bucketName string, extensions ...extensionOptions) (output *GetBucketLocationOutput, err error) {
   392  	if obsClient.conf.signature == SignatureObs {
   393  		return obsClient.getBucketLocationObs(bucketName, extensions)
   394  	}
   395  	return obsClient.getBucketLocationS3(bucketName, extensions)
   396  }
   397  
   398  // SetBucketAcl sets the bucket ACL.
   399  //
   400  // You can use this API to set the ACL for a bucket.
   401  func (obsClient ObsClient) SetBucketAcl(input *SetBucketAclInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   402  	if input == nil {
   403  		return nil, errors.New("SetBucketAclInput is nil")
   404  	}
   405  	output = &BaseModel{}
   406  	err = obsClient.doActionWithBucket("SetBucketAcl", HTTP_PUT, input.Bucket, input, output, extensions)
   407  	if err != nil {
   408  		output = nil
   409  	}
   410  	return
   411  }
   412  func (obsClient ObsClient) getBucketACLObs(bucketName string, extensions []extensionOptions) (output *GetBucketAclOutput, err error) {
   413  	output = &GetBucketAclOutput{}
   414  	var outputObs *getBucketACLOutputObs
   415  	outputObs = &getBucketACLOutputObs{}
   416  	err = obsClient.doActionWithBucket("GetBucketAcl", HTTP_GET, bucketName, newSubResourceSerial(SubResourceAcl), outputObs, extensions)
   417  	if err != nil {
   418  		output = nil
   419  	} else {
   420  		output.BaseModel = outputObs.BaseModel
   421  		output.Owner = outputObs.Owner
   422  		output.Grants = make([]Grant, 0, len(outputObs.Grants))
   423  		for _, valGrant := range outputObs.Grants {
   424  			tempOutput := Grant{}
   425  			tempOutput.Delivered = valGrant.Delivered
   426  			tempOutput.Permission = valGrant.Permission
   427  			tempOutput.Grantee.DisplayName = valGrant.Grantee.DisplayName
   428  			tempOutput.Grantee.ID = valGrant.Grantee.ID
   429  			tempOutput.Grantee.Type = valGrant.Grantee.Type
   430  			tempOutput.Grantee.URI = GroupAllUsers
   431  
   432  			output.Grants = append(output.Grants, tempOutput)
   433  		}
   434  	}
   435  	return
   436  }
   437  
   438  // GetBucketAcl gets the bucket ACL.
   439  //
   440  // You can use this API to obtain a bucket ACL.
   441  func (obsClient ObsClient) GetBucketAcl(bucketName string, extensions ...extensionOptions) (output *GetBucketAclOutput, err error) {
   442  	output = &GetBucketAclOutput{}
   443  	if obsClient.conf.signature == SignatureObs {
   444  		return obsClient.getBucketACLObs(bucketName, extensions)
   445  	}
   446  	err = obsClient.doActionWithBucket("GetBucketAcl", HTTP_GET, bucketName, newSubResourceSerial(SubResourceAcl), output, extensions)
   447  	if err != nil {
   448  		output = nil
   449  	}
   450  	return
   451  }
   452  
   453  // SetBucketPolicy sets the bucket policy.
   454  //
   455  // You can use this API to set a bucket policy. If the bucket already has a policy, the
   456  // policy will be overwritten by the one specified in this request.
   457  func (obsClient ObsClient) SetBucketPolicy(input *SetBucketPolicyInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   458  	if input == nil {
   459  		return nil, errors.New("SetBucketPolicy is nil")
   460  	}
   461  	output = &BaseModel{}
   462  	err = obsClient.doActionWithBucket("SetBucketPolicy", HTTP_PUT, input.Bucket, input, output, extensions)
   463  	if err != nil {
   464  		output = nil
   465  	}
   466  	return
   467  }
   468  
   469  // GetBucketPolicy gets the bucket policy.
   470  //
   471  // You can use this API to obtain the policy of a bucket.
   472  func (obsClient ObsClient) GetBucketPolicy(bucketName string, extensions ...extensionOptions) (output *GetBucketPolicyOutput, err error) {
   473  	output = &GetBucketPolicyOutput{}
   474  	err = obsClient.doActionWithBucketV2("GetBucketPolicy", HTTP_GET, bucketName, newSubResourceSerial(SubResourcePolicy), output, extensions)
   475  	if err != nil {
   476  		output = nil
   477  	}
   478  	return
   479  }
   480  
   481  // DeleteBucketPolicy deletes the bucket policy.
   482  //
   483  // You can use this API to delete the policy of a bucket.
   484  func (obsClient ObsClient) DeleteBucketPolicy(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   485  	output = &BaseModel{}
   486  	err = obsClient.doActionWithBucket("DeleteBucketPolicy", HTTP_DELETE, bucketName, newSubResourceSerial(SubResourcePolicy), output, extensions)
   487  	if err != nil {
   488  		output = nil
   489  	}
   490  	return
   491  }
   492  
   493  // SetBucketCors sets CORS rules for a bucket.
   494  //
   495  // You can use this API to set CORS rules for a bucket to allow client browsers to send cross-origin requests.
   496  func (obsClient ObsClient) SetBucketCors(input *SetBucketCorsInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   497  	if input == nil {
   498  		return nil, errors.New("SetBucketCorsInput is nil")
   499  	}
   500  	output = &BaseModel{}
   501  	err = obsClient.doActionWithBucket("SetBucketCors", HTTP_PUT, input.Bucket, input, output, extensions)
   502  	if err != nil {
   503  		output = nil
   504  	}
   505  	return
   506  }
   507  
   508  // GetBucketCors gets CORS rules of a bucket.
   509  //
   510  // You can use this API to obtain the CORS rules of a specified bucket.
   511  func (obsClient ObsClient) GetBucketCors(bucketName string, extensions ...extensionOptions) (output *GetBucketCorsOutput, err error) {
   512  	output = &GetBucketCorsOutput{}
   513  	err = obsClient.doActionWithBucket("GetBucketCors", HTTP_GET, bucketName, newSubResourceSerial(SubResourceCors), output, extensions)
   514  	if err != nil {
   515  		output = nil
   516  	}
   517  	return
   518  }
   519  
   520  // DeleteBucketCors deletes CORS rules of a bucket.
   521  //
   522  // You can use this API to delete the CORS rules of a specified bucket.
   523  func (obsClient ObsClient) DeleteBucketCors(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   524  	output = &BaseModel{}
   525  	err = obsClient.doActionWithBucket("DeleteBucketCors", HTTP_DELETE, bucketName, newSubResourceSerial(SubResourceCors), output, extensions)
   526  	if err != nil {
   527  		output = nil
   528  	}
   529  	return
   530  }
   531  
   532  // SetBucketVersioning sets the versioning status for a bucket.
   533  //
   534  // You can use this API to set the versioning status for a bucket.
   535  func (obsClient ObsClient) SetBucketVersioning(input *SetBucketVersioningInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   536  	if input == nil {
   537  		return nil, errors.New("SetBucketVersioningInput is nil")
   538  	}
   539  	output = &BaseModel{}
   540  	err = obsClient.doActionWithBucket("SetBucketVersioning", HTTP_PUT, input.Bucket, input, output, extensions)
   541  	if err != nil {
   542  		output = nil
   543  	}
   544  	return
   545  }
   546  
   547  // GetBucketVersioning gets the versioning status of a bucket.
   548  //
   549  // You can use this API to obtain the versioning status of a bucket.
   550  func (obsClient ObsClient) GetBucketVersioning(bucketName string, extensions ...extensionOptions) (output *GetBucketVersioningOutput, err error) {
   551  	output = &GetBucketVersioningOutput{}
   552  	err = obsClient.doActionWithBucket("GetBucketVersioning", HTTP_GET, bucketName, newSubResourceSerial(SubResourceVersioning), output, extensions)
   553  	if err != nil {
   554  		output = nil
   555  	}
   556  	return
   557  }
   558  
   559  // SetBucketWebsiteConfiguration sets website hosting for a bucket.
   560  //
   561  // You can use this API to set website hosting for a bucket.
   562  func (obsClient ObsClient) SetBucketWebsiteConfiguration(input *SetBucketWebsiteConfigurationInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   563  	if input == nil {
   564  		return nil, errors.New("SetBucketWebsiteConfigurationInput is nil")
   565  	}
   566  	output = &BaseModel{}
   567  	err = obsClient.doActionWithBucket("SetBucketWebsiteConfiguration", HTTP_PUT, input.Bucket, input, output, extensions)
   568  	if err != nil {
   569  		output = nil
   570  	}
   571  	return
   572  }
   573  
   574  // GetBucketWebsiteConfiguration gets the website hosting settings of a bucket.
   575  //
   576  // You can use this API to obtain the website hosting settings of a bucket.
   577  func (obsClient ObsClient) GetBucketWebsiteConfiguration(bucketName string, extensions ...extensionOptions) (output *GetBucketWebsiteConfigurationOutput, err error) {
   578  	output = &GetBucketWebsiteConfigurationOutput{}
   579  	err = obsClient.doActionWithBucket("GetBucketWebsiteConfiguration", HTTP_GET, bucketName, newSubResourceSerial(SubResourceWebsite), output, extensions)
   580  	if err != nil {
   581  		output = nil
   582  	}
   583  	return
   584  }
   585  
   586  // DeleteBucketWebsiteConfiguration deletes the website hosting settings of a bucket.
   587  //
   588  // You can use this API to delete the website hosting settings of a bucket.
   589  func (obsClient ObsClient) DeleteBucketWebsiteConfiguration(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   590  	output = &BaseModel{}
   591  	err = obsClient.doActionWithBucket("DeleteBucketWebsiteConfiguration", HTTP_DELETE, bucketName, newSubResourceSerial(SubResourceWebsite), output, extensions)
   592  	if err != nil {
   593  		output = nil
   594  	}
   595  	return
   596  }
   597  
   598  // SetBucketLoggingConfiguration sets the bucket logging.
   599  //
   600  // You can use this API to configure access logging for a bucket.
   601  func (obsClient ObsClient) SetBucketLoggingConfiguration(input *SetBucketLoggingConfigurationInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   602  	if input == nil {
   603  		return nil, errors.New("SetBucketLoggingConfigurationInput is nil")
   604  	}
   605  	output = &BaseModel{}
   606  	err = obsClient.doActionWithBucket("SetBucketLoggingConfiguration", HTTP_PUT, input.Bucket, input, output, extensions)
   607  	if err != nil {
   608  		output = nil
   609  	}
   610  	return
   611  }
   612  
   613  // GetBucketLoggingConfiguration gets the logging settings of a bucket.
   614  //
   615  // You can use this API to obtain the access logging settings of a bucket.
   616  func (obsClient ObsClient) GetBucketLoggingConfiguration(bucketName string, extensions ...extensionOptions) (output *GetBucketLoggingConfigurationOutput, err error) {
   617  	output = &GetBucketLoggingConfigurationOutput{}
   618  	err = obsClient.doActionWithBucket("GetBucketLoggingConfiguration", HTTP_GET, bucketName, newSubResourceSerial(SubResourceLogging), output, extensions)
   619  	if err != nil {
   620  		output = nil
   621  	}
   622  	return
   623  }
   624  
   625  // SetBucketLifecycleConfiguration sets lifecycle rules for a bucket.
   626  //
   627  // You can use this API to set lifecycle rules for a bucket, to periodically transit
   628  // storage classes of objects and delete objects in the bucket.
   629  func (obsClient ObsClient) SetBucketLifecycleConfiguration(input *SetBucketLifecycleConfigurationInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   630  	if input == nil {
   631  		return nil, errors.New("SetBucketLifecycleConfigurationInput is nil")
   632  	}
   633  	output = &BaseModel{}
   634  	err = obsClient.doActionWithBucket("SetBucketLifecycleConfiguration", HTTP_PUT, input.Bucket, input, output, extensions)
   635  	if err != nil {
   636  		output = nil
   637  	}
   638  	return
   639  }
   640  
   641  // GetBucketLifecycleConfiguration gets lifecycle rules of a bucket.
   642  //
   643  // You can use this API to obtain the lifecycle rules of a bucket.
   644  func (obsClient ObsClient) GetBucketLifecycleConfiguration(bucketName string, extensions ...extensionOptions) (output *GetBucketLifecycleConfigurationOutput, err error) {
   645  	output = &GetBucketLifecycleConfigurationOutput{}
   646  	err = obsClient.doActionWithBucket("GetBucketLifecycleConfiguration", HTTP_GET, bucketName, newSubResourceSerial(SubResourceLifecycle), output, extensions)
   647  	if err != nil {
   648  		output = nil
   649  	}
   650  	return
   651  }
   652  
   653  // DeleteBucketLifecycleConfiguration deletes lifecycle rules of a bucket.
   654  //
   655  // You can use this API to delete all lifecycle rules of a bucket.
   656  func (obsClient ObsClient) DeleteBucketLifecycleConfiguration(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   657  	output = &BaseModel{}
   658  	err = obsClient.doActionWithBucket("DeleteBucketLifecycleConfiguration", HTTP_DELETE, bucketName, newSubResourceSerial(SubResourceLifecycle), output, extensions)
   659  	if err != nil {
   660  		output = nil
   661  	}
   662  	return
   663  }
   664  
   665  // SetBucketEncryption sets the default server-side encryption for a bucket.
   666  //
   667  // You can use this API to create or update the default server-side encryption for a bucket.
   668  func (obsClient ObsClient) SetBucketEncryption(input *SetBucketEncryptionInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   669  	if input == nil {
   670  		return nil, errors.New("SetBucketEncryptionInput is nil")
   671  	}
   672  	output = &BaseModel{}
   673  	err = obsClient.doActionWithBucket("SetBucketEncryption", HTTP_PUT, input.Bucket, input, output, extensions)
   674  	if err != nil {
   675  		output = nil
   676  	}
   677  	return
   678  }
   679  
   680  // GetBucketEncryption gets the encryption configuration of a bucket.
   681  //
   682  // You can use this API to obtain obtain the encryption configuration of a bucket.
   683  func (obsClient ObsClient) GetBucketEncryption(bucketName string, extensions ...extensionOptions) (output *GetBucketEncryptionOutput, err error) {
   684  	output = &GetBucketEncryptionOutput{}
   685  	err = obsClient.doActionWithBucket("GetBucketEncryption", HTTP_GET, bucketName, newSubResourceSerial(SubResourceEncryption), output, extensions)
   686  	if err != nil {
   687  		output = nil
   688  	}
   689  	return
   690  }
   691  
   692  // DeleteBucketEncryption deletes the encryption configuration of a bucket.
   693  //
   694  // You can use this API to delete the encryption configuration of a bucket.
   695  func (obsClient ObsClient) DeleteBucketEncryption(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   696  	output = &BaseModel{}
   697  	err = obsClient.doActionWithBucket("DeleteBucketEncryption", HTTP_DELETE, bucketName, newSubResourceSerial(SubResourceEncryption), output, extensions)
   698  	if err != nil {
   699  		output = nil
   700  	}
   701  	return
   702  }
   703  
   704  // SetBucketTagging sets bucket tags.
   705  //
   706  // You can use this API to set bucket tags.
   707  func (obsClient ObsClient) SetBucketTagging(input *SetBucketTaggingInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   708  	if input == nil {
   709  		return nil, errors.New("SetBucketTaggingInput is nil")
   710  	}
   711  	output = &BaseModel{}
   712  	err = obsClient.doActionWithBucket("SetBucketTagging", HTTP_PUT, input.Bucket, input, output, extensions)
   713  	if err != nil {
   714  		output = nil
   715  	}
   716  	return
   717  }
   718  
   719  // GetBucketTagging gets bucket tags.
   720  //
   721  // You can use this API to obtain the tags of a specified bucket.
   722  func (obsClient ObsClient) GetBucketTagging(bucketName string, extensions ...extensionOptions) (output *GetBucketTaggingOutput, err error) {
   723  	output = &GetBucketTaggingOutput{}
   724  	err = obsClient.doActionWithBucket("GetBucketTagging", HTTP_GET, bucketName, newSubResourceSerial(SubResourceTagging), output, extensions)
   725  	if err != nil {
   726  		output = nil
   727  	}
   728  	return
   729  }
   730  
   731  // DeleteBucketTagging deletes bucket tags.
   732  //
   733  // You can use this API to delete the tags of a specified bucket.
   734  func (obsClient ObsClient) DeleteBucketTagging(bucketName string, extensions ...extensionOptions) (output *BaseModel, err error) {
   735  	output = &BaseModel{}
   736  	err = obsClient.doActionWithBucket("DeleteBucketTagging", HTTP_DELETE, bucketName, newSubResourceSerial(SubResourceTagging), output, extensions)
   737  	if err != nil {
   738  		output = nil
   739  	}
   740  	return
   741  }
   742  
   743  // SetBucketNotification sets event notification for a bucket.
   744  //
   745  // You can use this API to configure event notification for a bucket. You will be notified of all
   746  // specified operations performed on the bucket.
   747  func (obsClient ObsClient) SetBucketNotification(input *SetBucketNotificationInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   748  	if input == nil {
   749  		return nil, errors.New("SetBucketNotificationInput is nil")
   750  	}
   751  	output = &BaseModel{}
   752  	err = obsClient.doActionWithBucket("SetBucketNotification", HTTP_PUT, input.Bucket, input, output, extensions)
   753  	if err != nil {
   754  		output = nil
   755  	}
   756  	return
   757  }
   758  
   759  // GetBucketNotification gets event notification settings of a bucket.
   760  //
   761  // You can use this API to obtain the event notification configuration of a bucket.
   762  func (obsClient ObsClient) GetBucketNotification(bucketName string, extensions ...extensionOptions) (output *GetBucketNotificationOutput, err error) {
   763  	if obsClient.conf.signature != SignatureObs {
   764  		return obsClient.getBucketNotificationS3(bucketName, extensions)
   765  	}
   766  	output = &GetBucketNotificationOutput{}
   767  	err = obsClient.doActionWithBucket("GetBucketNotification", HTTP_GET, bucketName, newSubResourceSerial(SubResourceNotification), output, extensions)
   768  	if err != nil {
   769  		output = nil
   770  	}
   771  	return
   772  }
   773  
   774  func (obsClient ObsClient) getBucketNotificationS3(bucketName string, extensions []extensionOptions) (output *GetBucketNotificationOutput, err error) {
   775  	outputS3 := &getBucketNotificationOutputS3{}
   776  	err = obsClient.doActionWithBucket("GetBucketNotification", HTTP_GET, bucketName, newSubResourceSerial(SubResourceNotification), outputS3, extensions)
   777  	if err != nil {
   778  		return nil, err
   779  	}
   780  
   781  	output = &GetBucketNotificationOutput{}
   782  	output.BaseModel = outputS3.BaseModel
   783  	topicConfigurations := make([]TopicConfiguration, 0, len(outputS3.TopicConfigurations))
   784  	for _, topicConfigurationS3 := range outputS3.TopicConfigurations {
   785  		topicConfiguration := TopicConfiguration{}
   786  		topicConfiguration.ID = topicConfigurationS3.ID
   787  		topicConfiguration.Topic = topicConfigurationS3.Topic
   788  		topicConfiguration.FilterRules = topicConfigurationS3.FilterRules
   789  
   790  		events := make([]EventType, 0, len(topicConfigurationS3.Events))
   791  		for _, event := range topicConfigurationS3.Events {
   792  			events = append(events, ParseStringToEventType(event))
   793  		}
   794  		topicConfiguration.Events = events
   795  		topicConfigurations = append(topicConfigurations, topicConfiguration)
   796  	}
   797  	output.TopicConfigurations = topicConfigurations
   798  	return
   799  }
   800  
   801  // DeleteObject deletes an object.
   802  //
   803  // You can use this API to delete an object from a specified bucket.
   804  func (obsClient ObsClient) DeleteObject(input *DeleteObjectInput, extensions ...extensionOptions) (output *DeleteObjectOutput, err error) {
   805  	if input == nil {
   806  		return nil, errors.New("DeleteObjectInput is nil")
   807  	}
   808  	output = &DeleteObjectOutput{}
   809  	err = obsClient.doActionWithBucketAndKey("DeleteObject", HTTP_DELETE, input.Bucket, input.Key, input, output, extensions)
   810  	if err != nil {
   811  		output = nil
   812  	} else {
   813  		ParseDeleteObjectOutput(output)
   814  	}
   815  	return
   816  }
   817  
   818  // DeleteObjects deletes objects in a batch.
   819  //
   820  // You can use this API to batch delete objects from a specified bucket.
   821  func (obsClient ObsClient) DeleteObjects(input *DeleteObjectsInput, extensions ...extensionOptions) (output *DeleteObjectsOutput, err error) {
   822  	if input == nil {
   823  		return nil, errors.New("DeleteObjectsInput is nil")
   824  	}
   825  	output = &DeleteObjectsOutput{}
   826  	err = obsClient.doActionWithBucket("DeleteObjects", HTTP_POST, input.Bucket, input, output, extensions)
   827  	if err != nil {
   828  		output = nil
   829  	} else if output.EncodingType == "url" {
   830  		err = decodeDeleteObjectsOutput(output)
   831  		if err != nil {
   832  			doLog(LEVEL_ERROR, "Failed to get DeleteObjectsOutput with error: %v.", err)
   833  			output = nil
   834  		}
   835  	}
   836  	return
   837  }
   838  
   839  // SetObjectAcl sets ACL for an object.
   840  //
   841  // You can use this API to set the ACL for an object in a specified bucket.
   842  func (obsClient ObsClient) SetObjectAcl(input *SetObjectAclInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   843  	if input == nil {
   844  		return nil, errors.New("SetObjectAclInput is nil")
   845  	}
   846  	output = &BaseModel{}
   847  	err = obsClient.doActionWithBucketAndKey("SetObjectAcl", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
   848  	if err != nil {
   849  		output = nil
   850  	}
   851  	return
   852  }
   853  
   854  // GetObjectAcl gets the ACL of an object.
   855  //
   856  // You can use this API to obtain the ACL of an object in a specified bucket.
   857  func (obsClient ObsClient) GetObjectAcl(input *GetObjectAclInput, extensions ...extensionOptions) (output *GetObjectAclOutput, err error) {
   858  	if input == nil {
   859  		return nil, errors.New("GetObjectAclInput is nil")
   860  	}
   861  	output = &GetObjectAclOutput{}
   862  	err = obsClient.doActionWithBucketAndKey("GetObjectAcl", HTTP_GET, input.Bucket, input.Key, input, output, extensions)
   863  	if err != nil {
   864  		output = nil
   865  	} else {
   866  		if versionID, ok := output.ResponseHeaders[HEADER_VERSION_ID]; ok {
   867  			output.VersionId = versionID[0]
   868  		}
   869  	}
   870  	return
   871  }
   872  
   873  // RestoreObject restores an object.
   874  func (obsClient ObsClient) RestoreObject(input *RestoreObjectInput, extensions ...extensionOptions) (output *BaseModel, err error) {
   875  	if input == nil {
   876  		return nil, errors.New("RestoreObjectInput is nil")
   877  	}
   878  	output = &BaseModel{}
   879  	err = obsClient.doActionWithBucketAndKey("RestoreObject", HTTP_POST, input.Bucket, input.Key, input, output, extensions)
   880  	if err != nil {
   881  		output = nil
   882  	}
   883  	return
   884  }
   885  
   886  // GetObjectMetadata gets object metadata.
   887  //
   888  // You can use this API to send a HEAD request to the object of a specified bucket to obtain its metadata.
   889  func (obsClient ObsClient) GetObjectMetadata(input *GetObjectMetadataInput, extensions ...extensionOptions) (output *GetObjectMetadataOutput, err error) {
   890  	if input == nil {
   891  		return nil, errors.New("GetObjectMetadataInput is nil")
   892  	}
   893  	output = &GetObjectMetadataOutput{}
   894  	err = obsClient.doActionWithBucketAndKey("GetObjectMetadata", HTTP_HEAD, input.Bucket, input.Key, input, output, extensions)
   895  	if err != nil {
   896  		output = nil
   897  	} else {
   898  		ParseGetObjectMetadataOutput(output)
   899  	}
   900  	return
   901  }
   902  
   903  // GetObject downloads object.
   904  //
   905  // You can use this API to download an object in a specified bucket.
   906  func (obsClient ObsClient) GetObject(input *GetObjectInput, extensions ...extensionOptions) (output *GetObjectOutput, err error) {
   907  	if input == nil {
   908  		return nil, errors.New("GetObjectInput is nil")
   909  	}
   910  	output = &GetObjectOutput{}
   911  	err = obsClient.doActionWithBucketAndKey("GetObject", HTTP_GET, input.Bucket, input.Key, input, output, extensions)
   912  	if err != nil {
   913  		output = nil
   914  	} else {
   915  		ParseGetObjectOutput(output)
   916  	}
   917  	return
   918  }
   919  
   920  // PutObject uploads an object to the specified bucket.
   921  func (obsClient ObsClient) PutObject(input *PutObjectInput, extensions ...extensionOptions) (output *PutObjectOutput, err error) {
   922  	if input == nil {
   923  		return nil, errors.New("PutObjectInput is nil")
   924  	}
   925  
   926  	if input.ContentType == "" && input.Key != "" {
   927  		if contentType, ok := mimeTypes[strings.ToLower(input.Key[strings.LastIndex(input.Key, ".")+1:])]; ok {
   928  			input.ContentType = contentType
   929  		}
   930  	}
   931  	output = &PutObjectOutput{}
   932  	var repeatable bool
   933  	if input.Body != nil {
   934  		_, repeatable = input.Body.(*strings.Reader)
   935  		if input.ContentLength > 0 {
   936  			input.Body = &readerWrapper{reader: input.Body, totalCount: input.ContentLength}
   937  		}
   938  	}
   939  	if repeatable {
   940  		err = obsClient.doActionWithBucketAndKey("PutObject", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
   941  	} else {
   942  		err = obsClient.doActionWithBucketAndKeyUnRepeatable("PutObject", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
   943  	}
   944  	if err != nil {
   945  		output = nil
   946  	} else {
   947  		ParsePutObjectOutput(output)
   948  	}
   949  	return
   950  }
   951  
   952  func (obsClient ObsClient) getContentType(input *PutObjectInput, sourceFile string) (contentType string) {
   953  	if contentType, ok := mimeTypes[strings.ToLower(input.Key[strings.LastIndex(input.Key, ".")+1:])]; ok {
   954  		return contentType
   955  	}
   956  	if contentType, ok := mimeTypes[strings.ToLower(sourceFile[strings.LastIndex(sourceFile, ".")+1:])]; ok {
   957  		return contentType
   958  	}
   959  	return
   960  }
   961  
   962  func (obsClient ObsClient) isGetContentType(input *PutObjectInput) bool {
   963  	if input.ContentType == "" && input.Key != "" {
   964  		return true
   965  	}
   966  	return false
   967  }
   968  
   969  // PutFile uploads a file to the specified bucket.
   970  func (obsClient ObsClient) PutFile(input *PutFileInput, extensions ...extensionOptions) (output *PutObjectOutput, err error) {
   971  	if input == nil {
   972  		return nil, errors.New("PutFileInput is nil")
   973  	}
   974  
   975  	var body io.Reader
   976  	sourceFile := strings.TrimSpace(input.SourceFile)
   977  	if sourceFile != "" {
   978  		fd, _err := os.Open(sourceFile)
   979  		if _err != nil {
   980  			err = _err
   981  			return nil, err
   982  		}
   983  		defer func() {
   984  			errMsg := fd.Close()
   985  			if errMsg != nil {
   986  				doLog(LEVEL_WARN, "Failed to close file with reason: %v", errMsg)
   987  			}
   988  		}()
   989  
   990  		stat, _err := fd.Stat()
   991  		if _err != nil {
   992  			err = _err
   993  			return nil, err
   994  		}
   995  		fileReaderWrapper := &fileReaderWrapper{filePath: sourceFile}
   996  		fileReaderWrapper.reader = fd
   997  		if input.ContentLength > 0 {
   998  			if input.ContentLength > stat.Size() {
   999  				input.ContentLength = stat.Size()
  1000  			}
  1001  			fileReaderWrapper.totalCount = input.ContentLength
  1002  		} else {
  1003  			fileReaderWrapper.totalCount = stat.Size()
  1004  		}
  1005  		body = fileReaderWrapper
  1006  	}
  1007  
  1008  	_input := &PutObjectInput{}
  1009  	_input.PutObjectBasicInput = input.PutObjectBasicInput
  1010  	_input.Body = body
  1011  
  1012  	if obsClient.isGetContentType(_input) {
  1013  		_input.ContentType = obsClient.getContentType(_input, sourceFile)
  1014  	}
  1015  
  1016  	output = &PutObjectOutput{}
  1017  	err = obsClient.doActionWithBucketAndKey("PutFile", HTTP_PUT, _input.Bucket, _input.Key, _input, output, extensions)
  1018  	if err != nil {
  1019  		output = nil
  1020  	} else {
  1021  		ParsePutObjectOutput(output)
  1022  	}
  1023  	return
  1024  }
  1025  
  1026  // CopyObject creates a copy for an existing object.
  1027  //
  1028  // You can use this API to create a copy for an object in a specified bucket.
  1029  func (obsClient ObsClient) CopyObject(input *CopyObjectInput, extensions ...extensionOptions) (output *CopyObjectOutput, err error) {
  1030  	if input == nil {
  1031  		return nil, errors.New("CopyObjectInput is nil")
  1032  	}
  1033  
  1034  	if strings.TrimSpace(input.CopySourceBucket) == "" {
  1035  		return nil, errors.New("Source bucket is empty")
  1036  	}
  1037  	if strings.TrimSpace(input.CopySourceKey) == "" {
  1038  		return nil, errors.New("Source key is empty")
  1039  	}
  1040  
  1041  	output = &CopyObjectOutput{}
  1042  	err = obsClient.doActionWithBucketAndKey("CopyObject", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
  1043  	if err != nil {
  1044  		output = nil
  1045  	} else {
  1046  		ParseCopyObjectOutput(output)
  1047  	}
  1048  	return
  1049  }
  1050  
  1051  // AbortMultipartUpload aborts a multipart upload in a specified bucket by using the multipart upload ID.
  1052  func (obsClient ObsClient) AbortMultipartUpload(input *AbortMultipartUploadInput, extensions ...extensionOptions) (output *BaseModel, err error) {
  1053  	if input == nil {
  1054  		return nil, errors.New("AbortMultipartUploadInput is nil")
  1055  	}
  1056  	if input.UploadId == "" {
  1057  		return nil, errors.New("UploadId is empty")
  1058  	}
  1059  	output = &BaseModel{}
  1060  	err = obsClient.doActionWithBucketAndKey("AbortMultipartUpload", HTTP_DELETE, input.Bucket, input.Key, input, output, extensions)
  1061  	if err != nil {
  1062  		output = nil
  1063  	}
  1064  	return
  1065  }
  1066  
  1067  // InitiateMultipartUpload initializes a multipart upload.
  1068  func (obsClient ObsClient) InitiateMultipartUpload(input *InitiateMultipartUploadInput, extensions ...extensionOptions) (output *InitiateMultipartUploadOutput, err error) {
  1069  	if input == nil {
  1070  		return nil, errors.New("InitiateMultipartUploadInput is nil")
  1071  	}
  1072  
  1073  	if input.ContentType == "" && input.Key != "" {
  1074  		if contentType, ok := mimeTypes[strings.ToLower(input.Key[strings.LastIndex(input.Key, ".")+1:])]; ok {
  1075  			input.ContentType = contentType
  1076  		}
  1077  	}
  1078  
  1079  	output = &InitiateMultipartUploadOutput{}
  1080  	err = obsClient.doActionWithBucketAndKey("InitiateMultipartUpload", HTTP_POST, input.Bucket, input.Key, input, output, extensions)
  1081  	if err != nil {
  1082  		output = nil
  1083  	} else {
  1084  		ParseInitiateMultipartUploadOutput(output)
  1085  		if output.EncodingType == "url" {
  1086  			err = decodeInitiateMultipartUploadOutput(output)
  1087  			if err != nil {
  1088  				doLog(LEVEL_ERROR, "Failed to get InitiateMultipartUploadOutput with error: %v.", err)
  1089  				output = nil
  1090  			}
  1091  		}
  1092  	}
  1093  	return
  1094  }
  1095  
  1096  // UploadPart uploads a part to a specified bucket by using a specified multipart upload ID.
  1097  //
  1098  // After a multipart upload is initialized, you can use this API to upload a part to a specified bucket
  1099  // by using the multipart upload ID. Except for the last uploaded part whose size ranges from 0 to 5 GB,
  1100  // sizes of the other parts range from 100 KB to 5 GB. The upload part ID ranges from 1 to 10000.
  1101  func (obsClient ObsClient) UploadPart(_input *UploadPartInput, extensions ...extensionOptions) (output *UploadPartOutput, err error) {
  1102  	if _input == nil {
  1103  		return nil, errors.New("UploadPartInput is nil")
  1104  	}
  1105  
  1106  	if _input.UploadId == "" {
  1107  		return nil, errors.New("UploadId is empty")
  1108  	}
  1109  
  1110  	input := &UploadPartInput{}
  1111  	input.Bucket = _input.Bucket
  1112  	input.Key = _input.Key
  1113  	input.PartNumber = _input.PartNumber
  1114  	input.UploadId = _input.UploadId
  1115  	input.ContentMD5 = _input.ContentMD5
  1116  	input.SourceFile = _input.SourceFile
  1117  	input.Offset = _input.Offset
  1118  	input.PartSize = _input.PartSize
  1119  	input.SseHeader = _input.SseHeader
  1120  	input.Body = _input.Body
  1121  
  1122  	output = &UploadPartOutput{}
  1123  	var repeatable bool
  1124  	if input.Body != nil {
  1125  		_, repeatable = input.Body.(*strings.Reader)
  1126  		if _, ok := input.Body.(*readerWrapper); !ok && input.PartSize > 0 {
  1127  			input.Body = &readerWrapper{reader: input.Body, totalCount: input.PartSize}
  1128  		}
  1129  	} else if sourceFile := strings.TrimSpace(input.SourceFile); sourceFile != "" {
  1130  		fd, _err := os.Open(sourceFile)
  1131  		if _err != nil {
  1132  			err = _err
  1133  			return nil, err
  1134  		}
  1135  		defer func() {
  1136  			errMsg := fd.Close()
  1137  			if errMsg != nil {
  1138  				doLog(LEVEL_WARN, "Failed to close file with reason: %v", errMsg)
  1139  			}
  1140  		}()
  1141  
  1142  		stat, _err := fd.Stat()
  1143  		if _err != nil {
  1144  			err = _err
  1145  			return nil, err
  1146  		}
  1147  		fileSize := stat.Size()
  1148  		fileReaderWrapper := &fileReaderWrapper{filePath: sourceFile}
  1149  		fileReaderWrapper.reader = fd
  1150  
  1151  		if input.Offset < 0 || input.Offset > fileSize {
  1152  			input.Offset = 0
  1153  		}
  1154  
  1155  		if input.PartSize <= 0 || input.PartSize > (fileSize-input.Offset) {
  1156  			input.PartSize = fileSize - input.Offset
  1157  		}
  1158  		fileReaderWrapper.totalCount = input.PartSize
  1159  		if _, err = fd.Seek(input.Offset, io.SeekStart); err != nil {
  1160  			return nil, err
  1161  		}
  1162  		input.Body = fileReaderWrapper
  1163  		repeatable = true
  1164  	}
  1165  	if repeatable {
  1166  		err = obsClient.doActionWithBucketAndKey("UploadPart", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
  1167  	} else {
  1168  		err = obsClient.doActionWithBucketAndKeyUnRepeatable("UploadPart", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
  1169  	}
  1170  	if err != nil {
  1171  		output = nil
  1172  	} else {
  1173  		ParseUploadPartOutput(output)
  1174  		output.PartNumber = input.PartNumber
  1175  	}
  1176  	return
  1177  }
  1178  
  1179  // CompleteMultipartUpload combines the uploaded parts in a specified bucket by using the multipart upload ID.
  1180  func (obsClient ObsClient) CompleteMultipartUpload(input *CompleteMultipartUploadInput, extensions ...extensionOptions) (output *CompleteMultipartUploadOutput, err error) {
  1181  	if input == nil {
  1182  		return nil, errors.New("CompleteMultipartUploadInput is nil")
  1183  	}
  1184  
  1185  	if input.UploadId == "" {
  1186  		return nil, errors.New("UploadId is empty")
  1187  	}
  1188  
  1189  	var parts partSlice = input.Parts
  1190  	sort.Sort(parts)
  1191  
  1192  	output = &CompleteMultipartUploadOutput{}
  1193  	err = obsClient.doActionWithBucketAndKey("CompleteMultipartUpload", HTTP_POST, input.Bucket, input.Key, input, output, extensions)
  1194  	if err != nil {
  1195  		output = nil
  1196  	} else {
  1197  		ParseCompleteMultipartUploadOutput(output)
  1198  		if output.EncodingType == "url" {
  1199  			err = decodeCompleteMultipartUploadOutput(output)
  1200  			if err != nil {
  1201  				doLog(LEVEL_ERROR, "Failed to get CompleteMultipartUploadOutput with error: %v.", err)
  1202  				output = nil
  1203  			}
  1204  		}
  1205  	}
  1206  	return
  1207  }
  1208  
  1209  // ListParts lists the uploaded parts in a bucket by using the multipart upload ID.
  1210  func (obsClient ObsClient) ListParts(input *ListPartsInput, extensions ...extensionOptions) (output *ListPartsOutput, err error) {
  1211  	if input == nil {
  1212  		return nil, errors.New("ListPartsInput is nil")
  1213  	}
  1214  	if input.UploadId == "" {
  1215  		return nil, errors.New("UploadId is empty")
  1216  	}
  1217  	output = &ListPartsOutput{}
  1218  	err = obsClient.doActionWithBucketAndKey("ListParts", HTTP_GET, input.Bucket, input.Key, input, output, extensions)
  1219  	if err != nil {
  1220  		output = nil
  1221  	} else if output.EncodingType == "url" {
  1222  		err = decodeListPartsOutput(output)
  1223  		if err != nil {
  1224  			doLog(LEVEL_ERROR, "Failed to get ListPartsOutput with error: %v.", err)
  1225  			output = nil
  1226  		}
  1227  	}
  1228  	return
  1229  }
  1230  
  1231  // CopyPart copy a part to a specified bucket by using a specified multipart upload ID.
  1232  //
  1233  // After a multipart upload is initialized, you can use this API to copy a part to a specified bucket by using the multipart upload ID.
  1234  func (obsClient ObsClient) CopyPart(input *CopyPartInput, extensions ...extensionOptions) (output *CopyPartOutput, err error) {
  1235  	if input == nil {
  1236  		return nil, errors.New("CopyPartInput is nil")
  1237  	}
  1238  	if input.UploadId == "" {
  1239  		return nil, errors.New("UploadId is empty")
  1240  	}
  1241  	if strings.TrimSpace(input.CopySourceBucket) == "" {
  1242  		return nil, errors.New("Source bucket is empty")
  1243  	}
  1244  	if strings.TrimSpace(input.CopySourceKey) == "" {
  1245  		return nil, errors.New("Source key is empty")
  1246  	}
  1247  
  1248  	output = &CopyPartOutput{}
  1249  	err = obsClient.doActionWithBucketAndKey("CopyPart", HTTP_PUT, input.Bucket, input.Key, input, output, extensions)
  1250  	if err != nil {
  1251  		output = nil
  1252  	} else {
  1253  		ParseCopyPartOutput(output)
  1254  		output.PartNumber = input.PartNumber
  1255  	}
  1256  	return
  1257  }
  1258  
  1259  // SetBucketRequestPayment sets requester-pays setting for a bucket.
  1260  func (obsClient ObsClient) SetBucketRequestPayment(input *SetBucketRequestPaymentInput, extensions ...extensionOptions) (output *BaseModel, err error) {
  1261  	if input == nil {
  1262  		return nil, errors.New("SetBucketRequestPaymentInput is nil")
  1263  	}
  1264  	output = &BaseModel{}
  1265  	err = obsClient.doActionWithBucket("SetBucketRequestPayment", HTTP_PUT, input.Bucket, input, output, extensions)
  1266  	if err != nil {
  1267  		output = nil
  1268  	}
  1269  	return
  1270  }
  1271  
  1272  // GetBucketRequestPayment gets requester-pays setting of a bucket.
  1273  func (obsClient ObsClient) GetBucketRequestPayment(bucketName string, extensions ...extensionOptions) (output *GetBucketRequestPaymentOutput, err error) {
  1274  	output = &GetBucketRequestPaymentOutput{}
  1275  	err = obsClient.doActionWithBucket("GetBucketRequestPayment", HTTP_GET, bucketName, newSubResourceSerial(SubResourceRequestPayment), output, extensions)
  1276  	if err != nil {
  1277  		output = nil
  1278  	}
  1279  	return
  1280  }
  1281  
  1282  // UploadFile resume uploads.
  1283  //
  1284  // This API is an encapsulated and enhanced version of multipart upload, and aims to eliminate large file
  1285  // upload failures caused by poor network conditions and program breakdowns.
  1286  func (obsClient ObsClient) UploadFile(input *UploadFileInput, extensions ...extensionOptions) (output *CompleteMultipartUploadOutput, err error) {
  1287  	if input.EnableCheckpoint && input.CheckpointFile == "" {
  1288  		input.CheckpointFile = input.UploadFile + ".uploadfile_record"
  1289  	}
  1290  
  1291  	if input.TaskNum <= 0 {
  1292  		input.TaskNum = 1
  1293  	}
  1294  	if input.PartSize < MIN_PART_SIZE {
  1295  		input.PartSize = MIN_PART_SIZE
  1296  	} else if input.PartSize > MAX_PART_SIZE {
  1297  		input.PartSize = MAX_PART_SIZE
  1298  	}
  1299  
  1300  	output, err = obsClient.resumeUpload(input, extensions)
  1301  	return
  1302  }
  1303  
  1304  // DownloadFile resume downloads.
  1305  //
  1306  // This API is an encapsulated and enhanced version of partial download, and aims to eliminate large file
  1307  // download failures caused by poor network conditions and program breakdowns.
  1308  func (obsClient ObsClient) DownloadFile(input *DownloadFileInput, extensions ...extensionOptions) (output *GetObjectMetadataOutput, err error) {
  1309  	if input.DownloadFile == "" {
  1310  		input.DownloadFile = input.Key
  1311  	}
  1312  
  1313  	if input.EnableCheckpoint && input.CheckpointFile == "" {
  1314  		input.CheckpointFile = input.DownloadFile + ".downloadfile_record"
  1315  	}
  1316  
  1317  	if input.TaskNum <= 0 {
  1318  		input.TaskNum = 1
  1319  	}
  1320  	if input.PartSize <= 0 {
  1321  		input.PartSize = DEFAULT_PART_SIZE
  1322  	}
  1323  
  1324  	output, err = obsClient.resumeDownload(input, extensions)
  1325  	return
  1326  }
  1327  
  1328  // SetBucketFetchPolicy sets the bucket fetch policy.
  1329  //
  1330  // You can use this API to set a bucket fetch policy.
  1331  func (obsClient ObsClient) SetBucketFetchPolicy(input *SetBucketFetchPolicyInput, extensions ...extensionOptions) (output *BaseModel, err error) {
  1332  	if input == nil {
  1333  		return nil, errors.New("SetBucketFetchPolicyInput is nil")
  1334  	}
  1335  	if strings.TrimSpace(string(input.Status)) == "" {
  1336  		return nil, errors.New("Fetch policy status is empty")
  1337  	}
  1338  	if strings.TrimSpace(input.Agency) == "" {
  1339  		return nil, errors.New("Fetch policy agency is empty")
  1340  	}
  1341  	output = &BaseModel{}
  1342  	err = obsClient.doActionWithBucketAndKey("SetBucketFetchPolicy", HTTP_PUT, input.Bucket, string(objectKeyExtensionPolicy), input, output, extensions)
  1343  	if err != nil {
  1344  		output = nil
  1345  	}
  1346  	return
  1347  }
  1348  
  1349  // GetBucketFetchPolicy gets the bucket fetch policy.
  1350  //
  1351  // You can use this API to obtain the fetch policy of a bucket.
  1352  func (obsClient ObsClient) GetBucketFetchPolicy(input *GetBucketFetchPolicyInput, extensions ...extensionOptions) (output *GetBucketFetchPolicyOutput, err error) {
  1353  	if input == nil {
  1354  		return nil, errors.New("GetBucketFetchPolicyInput is nil")
  1355  	}
  1356  	output = &GetBucketFetchPolicyOutput{}
  1357  	err = obsClient.doActionWithBucketAndKeyV2("GetBucketFetchPolicy", HTTP_GET, input.Bucket, string(objectKeyExtensionPolicy), input, output, extensions)
  1358  	if err != nil {
  1359  		output = nil
  1360  	}
  1361  	return
  1362  }
  1363  
  1364  // DeleteBucketFetchPolicy deletes the bucket fetch policy.
  1365  //
  1366  // You can use this API to delete the fetch policy of a bucket.
  1367  func (obsClient ObsClient) DeleteBucketFetchPolicy(input *DeleteBucketFetchPolicyInput, extensions ...extensionOptions) (output *BaseModel, err error) {
  1368  	if input == nil {
  1369  		return nil, errors.New("DeleteBucketFetchPolicyInput is nil")
  1370  	}
  1371  	output = &BaseModel{}
  1372  	err = obsClient.doActionWithBucketAndKey("DeleteBucketFetchPolicy", HTTP_DELETE, input.Bucket, string(objectKeyExtensionPolicy), input, output, extensions)
  1373  	if err != nil {
  1374  		output = nil
  1375  	}
  1376  	return
  1377  }
  1378  
  1379  // SetBucketFetchJob sets the bucket fetch job.
  1380  //
  1381  // You can use this API to set a bucket fetch job.
  1382  func (obsClient ObsClient) SetBucketFetchJob(input *SetBucketFetchJobInput, extensions ...extensionOptions) (output *SetBucketFetchJobOutput, err error) {
  1383  	if input == nil {
  1384  		return nil, errors.New("SetBucketFetchJobInput is nil")
  1385  	}
  1386  	if strings.TrimSpace(input.URL) == "" {
  1387  		return nil, errors.New("URL is empty")
  1388  	}
  1389  	output = &SetBucketFetchJobOutput{}
  1390  	err = obsClient.doActionWithBucketAndKeyV2("SetBucketFetchJob", HTTP_POST, input.Bucket, string(objectKeyAsyncFetchJob), input, output, extensions)
  1391  	if err != nil {
  1392  		output = nil
  1393  	}
  1394  	return
  1395  }
  1396  
  1397  // GetBucketFetchJob gets the bucket fetch job.
  1398  //
  1399  // You can use this API to obtain the fetch job of a bucket.
  1400  func (obsClient ObsClient) GetBucketFetchJob(input *GetBucketFetchJobInput, extensions ...extensionOptions) (output *GetBucketFetchJobOutput, err error) {
  1401  	if input == nil {
  1402  		return nil, errors.New("GetBucketFetchJobInput is nil")
  1403  	}
  1404  	if strings.TrimSpace(input.JobID) == "" {
  1405  		return nil, errors.New("JobID is empty")
  1406  	}
  1407  	output = &GetBucketFetchJobOutput{}
  1408  	err = obsClient.doActionWithBucketAndKeyV2("GetBucketFetchJob", HTTP_GET, input.Bucket, string(objectKeyAsyncFetchJob)+"/"+input.JobID, input, output, extensions)
  1409  	if err != nil {
  1410  		output = nil
  1411  	}
  1412  	return
  1413  }