1// +------------------------------------------------------------------------- 2// | Copyright (C) 2016 Yunify, Inc. 3// +------------------------------------------------------------------------- 4// | Licensed under the Apache License, Version 2.0 (the "License"); 5// | you may not use this work except in compliance with the License. 6// | You may obtain a copy of the License in the LICENSE file, or at: 7// | 8// | http://www.apache.org/licenses/LICENSE-2.0 9// | 10// | Unless required by applicable law or agreed to in writing, software 11// | distributed under the License is distributed on an "AS IS" BASIS, 12// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// | See the License for the specific language governing permissions and 14// | limitations under the License. 15// +------------------------------------------------------------------------- 16 17package service 18 19import ( 20 "fmt" 21 "io" 22 "net/http" 23 "strings" 24 "time" 25 26 "github.com/yunify/qingstor-sdk-go/v3/config" 27 "github.com/yunify/qingstor-sdk-go/v3/request" 28 "github.com/yunify/qingstor-sdk-go/v3/request/data" 29 "github.com/yunify/qingstor-sdk-go/v3/request/errors" 30 "github.com/yunify/qingstor-sdk-go/v3/utils" 31) 32 33var _ fmt.State 34var _ io.Reader 35var _ http.Header 36var _ strings.Reader 37var _ time.Time 38var _ config.Config 39var _ utils.Conn 40 41// AbortMultipartUpload does Abort multipart upload. 42// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/abort_multipart_upload.html 43func (s *Bucket) AbortMultipartUpload(objectKey string, input *AbortMultipartUploadInput) (*AbortMultipartUploadOutput, error) { 44 r, x, err := s.AbortMultipartUploadRequest(objectKey, input) 45 46 if err != nil { 47 return x, err 48 } 49 50 err = r.Send() 51 if err != nil { 52 return nil, err 53 } 54 55 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 56 x.RequestID = &requestID 57 58 return x, err 59} 60 61// AbortMultipartUploadRequest creates request and output object of AbortMultipartUpload. 62func (s *Bucket) AbortMultipartUploadRequest(objectKey string, input *AbortMultipartUploadInput) (*request.Request, *AbortMultipartUploadOutput, error) { 63 64 if input == nil { 65 input = &AbortMultipartUploadInput{} 66 } 67 68 properties := *s.Properties 69 70 properties.ObjectKey = &objectKey 71 72 o := &data.Operation{ 73 Config: s.Config, 74 Properties: &properties, 75 APIName: "Abort Multipart Upload", 76 RequestMethod: "DELETE", 77 RequestURI: "/<bucket-name>/<object-key>", 78 StatusCodes: []int{ 79 204, // Object multipart deleted 80 }, 81 } 82 83 x := &AbortMultipartUploadOutput{} 84 r, err := request.New(o, input, x) 85 if err != nil { 86 return nil, nil, err 87 } 88 89 return r, x, nil 90} 91 92// AbortMultipartUploadInput presents input for AbortMultipartUpload. 93type AbortMultipartUploadInput struct { 94 // Object multipart upload ID 95 UploadID *string `json:"upload_id" name:"upload_id" location:"query"` // Required 96 97} 98 99// Validate validates the input for AbortMultipartUpload. 100func (v *AbortMultipartUploadInput) Validate() error { 101 102 if v.UploadID == nil { 103 return errors.ParameterRequiredError{ 104 ParameterName: "UploadID", 105 ParentName: "AbortMultipartUploadInput", 106 } 107 } 108 109 return nil 110} 111 112// AbortMultipartUploadOutput presents output for AbortMultipartUpload. 113type AbortMultipartUploadOutput struct { 114 StatusCode *int `location:"statusCode"` 115 116 RequestID *string `location:"requestID"` 117} 118 119// CompleteMultipartUpload does Complete multipart upload. 120// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/complete_multipart_upload.html 121func (s *Bucket) CompleteMultipartUpload(objectKey string, input *CompleteMultipartUploadInput) (*CompleteMultipartUploadOutput, error) { 122 r, x, err := s.CompleteMultipartUploadRequest(objectKey, input) 123 124 if err != nil { 125 return x, err 126 } 127 128 err = r.Send() 129 if err != nil { 130 return nil, err 131 } 132 133 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 134 x.RequestID = &requestID 135 136 return x, err 137} 138 139// CompleteMultipartUploadRequest creates request and output object of CompleteMultipartUpload. 140func (s *Bucket) CompleteMultipartUploadRequest(objectKey string, input *CompleteMultipartUploadInput) (*request.Request, *CompleteMultipartUploadOutput, error) { 141 142 if input == nil { 143 input = &CompleteMultipartUploadInput{} 144 } 145 146 properties := *s.Properties 147 148 properties.ObjectKey = &objectKey 149 150 o := &data.Operation{ 151 Config: s.Config, 152 Properties: &properties, 153 APIName: "Complete multipart upload", 154 RequestMethod: "POST", 155 RequestURI: "/<bucket-name>/<object-key>", 156 StatusCodes: []int{ 157 201, // Object created 158 }, 159 } 160 161 x := &CompleteMultipartUploadOutput{} 162 r, err := request.New(o, input, x) 163 if err != nil { 164 return nil, nil, err 165 } 166 167 return r, x, nil 168} 169 170// CompleteMultipartUploadInput presents input for CompleteMultipartUpload. 171type CompleteMultipartUploadInput struct { 172 // Object multipart upload ID 173 UploadID *string `json:"upload_id" name:"upload_id" location:"query"` // Required 174 175 // MD5sum of the object part 176 ETag *string `json:"ETag,omitempty" name:"ETag" location:"headers"` 177 // Encryption algorithm of the object 178 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 179 // Encryption key of the object 180 XQSEncryptionCustomerKey *string `json:"X-QS-Encryption-Customer-Key,omitempty" name:"X-QS-Encryption-Customer-Key" location:"headers"` 181 // MD5sum of encryption key 182 XQSEncryptionCustomerKeyMD5 *string `json:"X-QS-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Encryption-Customer-Key-MD5" location:"headers"` 183 184 // Object parts 185 ObjectParts []*ObjectPartType `json:"object_parts" name:"object_parts" location:"elements"` // Required 186 187} 188 189// Validate validates the input for CompleteMultipartUpload. 190func (v *CompleteMultipartUploadInput) Validate() error { 191 192 if v.UploadID == nil { 193 return errors.ParameterRequiredError{ 194 ParameterName: "UploadID", 195 ParentName: "CompleteMultipartUploadInput", 196 } 197 } 198 199 if len(v.ObjectParts) == 0 { 200 return errors.ParameterRequiredError{ 201 ParameterName: "ObjectParts", 202 ParentName: "CompleteMultipartUploadInput", 203 } 204 } 205 206 if len(v.ObjectParts) > 0 { 207 for _, property := range v.ObjectParts { 208 if err := property.Validate(); err != nil { 209 return err 210 } 211 } 212 } 213 214 return nil 215} 216 217// CompleteMultipartUploadOutput presents output for CompleteMultipartUpload. 218type CompleteMultipartUploadOutput struct { 219 StatusCode *int `location:"statusCode"` 220 221 RequestID *string `location:"requestID"` 222 223 // Encryption algorithm of the object 224 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 225} 226 227// DeleteObject does Delete the object. 228// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/delete.html 229func (s *Bucket) DeleteObject(objectKey string) (*DeleteObjectOutput, error) { 230 r, x, err := s.DeleteObjectRequest(objectKey) 231 232 if err != nil { 233 return x, err 234 } 235 236 err = r.Send() 237 if err != nil { 238 return nil, err 239 } 240 241 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 242 x.RequestID = &requestID 243 244 return x, err 245} 246 247// DeleteObjectRequest creates request and output object of DeleteObject. 248func (s *Bucket) DeleteObjectRequest(objectKey string) (*request.Request, *DeleteObjectOutput, error) { 249 250 properties := *s.Properties 251 252 properties.ObjectKey = &objectKey 253 254 o := &data.Operation{ 255 Config: s.Config, 256 Properties: &properties, 257 APIName: "DELETE Object", 258 RequestMethod: "DELETE", 259 RequestURI: "/<bucket-name>/<object-key>", 260 StatusCodes: []int{ 261 204, // Object deleted 262 }, 263 } 264 265 x := &DeleteObjectOutput{} 266 r, err := request.New(o, nil, x) 267 if err != nil { 268 return nil, nil, err 269 } 270 271 return r, x, nil 272} 273 274// DeleteObjectOutput presents output for DeleteObject. 275type DeleteObjectOutput struct { 276 StatusCode *int `location:"statusCode"` 277 278 RequestID *string `location:"requestID"` 279} 280 281// GetObject does Retrieve the object. 282// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/get.html 283func (s *Bucket) GetObject(objectKey string, input *GetObjectInput) (*GetObjectOutput, error) { 284 r, x, err := s.GetObjectRequest(objectKey, input) 285 286 if err != nil { 287 return x, err 288 } 289 290 err = r.Send() 291 if err != nil { 292 return nil, err 293 } 294 295 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 296 x.RequestID = &requestID 297 298 return x, err 299} 300 301// GetObjectRequest creates request and output object of GetObject. 302func (s *Bucket) GetObjectRequest(objectKey string, input *GetObjectInput) (*request.Request, *GetObjectOutput, error) { 303 304 if input == nil { 305 input = &GetObjectInput{} 306 } 307 308 properties := *s.Properties 309 310 properties.ObjectKey = &objectKey 311 312 o := &data.Operation{ 313 Config: s.Config, 314 Properties: &properties, 315 APIName: "GET Object", 316 RequestMethod: "GET", 317 RequestURI: "/<bucket-name>/<object-key>", 318 StatusCodes: []int{ 319 200, // OK 320 206, // Partial content 321 304, // Not modified 322 412, // Precondition failed 323 }, 324 } 325 326 x := &GetObjectOutput{} 327 r, err := request.New(o, input, x) 328 if err != nil { 329 return nil, nil, err 330 } 331 332 return r, x, nil 333} 334 335// GetObjectInput presents input for GetObject. 336type GetObjectInput struct { 337 // Specified the Cache-Control response header 338 ResponseCacheControl *string `json:"response-cache-control,omitempty" name:"response-cache-control" location:"query"` 339 // Specified the Content-Disposition response header 340 ResponseContentDisposition *string `json:"response-content-disposition,omitempty" name:"response-content-disposition" location:"query"` 341 // Specified the Content-Encoding response header 342 ResponseContentEncoding *string `json:"response-content-encoding,omitempty" name:"response-content-encoding" location:"query"` 343 // Specified the Content-Language response header 344 ResponseContentLanguage *string `json:"response-content-language,omitempty" name:"response-content-language" location:"query"` 345 // Specified the Content-Type response header 346 ResponseContentType *string `json:"response-content-type,omitempty" name:"response-content-type" location:"query"` 347 // Specified the Expires response header 348 ResponseExpires *string `json:"response-expires,omitempty" name:"response-expires" location:"query"` 349 350 // Check whether the ETag matches 351 IfMatch *string `json:"If-Match,omitempty" name:"If-Match" location:"headers"` 352 // Check whether the object has been modified 353 IfModifiedSince *time.Time `json:"If-Modified-Since,omitempty" name:"If-Modified-Since" format:"RFC 822" location:"headers"` 354 // Check whether the ETag does not match 355 IfNoneMatch *string `json:"If-None-Match,omitempty" name:"If-None-Match" location:"headers"` 356 // Check whether the object has not been modified 357 IfUnmodifiedSince *time.Time `json:"If-Unmodified-Since,omitempty" name:"If-Unmodified-Since" format:"RFC 822" location:"headers"` 358 // Specified range of the object 359 Range *string `json:"Range,omitempty" name:"Range" location:"headers"` 360 // Encryption algorithm of the object 361 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 362 // Encryption key of the object 363 XQSEncryptionCustomerKey *string `json:"X-QS-Encryption-Customer-Key,omitempty" name:"X-QS-Encryption-Customer-Key" location:"headers"` 364 // MD5sum of encryption key 365 XQSEncryptionCustomerKeyMD5 *string `json:"X-QS-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Encryption-Customer-Key-MD5" location:"headers"` 366} 367 368// Validate validates the input for GetObject. 369func (v *GetObjectInput) Validate() error { 370 371 return nil 372} 373 374// GetObjectOutput presents output for GetObject. 375type GetObjectOutput struct { 376 StatusCode *int `location:"statusCode"` 377 378 RequestID *string `location:"requestID"` 379 380 // The response body 381 Body io.ReadCloser `location:"body"` 382 383 // The Cache-Control general-header field is used to specify directives for caching mechanisms in both requests and responses. 384 CacheControl *string `json:"Cache-Control,omitempty" name:"Cache-Control" location:"headers"` 385 // In a multipart/form-data body, the HTTP Content-Disposition general header is a header that can be used on the subpart of a multipart body to give information about the field it applies to. 386 ContentDisposition *string `json:"Content-Disposition,omitempty" name:"Content-Disposition" location:"headers"` 387 // The Content-Encoding entity header is used to compress the media-type. 388 ContentEncoding *string `json:"Content-Encoding,omitempty" name:"Content-Encoding" location:"headers"` 389 // The Content-Language entity header is used to describe the language(s) intended for the audience. 390 ContentLanguage *string `json:"Content-Language,omitempty" name:"Content-Language" location:"headers"` 391 // Object content length 392 ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"` 393 // Range of response data content 394 ContentRange *string `json:"Content-Range,omitempty" name:"Content-Range" location:"headers"` 395 // The Content-Type entity header is used to indicate the media type of the resource. 396 ContentType *string `json:"Content-Type,omitempty" name:"Content-Type" location:"headers"` 397 // MD5sum of the object 398 ETag *string `json:"ETag,omitempty" name:"ETag" location:"headers"` 399 // The Expires header contains the date/time after which the response is considered stale. 400 Expires *string `json:"Expires,omitempty" name:"Expires" location:"headers"` 401 LastModified *time.Time `json:"Last-Modified,omitempty" name:"Last-Modified" format:"RFC 822" location:"headers"` 402 // Encryption algorithm of the object 403 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 404 // User-defined metadata 405 XQSMetaData *map[string]string `json:"X-QS-MetaData,omitempty" name:"X-QS-MetaData" location:"headers"` 406 // Storage class of the object 407 XQSStorageClass *string `json:"X-QS-Storage-Class,omitempty" name:"X-QS-Storage-Class" location:"headers"` 408} 409 410// Close will close the underlay body. 411func (o *GetObjectOutput) Close() (err error) { 412 if o.Body != nil { 413 return o.Body.Close() 414 } 415 return 416} 417 418// HeadObject does Check whether the object exists and available. 419// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/head.html 420func (s *Bucket) HeadObject(objectKey string, input *HeadObjectInput) (*HeadObjectOutput, error) { 421 r, x, err := s.HeadObjectRequest(objectKey, input) 422 423 if err != nil { 424 return x, err 425 } 426 427 err = r.Send() 428 if err != nil { 429 return nil, err 430 } 431 432 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 433 x.RequestID = &requestID 434 435 return x, err 436} 437 438// HeadObjectRequest creates request and output object of HeadObject. 439func (s *Bucket) HeadObjectRequest(objectKey string, input *HeadObjectInput) (*request.Request, *HeadObjectOutput, error) { 440 441 if input == nil { 442 input = &HeadObjectInput{} 443 } 444 445 properties := *s.Properties 446 447 properties.ObjectKey = &objectKey 448 449 o := &data.Operation{ 450 Config: s.Config, 451 Properties: &properties, 452 APIName: "HEAD Object", 453 RequestMethod: "HEAD", 454 RequestURI: "/<bucket-name>/<object-key>", 455 StatusCodes: []int{ 456 200, // OK 457 }, 458 } 459 460 x := &HeadObjectOutput{} 461 r, err := request.New(o, input, x) 462 if err != nil { 463 return nil, nil, err 464 } 465 466 return r, x, nil 467} 468 469// HeadObjectInput presents input for HeadObject. 470type HeadObjectInput struct { 471 // Check whether the ETag matches 472 IfMatch *string `json:"If-Match,omitempty" name:"If-Match" location:"headers"` 473 // Check whether the object has been modified 474 IfModifiedSince *time.Time `json:"If-Modified-Since,omitempty" name:"If-Modified-Since" format:"RFC 822" location:"headers"` 475 // Check whether the ETag does not match 476 IfNoneMatch *string `json:"If-None-Match,omitempty" name:"If-None-Match" location:"headers"` 477 // Check whether the object has not been modified 478 IfUnmodifiedSince *time.Time `json:"If-Unmodified-Since,omitempty" name:"If-Unmodified-Since" format:"RFC 822" location:"headers"` 479 // Encryption algorithm of the object 480 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 481 // Encryption key of the object 482 XQSEncryptionCustomerKey *string `json:"X-QS-Encryption-Customer-Key,omitempty" name:"X-QS-Encryption-Customer-Key" location:"headers"` 483 // MD5sum of encryption key 484 XQSEncryptionCustomerKeyMD5 *string `json:"X-QS-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Encryption-Customer-Key-MD5" location:"headers"` 485} 486 487// Validate validates the input for HeadObject. 488func (v *HeadObjectInput) Validate() error { 489 490 return nil 491} 492 493// HeadObjectOutput presents output for HeadObject. 494type HeadObjectOutput struct { 495 StatusCode *int `location:"statusCode"` 496 497 RequestID *string `location:"requestID"` 498 499 // Object content length 500 ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"` 501 // Object content type 502 ContentType *string `json:"Content-Type,omitempty" name:"Content-Type" location:"headers"` 503 // MD5sum of the object 504 ETag *string `json:"ETag,omitempty" name:"ETag" location:"headers"` 505 LastModified *time.Time `json:"Last-Modified,omitempty" name:"Last-Modified" format:"RFC 822" location:"headers"` 506 // Encryption algorithm of the object 507 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 508 // User-defined metadata 509 XQSMetaData *map[string]string `json:"X-QS-MetaData,omitempty" name:"X-QS-MetaData" location:"headers"` 510 // Storage class of the object 511 XQSStorageClass *string `json:"X-QS-Storage-Class,omitempty" name:"X-QS-Storage-Class" location:"headers"` 512} 513 514// ImageProcess does Image process with the action on the object 515// Documentation URL: https://docs.qingcloud.com/qingstor/data_process/image_process/index.html 516func (s *Bucket) ImageProcess(objectKey string, input *ImageProcessInput) (*ImageProcessOutput, error) { 517 r, x, err := s.ImageProcessRequest(objectKey, input) 518 519 if err != nil { 520 return x, err 521 } 522 523 err = r.Send() 524 if err != nil { 525 return nil, err 526 } 527 528 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 529 x.RequestID = &requestID 530 531 return x, err 532} 533 534// ImageProcessRequest creates request and output object of ImageProcess. 535func (s *Bucket) ImageProcessRequest(objectKey string, input *ImageProcessInput) (*request.Request, *ImageProcessOutput, error) { 536 537 if input == nil { 538 input = &ImageProcessInput{} 539 } 540 541 properties := *s.Properties 542 543 properties.ObjectKey = &objectKey 544 545 o := &data.Operation{ 546 Config: s.Config, 547 Properties: &properties, 548 APIName: "Image Process", 549 RequestMethod: "GET", 550 RequestURI: "/<bucket-name>/<object-key>?image", 551 StatusCodes: []int{ 552 200, // OK 553 304, // Not modified 554 }, 555 } 556 557 x := &ImageProcessOutput{} 558 r, err := request.New(o, input, x) 559 if err != nil { 560 return nil, nil, err 561 } 562 563 return r, x, nil 564} 565 566// ImageProcessInput presents input for ImageProcess. 567type ImageProcessInput struct { 568 // Image process action 569 Action *string `json:"action" name:"action" location:"query"` // Required 570 // Specified the Cache-Control response header 571 ResponseCacheControl *string `json:"response-cache-control,omitempty" name:"response-cache-control" location:"query"` 572 // Specified the Content-Disposition response header 573 ResponseContentDisposition *string `json:"response-content-disposition,omitempty" name:"response-content-disposition" location:"query"` 574 // Specified the Content-Encoding response header 575 ResponseContentEncoding *string `json:"response-content-encoding,omitempty" name:"response-content-encoding" location:"query"` 576 // Specified the Content-Language response header 577 ResponseContentLanguage *string `json:"response-content-language,omitempty" name:"response-content-language" location:"query"` 578 // Specified the Content-Type response header 579 ResponseContentType *string `json:"response-content-type,omitempty" name:"response-content-type" location:"query"` 580 // Specified the Expires response header 581 ResponseExpires *string `json:"response-expires,omitempty" name:"response-expires" location:"query"` 582 583 // Check whether the object has been modified 584 IfModifiedSince *time.Time `json:"If-Modified-Since,omitempty" name:"If-Modified-Since" format:"RFC 822" location:"headers"` 585} 586 587// Validate validates the input for ImageProcess. 588func (v *ImageProcessInput) Validate() error { 589 590 if v.Action == nil { 591 return errors.ParameterRequiredError{ 592 ParameterName: "Action", 593 ParentName: "ImageProcessInput", 594 } 595 } 596 597 return nil 598} 599 600// ImageProcessOutput presents output for ImageProcess. 601type ImageProcessOutput struct { 602 StatusCode *int `location:"statusCode"` 603 604 RequestID *string `location:"requestID"` 605 606 // The response body 607 Body io.ReadCloser `location:"body"` 608 609 // Object content length 610 ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"` 611} 612 613// Close will close the underlay body. 614func (o *ImageProcessOutput) Close() (err error) { 615 if o.Body != nil { 616 return o.Body.Close() 617 } 618 return 619} 620 621// InitiateMultipartUpload does Initial multipart upload on the object. 622// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/initiate_multipart_upload.html 623func (s *Bucket) InitiateMultipartUpload(objectKey string, input *InitiateMultipartUploadInput) (*InitiateMultipartUploadOutput, error) { 624 r, x, err := s.InitiateMultipartUploadRequest(objectKey, input) 625 626 if err != nil { 627 return x, err 628 } 629 630 err = r.Send() 631 if err != nil { 632 return nil, err 633 } 634 635 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 636 x.RequestID = &requestID 637 638 return x, err 639} 640 641// InitiateMultipartUploadRequest creates request and output object of InitiateMultipartUpload. 642func (s *Bucket) InitiateMultipartUploadRequest(objectKey string, input *InitiateMultipartUploadInput) (*request.Request, *InitiateMultipartUploadOutput, error) { 643 644 if input == nil { 645 input = &InitiateMultipartUploadInput{} 646 } 647 648 properties := *s.Properties 649 650 properties.ObjectKey = &objectKey 651 652 o := &data.Operation{ 653 Config: s.Config, 654 Properties: &properties, 655 APIName: "Initiate Multipart Upload", 656 RequestMethod: "POST", 657 RequestURI: "/<bucket-name>/<object-key>?uploads", 658 StatusCodes: []int{ 659 200, // OK 660 }, 661 } 662 663 x := &InitiateMultipartUploadOutput{} 664 r, err := request.New(o, input, x) 665 if err != nil { 666 return nil, nil, err 667 } 668 669 return r, x, nil 670} 671 672// InitiateMultipartUploadInput presents input for InitiateMultipartUpload. 673type InitiateMultipartUploadInput struct { 674 // Object content type 675 ContentType *string `json:"Content-Type,omitempty" name:"Content-Type" location:"headers"` 676 // Encryption algorithm of the object 677 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 678 // Encryption key of the object 679 XQSEncryptionCustomerKey *string `json:"X-QS-Encryption-Customer-Key,omitempty" name:"X-QS-Encryption-Customer-Key" location:"headers"` 680 // MD5sum of encryption key 681 XQSEncryptionCustomerKeyMD5 *string `json:"X-QS-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Encryption-Customer-Key-MD5" location:"headers"` 682 // User-defined metadata 683 XQSMetaData *map[string]string `json:"X-QS-MetaData,omitempty" name:"X-QS-MetaData" location:"headers"` 684 // Specify the storage class for object 685 // XQSStorageClass's available values: STANDARD, STANDARD_IA 686 XQSStorageClass *string `json:"X-QS-Storage-Class,omitempty" name:"X-QS-Storage-Class" location:"headers"` 687} 688 689// Validate validates the input for InitiateMultipartUpload. 690func (v *InitiateMultipartUploadInput) Validate() error { 691 692 if v.XQSMetaData != nil { 693 XQSMetaDataerr := utils.IsMetaDataValid(v.XQSMetaData) 694 if XQSMetaDataerr != nil { 695 return XQSMetaDataerr 696 } 697 } 698 699 if v.XQSStorageClass != nil { 700 xQSStorageClassValidValues := []string{"STANDARD", "STANDARD_IA"} 701 xQSStorageClassParameterValue := fmt.Sprint(*v.XQSStorageClass) 702 703 xQSStorageClassIsValid := false 704 for _, value := range xQSStorageClassValidValues { 705 if value == xQSStorageClassParameterValue { 706 xQSStorageClassIsValid = true 707 } 708 } 709 710 if !xQSStorageClassIsValid { 711 return errors.ParameterValueNotAllowedError{ 712 ParameterName: "XQSStorageClass", 713 ParameterValue: xQSStorageClassParameterValue, 714 AllowedValues: xQSStorageClassValidValues, 715 } 716 } 717 } 718 719 return nil 720} 721 722// InitiateMultipartUploadOutput presents output for InitiateMultipartUpload. 723type InitiateMultipartUploadOutput struct { 724 StatusCode *int `location:"statusCode"` 725 726 RequestID *string `location:"requestID"` 727 728 // Bucket name 729 Bucket *string `json:"bucket,omitempty" name:"bucket" location:"elements"` 730 // Object key 731 Key *string `json:"key,omitempty" name:"key" location:"elements"` 732 // Object multipart upload ID 733 UploadID *string `json:"upload_id,omitempty" name:"upload_id" location:"elements"` 734 735 // Encryption algorithm of the object 736 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 737} 738 739// ListMultipart does List object parts. 740// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/list_multipart.html 741func (s *Bucket) ListMultipart(objectKey string, input *ListMultipartInput) (*ListMultipartOutput, error) { 742 r, x, err := s.ListMultipartRequest(objectKey, input) 743 744 if err != nil { 745 return x, err 746 } 747 748 err = r.Send() 749 if err != nil { 750 return nil, err 751 } 752 753 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 754 x.RequestID = &requestID 755 756 return x, err 757} 758 759// ListMultipartRequest creates request and output object of ListMultipart. 760func (s *Bucket) ListMultipartRequest(objectKey string, input *ListMultipartInput) (*request.Request, *ListMultipartOutput, error) { 761 762 if input == nil { 763 input = &ListMultipartInput{} 764 } 765 766 properties := *s.Properties 767 768 properties.ObjectKey = &objectKey 769 770 o := &data.Operation{ 771 Config: s.Config, 772 Properties: &properties, 773 APIName: "List Multipart", 774 RequestMethod: "GET", 775 RequestURI: "/<bucket-name>/<object-key>", 776 StatusCodes: []int{ 777 200, // OK 778 }, 779 } 780 781 x := &ListMultipartOutput{} 782 r, err := request.New(o, input, x) 783 if err != nil { 784 return nil, nil, err 785 } 786 787 return r, x, nil 788} 789 790// ListMultipartInput presents input for ListMultipart. 791type ListMultipartInput struct { 792 // Limit results count 793 Limit *int `json:"limit,omitempty" name:"limit" location:"query"` 794 // Object multipart upload part number 795 PartNumberMarker *int `json:"part_number_marker,omitempty" name:"part_number_marker" location:"query"` 796 // Object multipart upload ID 797 UploadID *string `json:"upload_id" name:"upload_id" location:"query"` // Required 798 799} 800 801// Validate validates the input for ListMultipart. 802func (v *ListMultipartInput) Validate() error { 803 804 if v.UploadID == nil { 805 return errors.ParameterRequiredError{ 806 ParameterName: "UploadID", 807 ParentName: "ListMultipartInput", 808 } 809 } 810 811 return nil 812} 813 814// ListMultipartOutput presents output for ListMultipart. 815type ListMultipartOutput struct { 816 StatusCode *int `location:"statusCode"` 817 818 RequestID *string `location:"requestID"` 819 820 // Object multipart count 821 Count *int `json:"count,omitempty" name:"count" location:"elements"` 822 // Object parts 823 ObjectParts []*ObjectPartType `json:"object_parts,omitempty" name:"object_parts" location:"elements"` 824} 825 826// OptionsObject does Check whether the object accepts a origin with method and header. 827// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/options.html 828func (s *Bucket) OptionsObject(objectKey string, input *OptionsObjectInput) (*OptionsObjectOutput, error) { 829 r, x, err := s.OptionsObjectRequest(objectKey, input) 830 831 if err != nil { 832 return x, err 833 } 834 835 err = r.Send() 836 if err != nil { 837 return nil, err 838 } 839 840 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 841 x.RequestID = &requestID 842 843 return x, err 844} 845 846// OptionsObjectRequest creates request and output object of OptionsObject. 847func (s *Bucket) OptionsObjectRequest(objectKey string, input *OptionsObjectInput) (*request.Request, *OptionsObjectOutput, error) { 848 849 if input == nil { 850 input = &OptionsObjectInput{} 851 } 852 853 properties := *s.Properties 854 855 properties.ObjectKey = &objectKey 856 857 o := &data.Operation{ 858 Config: s.Config, 859 Properties: &properties, 860 APIName: "OPTIONS Object", 861 RequestMethod: "OPTIONS", 862 RequestURI: "/<bucket-name>/<object-key>", 863 StatusCodes: []int{ 864 200, // OK 865 304, // Object not modified 866 412, // Object precondition failed 867 }, 868 } 869 870 x := &OptionsObjectOutput{} 871 r, err := request.New(o, input, x) 872 if err != nil { 873 return nil, nil, err 874 } 875 876 return r, x, nil 877} 878 879// OptionsObjectInput presents input for OptionsObject. 880type OptionsObjectInput struct { 881 // Request headers 882 AccessControlRequestHeaders *string `json:"Access-Control-Request-Headers,omitempty" name:"Access-Control-Request-Headers" location:"headers"` 883 // Request method 884 AccessControlRequestMethod *string `json:"Access-Control-Request-Method" name:"Access-Control-Request-Method" location:"headers"` // Required 885 // Request origin 886 Origin *string `json:"Origin" name:"Origin" location:"headers"` // Required 887 888} 889 890// Validate validates the input for OptionsObject. 891func (v *OptionsObjectInput) Validate() error { 892 893 if v.AccessControlRequestMethod == nil { 894 return errors.ParameterRequiredError{ 895 ParameterName: "AccessControlRequestMethod", 896 ParentName: "OptionsObjectInput", 897 } 898 } 899 900 if v.Origin == nil { 901 return errors.ParameterRequiredError{ 902 ParameterName: "Origin", 903 ParentName: "OptionsObjectInput", 904 } 905 } 906 907 return nil 908} 909 910// OptionsObjectOutput presents output for OptionsObject. 911type OptionsObjectOutput struct { 912 StatusCode *int `location:"statusCode"` 913 914 RequestID *string `location:"requestID"` 915 916 // Allowed headers 917 AccessControlAllowHeaders *string `json:"Access-Control-Allow-Headers,omitempty" name:"Access-Control-Allow-Headers" location:"headers"` 918 // Allowed methods 919 AccessControlAllowMethods *string `json:"Access-Control-Allow-Methods,omitempty" name:"Access-Control-Allow-Methods" location:"headers"` 920 // Allowed origin 921 AccessControlAllowOrigin *string `json:"Access-Control-Allow-Origin,omitempty" name:"Access-Control-Allow-Origin" location:"headers"` 922 // Expose headers 923 AccessControlExposeHeaders *string `json:"Access-Control-Expose-Headers,omitempty" name:"Access-Control-Expose-Headers" location:"headers"` 924 // Max age 925 AccessControlMaxAge *string `json:"Access-Control-Max-Age,omitempty" name:"Access-Control-Max-Age" location:"headers"` 926} 927 928// PutObject does Upload the object. 929// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/put.html 930func (s *Bucket) PutObject(objectKey string, input *PutObjectInput) (*PutObjectOutput, error) { 931 r, x, err := s.PutObjectRequest(objectKey, input) 932 933 if err != nil { 934 return x, err 935 } 936 937 err = r.Send() 938 if err != nil { 939 return nil, err 940 } 941 942 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 943 x.RequestID = &requestID 944 945 return x, err 946} 947 948// PutObjectRequest creates request and output object of PutObject. 949func (s *Bucket) PutObjectRequest(objectKey string, input *PutObjectInput) (*request.Request, *PutObjectOutput, error) { 950 951 if input == nil { 952 input = &PutObjectInput{} 953 } 954 955 properties := *s.Properties 956 957 properties.ObjectKey = &objectKey 958 959 o := &data.Operation{ 960 Config: s.Config, 961 Properties: &properties, 962 APIName: "PUT Object", 963 RequestMethod: "PUT", 964 RequestURI: "/<bucket-name>/<object-key>", 965 StatusCodes: []int{ 966 201, // Object created 967 }, 968 } 969 970 x := &PutObjectOutput{} 971 r, err := request.New(o, input, x) 972 if err != nil { 973 return nil, nil, err 974 } 975 976 return r, x, nil 977} 978 979// PutObjectInput presents input for PutObject. 980type PutObjectInput struct { 981 // Object cache control 982 CacheControl *string `json:"Cache-Control,omitempty" name:"Cache-Control" location:"headers"` 983 // Object content encoding 984 ContentEncoding *string `json:"Content-Encoding,omitempty" name:"Content-Encoding" location:"headers"` 985 // Object content size 986 ContentLength *int64 `json:"Content-Length" name:"Content-Length" location:"headers"` // Required 987 // Object MD5sum 988 ContentMD5 *string `json:"Content-MD5,omitempty" name:"Content-MD5" location:"headers"` 989 // Object content type 990 ContentType *string `json:"Content-Type,omitempty" name:"Content-Type" location:"headers"` 991 // Used to indicate that particular server behaviors are required by the client 992 Expect *string `json:"Expect,omitempty" name:"Expect" location:"headers"` 993 // Copy source, format (/<bucket-name>/<object-key>) 994 XQSCopySource *string `json:"X-QS-Copy-Source,omitempty" name:"X-QS-Copy-Source" location:"headers"` 995 // Encryption algorithm of the object 996 XQSCopySourceEncryptionCustomerAlgorithm *string `json:"X-QS-Copy-Source-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Algorithm" location:"headers"` 997 // Encryption key of the object 998 XQSCopySourceEncryptionCustomerKey *string `json:"X-QS-Copy-Source-Encryption-Customer-Key,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Key" location:"headers"` 999 // MD5sum of encryption key 1000 XQSCopySourceEncryptionCustomerKeyMD5 *string `json:"X-QS-Copy-Source-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Key-MD5" location:"headers"` 1001 // Check whether the copy source matches 1002 XQSCopySourceIfMatch *string `json:"X-QS-Copy-Source-If-Match,omitempty" name:"X-QS-Copy-Source-If-Match" location:"headers"` 1003 // Check whether the copy source has been modified 1004 XQSCopySourceIfModifiedSince *time.Time `json:"X-QS-Copy-Source-If-Modified-Since,omitempty" name:"X-QS-Copy-Source-If-Modified-Since" format:"RFC 822" location:"headers"` 1005 // Check whether the copy source does not match 1006 XQSCopySourceIfNoneMatch *string `json:"X-QS-Copy-Source-If-None-Match,omitempty" name:"X-QS-Copy-Source-If-None-Match" location:"headers"` 1007 // Check whether the copy source has not been modified 1008 XQSCopySourceIfUnmodifiedSince *time.Time `json:"X-QS-Copy-Source-If-Unmodified-Since,omitempty" name:"X-QS-Copy-Source-If-Unmodified-Since" format:"RFC 822" location:"headers"` 1009 // Encryption algorithm of the object 1010 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 1011 // Encryption key of the object 1012 XQSEncryptionCustomerKey *string `json:"X-QS-Encryption-Customer-Key,omitempty" name:"X-QS-Encryption-Customer-Key" location:"headers"` 1013 // MD5sum of encryption key 1014 XQSEncryptionCustomerKeyMD5 *string `json:"X-QS-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Encryption-Customer-Key-MD5" location:"headers"` 1015 // Check whether fetch target object has not been modified 1016 XQSFetchIfUnmodifiedSince *time.Time `json:"X-QS-Fetch-If-Unmodified-Since,omitempty" name:"X-QS-Fetch-If-Unmodified-Since" format:"RFC 822" location:"headers"` 1017 // Fetch source, should be a valid url 1018 XQSFetchSource *string `json:"X-QS-Fetch-Source,omitempty" name:"X-QS-Fetch-Source" location:"headers"` 1019 // User-defined metadata 1020 XQSMetaData *map[string]string `json:"X-QS-MetaData,omitempty" name:"X-QS-MetaData" location:"headers"` 1021 // Move source, format (/<bucket-name>/<object-key>) 1022 XQSMoveSource *string `json:"X-QS-Move-Source,omitempty" name:"X-QS-Move-Source" location:"headers"` 1023 // Specify the storage class for object 1024 // XQSStorageClass's available values: STANDARD, STANDARD_IA 1025 XQSStorageClass *string `json:"X-QS-Storage-Class,omitempty" name:"X-QS-Storage-Class" location:"headers"` 1026 1027 // The request body 1028 Body io.Reader `location:"body"` 1029} 1030 1031// Validate validates the input for PutObject. 1032func (v *PutObjectInput) Validate() error { 1033 1034 if v.XQSMetaData != nil { 1035 XQSMetaDataerr := utils.IsMetaDataValid(v.XQSMetaData) 1036 if XQSMetaDataerr != nil { 1037 return XQSMetaDataerr 1038 } 1039 } 1040 1041 if v.XQSStorageClass != nil { 1042 xQSStorageClassValidValues := []string{"STANDARD", "STANDARD_IA"} 1043 xQSStorageClassParameterValue := fmt.Sprint(*v.XQSStorageClass) 1044 1045 xQSStorageClassIsValid := false 1046 for _, value := range xQSStorageClassValidValues { 1047 if value == xQSStorageClassParameterValue { 1048 xQSStorageClassIsValid = true 1049 } 1050 } 1051 1052 if !xQSStorageClassIsValid { 1053 return errors.ParameterValueNotAllowedError{ 1054 ParameterName: "XQSStorageClass", 1055 ParameterValue: xQSStorageClassParameterValue, 1056 AllowedValues: xQSStorageClassValidValues, 1057 } 1058 } 1059 } 1060 1061 return nil 1062} 1063 1064// PutObjectOutput presents output for PutObject. 1065type PutObjectOutput struct { 1066 StatusCode *int `location:"statusCode"` 1067 1068 RequestID *string `location:"requestID"` 1069 1070 // MD5sum of the object 1071 ETag *string `json:"ETag,omitempty" name:"ETag" location:"headers"` 1072 // Encryption algorithm of the object 1073 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 1074} 1075 1076// UploadMultipart does Upload object multipart. 1077// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/multipart/upload_multipart.html 1078func (s *Bucket) UploadMultipart(objectKey string, input *UploadMultipartInput) (*UploadMultipartOutput, error) { 1079 r, x, err := s.UploadMultipartRequest(objectKey, input) 1080 1081 if err != nil { 1082 return x, err 1083 } 1084 1085 err = r.Send() 1086 if err != nil { 1087 return nil, err 1088 } 1089 1090 requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID")) 1091 x.RequestID = &requestID 1092 1093 return x, err 1094} 1095 1096// UploadMultipartRequest creates request and output object of UploadMultipart. 1097func (s *Bucket) UploadMultipartRequest(objectKey string, input *UploadMultipartInput) (*request.Request, *UploadMultipartOutput, error) { 1098 1099 if input == nil { 1100 input = &UploadMultipartInput{} 1101 } 1102 1103 properties := *s.Properties 1104 1105 properties.ObjectKey = &objectKey 1106 1107 o := &data.Operation{ 1108 Config: s.Config, 1109 Properties: &properties, 1110 APIName: "Upload Multipart", 1111 RequestMethod: "PUT", 1112 RequestURI: "/<bucket-name>/<object-key>", 1113 StatusCodes: []int{ 1114 201, // Object multipart created 1115 }, 1116 } 1117 1118 x := &UploadMultipartOutput{} 1119 r, err := request.New(o, input, x) 1120 if err != nil { 1121 return nil, nil, err 1122 } 1123 1124 return r, x, nil 1125} 1126 1127// UploadMultipartInput presents input for UploadMultipart. 1128type UploadMultipartInput struct { 1129 // Object multipart upload part number 1130 PartNumber *int `json:"part_number" name:"part_number" default:"0" location:"query"` // Required 1131 // Object multipart upload ID 1132 UploadID *string `json:"upload_id" name:"upload_id" location:"query"` // Required 1133 1134 // Object multipart content length 1135 ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"` 1136 // Object multipart content MD5sum 1137 ContentMD5 *string `json:"Content-MD5,omitempty" name:"Content-MD5" location:"headers"` 1138 // Specify range of the source object 1139 XQSCopyRange *string `json:"X-QS-Copy-Range,omitempty" name:"X-QS-Copy-Range" location:"headers"` 1140 // Copy source, format (/<bucket-name>/<object-key>) 1141 XQSCopySource *string `json:"X-QS-Copy-Source,omitempty" name:"X-QS-Copy-Source" location:"headers"` 1142 // Encryption algorithm of the object 1143 XQSCopySourceEncryptionCustomerAlgorithm *string `json:"X-QS-Copy-Source-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Algorithm" location:"headers"` 1144 // Encryption key of the object 1145 XQSCopySourceEncryptionCustomerKey *string `json:"X-QS-Copy-Source-Encryption-Customer-Key,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Key" location:"headers"` 1146 // MD5sum of encryption key 1147 XQSCopySourceEncryptionCustomerKeyMD5 *string `json:"X-QS-Copy-Source-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Key-MD5" location:"headers"` 1148 // Check whether the Etag of copy source matches the specified value 1149 XQSCopySourceIfMatch *string `json:"X-QS-Copy-Source-If-Match,omitempty" name:"X-QS-Copy-Source-If-Match" location:"headers"` 1150 // Check whether the copy source has been modified since the specified date 1151 XQSCopySourceIfModifiedSince *time.Time `json:"X-QS-Copy-Source-If-Modified-Since,omitempty" name:"X-QS-Copy-Source-If-Modified-Since" format:"RFC 822" location:"headers"` 1152 // Check whether the Etag of copy source does not matches the specified value 1153 XQSCopySourceIfNoneMatch *string `json:"X-QS-Copy-Source-If-None-Match,omitempty" name:"X-QS-Copy-Source-If-None-Match" location:"headers"` 1154 // Check whether the copy source has not been unmodified since the specified date 1155 XQSCopySourceIfUnmodifiedSince *time.Time `json:"X-QS-Copy-Source-If-Unmodified-Since,omitempty" name:"X-QS-Copy-Source-If-Unmodified-Since" format:"RFC 822" location:"headers"` 1156 // Encryption algorithm of the object 1157 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 1158 // Encryption key of the object 1159 XQSEncryptionCustomerKey *string `json:"X-QS-Encryption-Customer-Key,omitempty" name:"X-QS-Encryption-Customer-Key" location:"headers"` 1160 // MD5sum of encryption key 1161 XQSEncryptionCustomerKeyMD5 *string `json:"X-QS-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Encryption-Customer-Key-MD5" location:"headers"` 1162 1163 // The request body 1164 Body io.Reader `location:"body"` 1165} 1166 1167// Validate validates the input for UploadMultipart. 1168func (v *UploadMultipartInput) Validate() error { 1169 1170 if v.PartNumber == nil { 1171 return errors.ParameterRequiredError{ 1172 ParameterName: "PartNumber", 1173 ParentName: "UploadMultipartInput", 1174 } 1175 } 1176 1177 if v.UploadID == nil { 1178 return errors.ParameterRequiredError{ 1179 ParameterName: "UploadID", 1180 ParentName: "UploadMultipartInput", 1181 } 1182 } 1183 1184 return nil 1185} 1186 1187// UploadMultipartOutput presents output for UploadMultipart. 1188type UploadMultipartOutput struct { 1189 StatusCode *int `location:"statusCode"` 1190 1191 RequestID *string `location:"requestID"` 1192 1193 // MD5sum of the object 1194 ETag *string `json:"ETag,omitempty" name:"ETag" location:"headers"` 1195 // Range of response data content 1196 XQSContentCopyRange *string `json:"X-QS-Content-Copy-Range,omitempty" name:"X-QS-Content-Copy-Range" location:"headers"` 1197 // Encryption algorithm of the object 1198 XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"` 1199} 1200