github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/obs/trait.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 //nolint:structcheck, unused 14 package obs 15 16 import ( 17 "bytes" 18 "fmt" 19 "io" 20 "net/url" 21 "os" 22 "strings" 23 ) 24 25 // IReadCloser defines interface with function: setReadCloser 26 type IReadCloser interface { 27 setReadCloser(body io.ReadCloser) 28 } 29 30 func (output *GetObjectOutput) setReadCloser(body io.ReadCloser) { 31 output.Body = body 32 } 33 34 func setHeaders(headers map[string][]string, header string, headerValue []string, isObs bool) { 35 if isObs { 36 header = HEADER_PREFIX_OBS + header 37 headers[header] = headerValue 38 } else { 39 header = HEADER_PREFIX + header 40 headers[header] = headerValue 41 } 42 } 43 44 func setHeadersNext(headers map[string][]string, header string, headerNext string, headerValue []string, isObs bool) { 45 if isObs { 46 headers[header] = headerValue 47 } else { 48 headers[headerNext] = headerValue 49 } 50 } 51 52 // IBaseModel defines interface for base response model 53 type IBaseModel interface { 54 setStatusCode(statusCode int) 55 56 setRequestID(requestID string) 57 58 setResponseHeaders(responseHeaders map[string][]string) 59 } 60 61 // ISerializable defines interface with function: trans 62 type ISerializable interface { 63 trans(isObs bool) (map[string]string, map[string][]string, interface{}, error) 64 } 65 66 // DefaultSerializable defines default serializable struct 67 type DefaultSerializable struct { 68 params map[string]string 69 headers map[string][]string 70 data interface{} 71 } 72 73 func (input DefaultSerializable) trans(isObs bool) (map[string]string, map[string][]string, interface{}, error) { 74 return input.params, input.headers, input.data, nil 75 } 76 77 var defaultSerializable = &DefaultSerializable{} 78 79 func newSubResourceSerial(subResource SubResourceType) *DefaultSerializable { 80 return &DefaultSerializable{map[string]string{string(subResource): ""}, nil, nil} 81 } 82 83 func trans(subResource SubResourceType, input interface{}) (params map[string]string, headers map[string][]string, data interface{}, err error) { 84 params = map[string]string{string(subResource): ""} 85 data, err = ConvertRequestToIoReader(input) 86 return 87 } 88 89 func (baseModel *BaseModel) setStatusCode(statusCode int) { 90 baseModel.StatusCode = statusCode 91 } 92 93 func (baseModel *BaseModel) setRequestID(requestID string) { 94 baseModel.RequestId = requestID 95 } 96 97 func (baseModel *BaseModel) setResponseHeaders(responseHeaders map[string][]string) { 98 baseModel.ResponseHeaders = responseHeaders 99 } 100 101 func (input ListBucketsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 102 headers = make(map[string][]string) 103 if input.QueryLocation && !isObs { 104 setHeaders(headers, HEADER_LOCATION_AMZ, []string{"true"}, isObs) 105 } 106 return 107 } 108 109 func (input CreateBucketInput) prepareGrantHeaders(headers map[string][]string, isObs bool) { 110 if grantReadID := input.GrantReadId; grantReadID != "" { 111 setHeaders(headers, HEADER_GRANT_READ_OBS, []string{grantReadID}, isObs) 112 } 113 if grantWriteID := input.GrantWriteId; grantWriteID != "" { 114 setHeaders(headers, HEADER_GRANT_WRITE_OBS, []string{grantWriteID}, isObs) 115 } 116 if grantReadAcpID := input.GrantReadAcpId; grantReadAcpID != "" { 117 setHeaders(headers, HEADER_GRANT_READ_ACP_OBS, []string{grantReadAcpID}, isObs) 118 } 119 if grantWriteAcpID := input.GrantWriteAcpId; grantWriteAcpID != "" { 120 setHeaders(headers, HEADER_GRANT_WRITE_ACP_OBS, []string{grantWriteAcpID}, isObs) 121 } 122 if grantFullControlID := input.GrantFullControlId; grantFullControlID != "" { 123 setHeaders(headers, HEADER_GRANT_FULL_CONTROL_OBS, []string{grantFullControlID}, isObs) 124 } 125 if grantReadDeliveredID := input.GrantReadDeliveredId; grantReadDeliveredID != "" { 126 setHeaders(headers, HEADER_GRANT_READ_DELIVERED_OBS, []string{grantReadDeliveredID}, true) 127 } 128 if grantFullControlDeliveredID := input.GrantFullControlDeliveredId; grantFullControlDeliveredID != "" { 129 setHeaders(headers, HEADER_GRANT_FULL_CONTROL_DELIVERED_OBS, []string{grantFullControlDeliveredID}, true) 130 } 131 } 132 133 func (input CreateBucketInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 134 headers = make(map[string][]string) 135 if acl := string(input.ACL); acl != "" { 136 setHeaders(headers, HEADER_ACL, []string{acl}, isObs) 137 } 138 if storageClass := string(input.StorageClass); storageClass != "" { 139 if !isObs { 140 if storageClass == string(StorageClassWarm) { 141 storageClass = string(storageClassStandardIA) 142 } else if storageClass == string(StorageClassCold) { 143 storageClass = string(storageClassGlacier) 144 } 145 } 146 setHeadersNext(headers, HEADER_STORAGE_CLASS_OBS, HEADER_STORAGE_CLASS, []string{storageClass}, isObs) 147 } 148 if epid := input.Epid; epid != "" { 149 setHeaders(headers, HEADER_EPID_HEADERS, []string{epid}, isObs) 150 } 151 if availableZone := input.AvailableZone; availableZone != "" { 152 setHeaders(headers, HEADER_AZ_REDUNDANCY, []string{availableZone}, isObs) 153 } 154 155 input.prepareGrantHeaders(headers, isObs) 156 if input.IsFSFileInterface { 157 setHeaders(headers, headerFSFileInterface, []string{"Enabled"}, true) 158 } 159 160 if location := strings.TrimSpace(input.Location); location != "" { 161 input.Location = location 162 163 xml := make([]string, 0, 3) 164 xml = append(xml, "<CreateBucketConfiguration>") 165 if isObs { 166 xml = append(xml, fmt.Sprintf("<Location>%s</Location>", input.Location)) 167 } else { 168 xml = append(xml, fmt.Sprintf("<LocationConstraint>%s</LocationConstraint>", input.Location)) 169 } 170 xml = append(xml, "</CreateBucketConfiguration>") 171 172 data = strings.Join(xml, "") 173 } 174 return 175 } 176 177 func (input SetBucketStoragePolicyInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 178 xml := make([]string, 0, 1) 179 if !isObs { 180 storageClass := "STANDARD" 181 if input.StorageClass == StorageClassWarm { 182 storageClass = string(storageClassStandardIA) 183 } else if input.StorageClass == StorageClassCold { 184 storageClass = string(storageClassGlacier) 185 } 186 params = map[string]string{string(SubResourceStoragePolicy): ""} 187 xml = append(xml, fmt.Sprintf("<StoragePolicy><DefaultStorageClass>%s</DefaultStorageClass></StoragePolicy>", storageClass)) 188 } else { 189 if input.StorageClass != StorageClassWarm && input.StorageClass != StorageClassCold { 190 input.StorageClass = StorageClassStandard 191 } 192 params = map[string]string{string(SubResourceStorageClass): ""} 193 xml = append(xml, fmt.Sprintf("<StorageClass>%s</StorageClass>", input.StorageClass)) 194 } 195 data = strings.Join(xml, "") 196 return 197 } 198 199 func (input ListObjsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 200 params = make(map[string]string) 201 if input.Prefix != "" { 202 params["prefix"] = input.Prefix 203 } 204 if input.Delimiter != "" { 205 params["delimiter"] = input.Delimiter 206 } 207 if input.MaxKeys > 0 { 208 params["max-keys"] = IntToString(input.MaxKeys) 209 } 210 if input.EncodingType != "" { 211 params["encoding-type"] = input.EncodingType 212 } 213 headers = make(map[string][]string) 214 if origin := strings.TrimSpace(input.Origin); origin != "" { 215 headers[HEADER_ORIGIN_CAMEL] = []string{origin} 216 } 217 if requestHeader := strings.TrimSpace(input.RequestHeader); requestHeader != "" { 218 headers[HEADER_ACCESS_CONTROL_REQUEST_HEADER_CAMEL] = []string{requestHeader} 219 } 220 return 221 } 222 223 func (input ListObjectsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 224 params, headers, data, err = input.ListObjsInput.trans(isObs) 225 if err != nil { 226 return 227 } 228 if input.Marker != "" { 229 params["marker"] = input.Marker 230 } 231 return 232 } 233 234 func (input ListVersionsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 235 params, headers, data, err = input.ListObjsInput.trans(isObs) 236 if err != nil { 237 return 238 } 239 params[string(SubResourceVersions)] = "" 240 if input.KeyMarker != "" { 241 params["key-marker"] = input.KeyMarker 242 } 243 if input.VersionIdMarker != "" { 244 params["version-id-marker"] = input.VersionIdMarker 245 } 246 return 247 } 248 249 func (input ListMultipartUploadsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 250 params = map[string]string{string(SubResourceUploads): ""} 251 if input.Prefix != "" { 252 params["prefix"] = input.Prefix 253 } 254 if input.Delimiter != "" { 255 params["delimiter"] = input.Delimiter 256 } 257 if input.MaxUploads > 0 { 258 params["max-uploads"] = IntToString(input.MaxUploads) 259 } 260 if input.KeyMarker != "" { 261 params["key-marker"] = input.KeyMarker 262 } 263 if input.UploadIdMarker != "" { 264 params["upload-id-marker"] = input.UploadIdMarker 265 } 266 if input.EncodingType != "" { 267 params["encoding-type"] = input.EncodingType 268 } 269 return 270 } 271 272 func (input SetBucketQuotaInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 273 return trans(SubResourceQuota, input) 274 } 275 276 func (input SetBucketAclInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 277 params = map[string]string{string(SubResourceAcl): ""} 278 headers = make(map[string][]string) 279 280 if acl := string(input.ACL); acl != "" { 281 setHeaders(headers, HEADER_ACL, []string{acl}, isObs) 282 } else { 283 data, _ = convertBucketACLToXML(input.AccessControlPolicy, false, isObs) 284 } 285 return 286 } 287 288 func (input SetBucketPolicyInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 289 params = map[string]string{string(SubResourcePolicy): ""} 290 data = strings.NewReader(input.Policy) 291 return 292 } 293 294 func (input SetBucketCorsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 295 params = map[string]string{string(SubResourceCors): ""} 296 data, md5, err := ConvertRequestToIoReaderV2(input) 297 if err != nil { 298 return 299 } 300 headers = map[string][]string{HEADER_MD5_CAMEL: {md5}} 301 return 302 } 303 304 func (input SetBucketVersioningInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 305 return trans(SubResourceVersioning, input) 306 } 307 308 func (input SetBucketWebsiteConfigurationInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 309 params = map[string]string{string(SubResourceWebsite): ""} 310 data, _ = ConvertWebsiteConfigurationToXml(input.BucketWebsiteConfiguration, false) 311 return 312 } 313 314 func (input GetBucketMetadataInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 315 headers = make(map[string][]string) 316 if origin := strings.TrimSpace(input.Origin); origin != "" { 317 headers[HEADER_ORIGIN_CAMEL] = []string{origin} 318 } 319 if requestHeader := strings.TrimSpace(input.RequestHeader); requestHeader != "" { 320 headers[HEADER_ACCESS_CONTROL_REQUEST_HEADER_CAMEL] = []string{requestHeader} 321 } 322 return 323 } 324 325 func (input SetBucketLoggingConfigurationInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 326 params = map[string]string{string(SubResourceLogging): ""} 327 data, _ = ConvertLoggingStatusToXml(input.BucketLoggingStatus, false, isObs) 328 return 329 } 330 331 func (input SetBucketLifecycleConfigurationInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 332 params = map[string]string{string(SubResourceLifecycle): ""} 333 data, md5 := ConvertLifecyleConfigurationToXml(input.BucketLifecyleConfiguration, true, isObs) 334 headers = map[string][]string{HEADER_MD5_CAMEL: {md5}} 335 return 336 } 337 338 func (input SetBucketEncryptionInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 339 params = map[string]string{string(SubResourceEncryption): ""} 340 data, _ = ConvertEncryptionConfigurationToXml(input.BucketEncryptionConfiguration, false, isObs) 341 return 342 } 343 344 func (input SetBucketTaggingInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 345 params = map[string]string{string(SubResourceTagging): ""} 346 data, md5, err := ConvertRequestToIoReaderV2(input) 347 if err != nil { 348 return 349 } 350 headers = map[string][]string{HEADER_MD5_CAMEL: {md5}} 351 return 352 } 353 354 func (input SetBucketNotificationInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 355 params = map[string]string{string(SubResourceNotification): ""} 356 data, _ = ConvertNotificationToXml(input.BucketNotification, false, isObs) 357 return 358 } 359 360 func (input DeleteObjectInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 361 params = make(map[string]string) 362 if input.VersionId != "" { 363 params[PARAM_VERSION_ID] = input.VersionId 364 } 365 return 366 } 367 368 func (input DeleteObjectsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 369 params = map[string]string{string(SubResourceDelete): ""} 370 if strings.ToLower(input.EncodingType) == "url" { 371 for index, object := range input.Objects { 372 input.Objects[index].Key = url.QueryEscape(object.Key) 373 } 374 } 375 data, md5 := convertDeleteObjectsToXML(input) 376 headers = map[string][]string{HEADER_MD5_CAMEL: {md5}} 377 return 378 } 379 380 func (input SetObjectAclInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 381 params = map[string]string{string(SubResourceAcl): ""} 382 if input.VersionId != "" { 383 params[PARAM_VERSION_ID] = input.VersionId 384 } 385 headers = make(map[string][]string) 386 if acl := string(input.ACL); acl != "" { 387 setHeaders(headers, HEADER_ACL, []string{acl}, isObs) 388 } else { 389 data, _ = ConvertAclToXml(input.AccessControlPolicy, false, isObs) 390 } 391 return 392 } 393 394 func (input GetObjectAclInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 395 params = map[string]string{string(SubResourceAcl): ""} 396 if input.VersionId != "" { 397 params[PARAM_VERSION_ID] = input.VersionId 398 } 399 return 400 } 401 402 func (input RestoreObjectInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 403 params = map[string]string{string(SubResourceRestore): ""} 404 if input.VersionId != "" { 405 params[PARAM_VERSION_ID] = input.VersionId 406 } 407 if !isObs { 408 data, err = ConvertRequestToIoReader(input) 409 } else { 410 data = ConverntObsRestoreToXml(input) 411 } 412 return 413 } 414 415 // GetEncryption gets the Encryption field value from SseKmsHeader 416 func (header SseKmsHeader) GetEncryption() string { 417 if header.Encryption != "" { 418 return header.Encryption 419 } 420 if !header.isObs { 421 return DEFAULT_SSE_KMS_ENCRYPTION 422 } 423 return DEFAULT_SSE_KMS_ENCRYPTION_OBS 424 } 425 426 // GetKey gets the Key field value from SseKmsHeader 427 func (header SseKmsHeader) GetKey() string { 428 return header.Key 429 } 430 431 // GetEncryption gets the Encryption field value from SseCHeader 432 func (header SseCHeader) GetEncryption() string { 433 if header.Encryption != "" { 434 return header.Encryption 435 } 436 return DEFAULT_SSE_C_ENCRYPTION 437 } 438 439 // GetKey gets the Key field value from SseCHeader 440 func (header SseCHeader) GetKey() string { 441 return header.Key 442 } 443 444 // GetKeyMD5 gets the KeyMD5 field value from SseCHeader 445 func (header SseCHeader) GetKeyMD5() string { 446 if header.KeyMD5 != "" { 447 return header.KeyMD5 448 } 449 450 if ret, err := Base64Decode(header.GetKey()); err == nil { 451 return Base64Md5(ret) 452 } 453 return "" 454 } 455 456 func setSseHeader(headers map[string][]string, sseHeader ISseHeader, sseCOnly bool, isObs bool) { 457 if sseHeader != nil { 458 if sseCHeader, ok := sseHeader.(SseCHeader); ok { 459 setHeaders(headers, HEADER_SSEC_ENCRYPTION, []string{sseCHeader.GetEncryption()}, isObs) 460 setHeaders(headers, HEADER_SSEC_KEY, []string{sseCHeader.GetKey()}, isObs) 461 setHeaders(headers, HEADER_SSEC_KEY_MD5, []string{sseCHeader.GetKeyMD5()}, isObs) 462 } else if sseKmsHeader, ok := sseHeader.(SseKmsHeader); !sseCOnly && ok { 463 sseKmsHeader.isObs = isObs 464 setHeaders(headers, HEADER_SSEKMS_ENCRYPTION, []string{sseKmsHeader.GetEncryption()}, isObs) 465 if sseKmsHeader.GetKey() != "" { 466 setHeadersNext(headers, HEADER_SSEKMS_KEY_OBS, HEADER_SSEKMS_KEY_AMZ, []string{sseKmsHeader.GetKey()}, isObs) 467 } 468 } 469 } 470 } 471 472 func (input GetObjectMetadataInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 473 params = make(map[string]string) 474 if input.VersionId != "" { 475 params[PARAM_VERSION_ID] = input.VersionId 476 } 477 headers = make(map[string][]string) 478 479 if input.Origin != "" { 480 headers[HEADER_ORIGIN_CAMEL] = []string{input.Origin} 481 } 482 483 if input.RequestHeader != "" { 484 headers[HEADER_ACCESS_CONTROL_REQUEST_HEADER_CAMEL] = []string{input.RequestHeader} 485 } 486 setSseHeader(headers, input.SseHeader, true, isObs) 487 return 488 } 489 490 func (input SetObjectMetadataInput) prepareContentHeaders(headers map[string][]string) { 491 if input.ContentDisposition != "" { 492 headers[HEADER_CONTENT_DISPOSITION_CAMEL] = []string{input.ContentDisposition} 493 } 494 if input.ContentEncoding != "" { 495 headers[HEADER_CONTENT_ENCODING_CAMEL] = []string{input.ContentEncoding} 496 } 497 if input.ContentLanguage != "" { 498 headers[HEADER_CONTENT_LANGUAGE_CAMEL] = []string{input.ContentLanguage} 499 } 500 501 if input.ContentType != "" { 502 headers[HEADER_CONTENT_TYPE_CAML] = []string{input.ContentType} 503 } 504 } 505 506 func (input SetObjectMetadataInput) prepareStorageClass(headers map[string][]string, isObs bool) { 507 if storageClass := string(input.StorageClass); storageClass != "" { 508 if !isObs { 509 if storageClass == string(StorageClassWarm) { 510 storageClass = string(storageClassStandardIA) 511 } else if storageClass == string(StorageClassCold) { 512 storageClass = string(storageClassGlacier) 513 } 514 } 515 setHeaders(headers, HEADER_STORAGE_CLASS2, []string{storageClass}, isObs) 516 } 517 } 518 519 func (input SetObjectMetadataInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 520 params = make(map[string]string) 521 params = map[string]string{string(SubResourceMetadata): ""} 522 if input.VersionId != "" { 523 params[PARAM_VERSION_ID] = input.VersionId 524 } 525 headers = make(map[string][]string) 526 527 if directive := string(input.MetadataDirective); directive != "" { 528 setHeaders(headers, HEADER_METADATA_DIRECTIVE, []string{string(input.MetadataDirective)}, isObs) 529 } else { 530 setHeaders(headers, HEADER_METADATA_DIRECTIVE, []string{string(ReplaceNew)}, isObs) 531 } 532 if input.CacheControl != "" { 533 headers[HEADER_CACHE_CONTROL_CAMEL] = []string{input.CacheControl} 534 } 535 input.prepareContentHeaders(headers) 536 if input.Expires != "" { 537 headers[HEADER_EXPIRES_CAMEL] = []string{input.Expires} 538 } 539 if input.WebsiteRedirectLocation != "" { 540 setHeaders(headers, HEADER_WEBSITE_REDIRECT_LOCATION, []string{input.WebsiteRedirectLocation}, isObs) 541 } 542 input.prepareStorageClass(headers, isObs) 543 if input.Metadata != nil { 544 for key, value := range input.Metadata { 545 key = strings.TrimSpace(key) 546 setHeadersNext(headers, HEADER_PREFIX_META_OBS+key, HEADER_PREFIX_META+key, []string{value}, isObs) 547 } 548 } 549 return 550 } 551 552 func (input GetObjectInput) prepareResponseParams(params map[string]string) { 553 if input.ResponseCacheControl != "" { 554 params[PARAM_RESPONSE_CACHE_CONTROL] = input.ResponseCacheControl 555 } 556 if input.ResponseContentDisposition != "" { 557 params[PARAM_RESPONSE_CONTENT_DISPOSITION] = input.ResponseContentDisposition 558 } 559 if input.ResponseContentEncoding != "" { 560 params[PARAM_RESPONSE_CONTENT_ENCODING] = input.ResponseContentEncoding 561 } 562 if input.ResponseContentLanguage != "" { 563 params[PARAM_RESPONSE_CONTENT_LANGUAGE] = input.ResponseContentLanguage 564 } 565 if input.ResponseContentType != "" { 566 params[PARAM_RESPONSE_CONTENT_TYPE] = input.ResponseContentType 567 } 568 if input.ResponseExpires != "" { 569 params[PARAM_RESPONSE_EXPIRES] = input.ResponseExpires 570 } 571 } 572 573 func (input GetObjectInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 574 params, headers, data, err = input.GetObjectMetadataInput.trans(isObs) 575 if err != nil { 576 return 577 } 578 input.prepareResponseParams(params) 579 if input.ImageProcess != "" { 580 params[PARAM_IMAGE_PROCESS] = input.ImageProcess 581 } 582 if input.RangeStart >= 0 && input.RangeEnd > input.RangeStart { 583 headers[HEADER_RANGE] = []string{fmt.Sprintf("bytes=%d-%d", input.RangeStart, input.RangeEnd)} 584 } 585 586 if input.IfMatch != "" { 587 headers[HEADER_IF_MATCH] = []string{input.IfMatch} 588 } 589 if input.IfNoneMatch != "" { 590 headers[HEADER_IF_NONE_MATCH] = []string{input.IfNoneMatch} 591 } 592 if !input.IfModifiedSince.IsZero() { 593 headers[HEADER_IF_MODIFIED_SINCE] = []string{FormatUtcToRfc1123(input.IfModifiedSince)} 594 } 595 if !input.IfUnmodifiedSince.IsZero() { 596 headers[HEADER_IF_UNMODIFIED_SINCE] = []string{FormatUtcToRfc1123(input.IfUnmodifiedSince)} 597 } 598 return 599 } 600 601 func (input ObjectOperationInput) prepareGrantHeaders(headers map[string][]string) { 602 if GrantReadID := input.GrantReadId; GrantReadID != "" { 603 setHeaders(headers, HEADER_GRANT_READ_OBS, []string{GrantReadID}, true) 604 } 605 if GrantReadAcpID := input.GrantReadAcpId; GrantReadAcpID != "" { 606 setHeaders(headers, HEADER_GRANT_READ_ACP_OBS, []string{GrantReadAcpID}, true) 607 } 608 if GrantWriteAcpID := input.GrantWriteAcpId; GrantWriteAcpID != "" { 609 setHeaders(headers, HEADER_GRANT_WRITE_ACP_OBS, []string{GrantWriteAcpID}, true) 610 } 611 if GrantFullControlID := input.GrantFullControlId; GrantFullControlID != "" { 612 setHeaders(headers, HEADER_GRANT_FULL_CONTROL_OBS, []string{GrantFullControlID}, true) 613 } 614 } 615 616 func (input ObjectOperationInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 617 headers = make(map[string][]string) 618 params = make(map[string]string) 619 if acl := string(input.ACL); acl != "" { 620 setHeaders(headers, HEADER_ACL, []string{acl}, isObs) 621 } 622 input.prepareGrantHeaders(headers) 623 if storageClass := string(input.StorageClass); storageClass != "" { 624 if !isObs { 625 if storageClass == string(StorageClassWarm) { 626 storageClass = string(storageClassStandardIA) 627 } else if storageClass == string(StorageClassCold) { 628 storageClass = string(storageClassGlacier) 629 } 630 } 631 setHeaders(headers, HEADER_STORAGE_CLASS2, []string{storageClass}, isObs) 632 } 633 if input.WebsiteRedirectLocation != "" { 634 setHeaders(headers, HEADER_WEBSITE_REDIRECT_LOCATION, []string{input.WebsiteRedirectLocation}, isObs) 635 636 } 637 setSseHeader(headers, input.SseHeader, false, isObs) 638 if input.Expires != 0 { 639 setHeaders(headers, HEADER_EXPIRES, []string{Int64ToString(input.Expires)}, true) 640 } 641 if input.Metadata != nil { 642 for key, value := range input.Metadata { 643 key = strings.TrimSpace(key) 644 setHeadersNext(headers, HEADER_PREFIX_META_OBS+key, HEADER_PREFIX_META+key, []string{value}, isObs) 645 } 646 } 647 return 648 } 649 650 func (input PutObjectBasicInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 651 params, headers, data, err = input.ObjectOperationInput.trans(isObs) 652 if err != nil { 653 return 654 } 655 656 if input.ContentMD5 != "" { 657 headers[HEADER_MD5_CAMEL] = []string{input.ContentMD5} 658 } 659 660 if input.ContentLength > 0 { 661 headers[HEADER_CONTENT_LENGTH_CAMEL] = []string{Int64ToString(input.ContentLength)} 662 } 663 if input.ContentType != "" { 664 headers[HEADER_CONTENT_TYPE_CAML] = []string{input.ContentType} 665 } 666 667 return 668 } 669 670 func (input PutObjectInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 671 params, headers, data, err = input.PutObjectBasicInput.trans(isObs) 672 if err != nil { 673 return 674 } 675 if input.Body != nil { 676 data = input.Body 677 } 678 return 679 } 680 681 func (input CopyObjectInput) prepareReplaceHeaders(headers map[string][]string) { 682 if input.CacheControl != "" { 683 headers[HEADER_CACHE_CONTROL] = []string{input.CacheControl} 684 } 685 if input.ContentDisposition != "" { 686 headers[HEADER_CONTENT_DISPOSITION] = []string{input.ContentDisposition} 687 } 688 if input.ContentEncoding != "" { 689 headers[HEADER_CONTENT_ENCODING] = []string{input.ContentEncoding} 690 } 691 if input.ContentLanguage != "" { 692 headers[HEADER_CONTENT_LANGUAGE] = []string{input.ContentLanguage} 693 } 694 if input.ContentType != "" { 695 headers[HEADER_CONTENT_TYPE] = []string{input.ContentType} 696 } 697 if input.Expires != "" { 698 headers[HEADER_EXPIRES] = []string{input.Expires} 699 } 700 } 701 702 func (input CopyObjectInput) prepareCopySourceHeaders(headers map[string][]string, isObs bool) { 703 if input.CopySourceIfMatch != "" { 704 setHeaders(headers, HEADER_COPY_SOURCE_IF_MATCH, []string{input.CopySourceIfMatch}, isObs) 705 } 706 if input.CopySourceIfNoneMatch != "" { 707 setHeaders(headers, HEADER_COPY_SOURCE_IF_NONE_MATCH, []string{input.CopySourceIfNoneMatch}, isObs) 708 } 709 if !input.CopySourceIfModifiedSince.IsZero() { 710 setHeaders(headers, HEADER_COPY_SOURCE_IF_MODIFIED_SINCE, []string{FormatUtcToRfc1123(input.CopySourceIfModifiedSince)}, isObs) 711 } 712 if !input.CopySourceIfUnmodifiedSince.IsZero() { 713 setHeaders(headers, HEADER_COPY_SOURCE_IF_UNMODIFIED_SINCE, []string{FormatUtcToRfc1123(input.CopySourceIfUnmodifiedSince)}, isObs) 714 } 715 } 716 717 func (input CopyObjectInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 718 params, headers, data, err = input.ObjectOperationInput.trans(isObs) 719 if err != nil { 720 return 721 } 722 723 var copySource string 724 if input.CopySourceVersionId != "" { 725 copySource = fmt.Sprintf("%s/%s?versionId=%s", input.CopySourceBucket, UrlEncode(input.CopySourceKey, false), input.CopySourceVersionId) 726 } else { 727 copySource = fmt.Sprintf("%s/%s", input.CopySourceBucket, UrlEncode(input.CopySourceKey, false)) 728 } 729 setHeaders(headers, HEADER_COPY_SOURCE, []string{copySource}, isObs) 730 731 if directive := string(input.MetadataDirective); directive != "" { 732 setHeaders(headers, HEADER_METADATA_DIRECTIVE, []string{directive}, isObs) 733 } 734 735 if input.MetadataDirective == ReplaceMetadata { 736 input.prepareReplaceHeaders(headers) 737 } 738 739 input.prepareCopySourceHeaders(headers, isObs) 740 if input.SourceSseHeader != nil { 741 if sseCHeader, ok := input.SourceSseHeader.(SseCHeader); ok { 742 setHeaders(headers, HEADER_SSEC_COPY_SOURCE_ENCRYPTION, []string{sseCHeader.GetEncryption()}, isObs) 743 setHeaders(headers, HEADER_SSEC_COPY_SOURCE_KEY, []string{sseCHeader.GetKey()}, isObs) 744 setHeaders(headers, HEADER_SSEC_COPY_SOURCE_KEY_MD5, []string{sseCHeader.GetKeyMD5()}, isObs) 745 } 746 } 747 if input.SuccessActionRedirect != "" { 748 headers[HEADER_SUCCESS_ACTION_REDIRECT] = []string{input.SuccessActionRedirect} 749 } 750 return 751 } 752 753 func (input AbortMultipartUploadInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 754 params = map[string]string{"uploadId": input.UploadId} 755 return 756 } 757 758 func (input InitiateMultipartUploadInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 759 params, headers, data, err = input.ObjectOperationInput.trans(isObs) 760 if err != nil { 761 return 762 } 763 if input.ContentType != "" { 764 headers[HEADER_CONTENT_TYPE_CAML] = []string{input.ContentType} 765 } 766 params[string(SubResourceUploads)] = "" 767 if input.EncodingType != "" { 768 params["encoding-type"] = input.EncodingType 769 } 770 return 771 } 772 773 func (input UploadPartInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 774 params = map[string]string{"uploadId": input.UploadId, "partNumber": IntToString(input.PartNumber)} 775 headers = make(map[string][]string) 776 setSseHeader(headers, input.SseHeader, true, isObs) 777 if input.ContentMD5 != "" { 778 headers[HEADER_MD5_CAMEL] = []string{input.ContentMD5} 779 } 780 if input.Body != nil { 781 data = input.Body 782 } 783 return 784 } 785 786 func (input CompleteMultipartUploadInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 787 params = map[string]string{"uploadId": input.UploadId} 788 if input.EncodingType != "" { 789 params["encoding-type"] = input.EncodingType 790 } 791 data, _ = ConvertCompleteMultipartUploadInputToXml(input, false) 792 return 793 } 794 795 func (input ListPartsInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 796 params = map[string]string{"uploadId": input.UploadId} 797 if input.MaxParts > 0 { 798 params["max-parts"] = IntToString(input.MaxParts) 799 } 800 if input.PartNumberMarker > 0 { 801 params["part-number-marker"] = IntToString(input.PartNumberMarker) 802 } 803 if input.EncodingType != "" { 804 params["encoding-type"] = input.EncodingType 805 } 806 return 807 } 808 809 func (input CopyPartInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 810 params = map[string]string{"uploadId": input.UploadId, "partNumber": IntToString(input.PartNumber)} 811 headers = make(map[string][]string, 1) 812 var copySource string 813 if input.CopySourceVersionId != "" { 814 copySource = fmt.Sprintf("%s/%s?versionId=%s", input.CopySourceBucket, UrlEncode(input.CopySourceKey, false), input.CopySourceVersionId) 815 } else { 816 copySource = fmt.Sprintf("%s/%s", input.CopySourceBucket, UrlEncode(input.CopySourceKey, false)) 817 } 818 setHeaders(headers, HEADER_COPY_SOURCE, []string{copySource}, isObs) 819 if input.CopySourceRangeStart >= 0 && input.CopySourceRangeEnd > input.CopySourceRangeStart { 820 setHeaders(headers, HEADER_COPY_SOURCE_RANGE, []string{fmt.Sprintf("bytes=%d-%d", input.CopySourceRangeStart, input.CopySourceRangeEnd)}, isObs) 821 } 822 823 setSseHeader(headers, input.SseHeader, true, isObs) 824 if input.SourceSseHeader != nil { 825 if sseCHeader, ok := input.SourceSseHeader.(SseCHeader); ok { 826 setHeaders(headers, HEADER_SSEC_COPY_SOURCE_ENCRYPTION, []string{sseCHeader.GetEncryption()}, isObs) 827 setHeaders(headers, HEADER_SSEC_COPY_SOURCE_KEY, []string{sseCHeader.GetKey()}, isObs) 828 setHeaders(headers, HEADER_SSEC_COPY_SOURCE_KEY_MD5, []string{sseCHeader.GetKeyMD5()}, isObs) 829 } 830 831 } 832 return 833 } 834 835 func (input HeadObjectInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 836 params = make(map[string]string) 837 if input.VersionId != "" { 838 params[PARAM_VERSION_ID] = input.VersionId 839 } 840 return 841 } 842 843 func (input SetBucketRequestPaymentInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 844 return trans(SubResourceRequestPayment, input) 845 } 846 847 type partSlice []Part 848 849 func (parts partSlice) Len() int { 850 return len(parts) 851 } 852 853 func (parts partSlice) Less(i, j int) bool { 854 return parts[i].PartNumber < parts[j].PartNumber 855 } 856 857 func (parts partSlice) Swap(i, j int) { 858 parts[i], parts[j] = parts[j], parts[i] 859 } 860 861 type readerWrapper struct { 862 reader io.Reader 863 mark int64 864 totalCount int64 865 readedCount int64 866 } 867 868 func (rw *readerWrapper) seek(offset int64, whence int) (int64, error) { 869 if r, ok := rw.reader.(*strings.Reader); ok { 870 return r.Seek(offset, whence) 871 } else if r, ok := rw.reader.(*bytes.Reader); ok { 872 return r.Seek(offset, whence) 873 } else if r, ok := rw.reader.(*os.File); ok { 874 return r.Seek(offset, whence) 875 } 876 return offset, nil 877 } 878 879 func (rw *readerWrapper) Read(p []byte) (n int, err error) { 880 if rw.totalCount == 0 { 881 return 0, io.EOF 882 } 883 if rw.totalCount > 0 { 884 n, err = rw.reader.Read(p) 885 readedOnce := int64(n) 886 remainCount := rw.totalCount - rw.readedCount 887 if remainCount > readedOnce { 888 rw.readedCount += readedOnce 889 return n, err 890 } 891 rw.readedCount += remainCount 892 return int(remainCount), io.EOF 893 } 894 return rw.reader.Read(p) 895 } 896 897 type fileReaderWrapper struct { 898 readerWrapper 899 filePath string 900 } 901 902 func (input SetBucketFetchPolicyInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 903 contentType, _ := mimeTypes["json"] 904 headers = make(map[string][]string, 2) 905 headers[HEADER_CONTENT_TYPE] = []string{contentType} 906 setHeaders(headers, headerOefMarker, []string{"yes"}, isObs) 907 data, err = convertFetchPolicyToJSON(input) 908 return 909 } 910 911 func (input GetBucketFetchPolicyInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 912 headers = make(map[string][]string, 1) 913 setHeaders(headers, headerOefMarker, []string{"yes"}, isObs) 914 return 915 } 916 917 func (input DeleteBucketFetchPolicyInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 918 headers = make(map[string][]string, 1) 919 setHeaders(headers, headerOefMarker, []string{"yes"}, isObs) 920 return 921 } 922 923 func (input SetBucketFetchJobInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 924 contentType, _ := mimeTypes["json"] 925 headers = make(map[string][]string, 2) 926 headers[HEADER_CONTENT_TYPE] = []string{contentType} 927 setHeaders(headers, headerOefMarker, []string{"yes"}, isObs) 928 data, err = convertFetchJobToJSON(input) 929 return 930 } 931 932 func (input GetBucketFetchJobInput) trans(isObs bool) (params map[string]string, headers map[string][]string, data interface{}, err error) { 933 headers = make(map[string][]string, 1) 934 setHeaders(headers, headerOefMarker, []string{"yes"}, isObs) 935 return 936 }