github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/obs/client_part.go (about) 1 package obs 2 3 import ( 4 "errors" 5 "io" 6 "os" 7 "sort" 8 "strings" 9 ) 10 11 // ListMultipartUploads lists the multipart uploads. 12 // 13 // You can use this API to list the multipart uploads that are initialized but not combined or aborted in a specified bucket. 14 func (obsClient ObsClient) ListMultipartUploads(input *ListMultipartUploadsInput) (output *ListMultipartUploadsOutput, err error) { 15 if input == nil { 16 return nil, errors.New("ListMultipartUploadsInput is nil") 17 } 18 output = &ListMultipartUploadsOutput{} 19 err = obsClient.doActionWithBucket("ListMultipartUploads", HTTP_GET, input.Bucket, input, output) 20 if err != nil { 21 output = nil 22 } 23 return 24 } 25 26 // AbortMultipartUpload aborts a multipart upload in a specified bucket by using the multipart upload ID. 27 func (obsClient ObsClient) AbortMultipartUpload(input *AbortMultipartUploadInput) (output *BaseModel, err error) { 28 if input == nil { 29 return nil, errors.New("AbortMultipartUploadInput is nil") 30 } 31 if input.UploadId == "" { 32 return nil, errors.New("UploadId is empty") 33 } 34 output = &BaseModel{} 35 err = obsClient.doActionWithBucketAndKey("AbortMultipartUpload", HTTP_DELETE, input.Bucket, input.Key, input, output) 36 if err != nil { 37 output = nil 38 } 39 return 40 } 41 42 // InitiateMultipartUpload initializes a multipart upload. 43 func (obsClient ObsClient) InitiateMultipartUpload(input *InitiateMultipartUploadInput) (output *InitiateMultipartUploadOutput, err error) { 44 if input == nil { 45 return nil, errors.New("InitiateMultipartUploadInput is nil") 46 } 47 48 if input.ContentType == "" && input.Key != "" { 49 if contentType, ok := mimeTypes[strings.ToLower(input.Key[strings.LastIndex(input.Key, ".")+1:])]; ok { 50 input.ContentType = contentType 51 } 52 } 53 54 output = &InitiateMultipartUploadOutput{} 55 err = obsClient.doActionWithBucketAndKey("InitiateMultipartUpload", HTTP_POST, input.Bucket, input.Key, input, output) 56 if err != nil { 57 output = nil 58 } else { 59 ParseInitiateMultipartUploadOutput(output) 60 } 61 return 62 } 63 64 // UploadPart uploads a part to a specified bucket by using a specified multipart upload ID. 65 // 66 // After a multipart upload is initialized, you can use this API to upload a part to a specified bucket 67 // by using the multipart upload ID. Except for the last uploaded part whose size ranges from 0 to 5 GB, 68 // sizes of the other parts range from 100 KB to 5 GB. The upload part ID ranges from 1 to 10000. 69 func (obsClient ObsClient) UploadPart(_input *UploadPartInput) (output *UploadPartOutput, err error) { 70 if _input == nil { 71 return nil, errors.New("UploadPartInput is nil") 72 } 73 74 if _input.UploadId == "" { 75 return nil, errors.New("UploadId is empty") 76 } 77 78 input := &UploadPartInput{} 79 input.Bucket = _input.Bucket 80 input.Key = _input.Key 81 input.PartNumber = _input.PartNumber 82 input.UploadId = _input.UploadId 83 input.ContentMD5 = _input.ContentMD5 84 input.SourceFile = _input.SourceFile 85 input.Offset = _input.Offset 86 input.PartSize = _input.PartSize 87 input.SseHeader = _input.SseHeader 88 input.Body = _input.Body 89 90 output = &UploadPartOutput{} 91 var repeatable bool 92 if input.Body != nil { 93 _, repeatable = input.Body.(*strings.Reader) 94 if _, ok := input.Body.(*readerWrapper); !ok && input.PartSize > 0 { 95 input.Body = &readerWrapper{reader: input.Body, totalCount: input.PartSize} 96 } 97 } else if sourceFile := strings.TrimSpace(input.SourceFile); sourceFile != "" { 98 fd, _err := os.Open(sourceFile) 99 if _err != nil { 100 err = _err 101 return nil, err 102 } 103 defer func() { 104 errMsg := fd.Close() 105 if errMsg != nil { 106 doLog(LEVEL_WARN, "Failed to close file with reason: %v", errMsg) 107 } 108 }() 109 110 stat, _err := fd.Stat() 111 if _err != nil { 112 err = _err 113 return nil, err 114 } 115 fileSize := stat.Size() 116 fileReaderWrapper := &fileReaderWrapper{filePath: sourceFile} 117 fileReaderWrapper.reader = fd 118 119 if input.Offset < 0 || input.Offset > fileSize { 120 input.Offset = 0 121 } 122 123 if input.PartSize <= 0 || input.PartSize > (fileSize-input.Offset) { 124 input.PartSize = fileSize - input.Offset 125 } 126 fileReaderWrapper.totalCount = input.PartSize 127 if _, err = fd.Seek(input.Offset, io.SeekStart); err != nil { 128 return nil, err 129 } 130 input.Body = fileReaderWrapper 131 repeatable = true 132 } 133 if repeatable { 134 err = obsClient.doActionWithBucketAndKey("UploadPart", HTTP_PUT, input.Bucket, input.Key, input, output) 135 } else { 136 err = obsClient.doActionWithBucketAndKeyUnRepeatable("UploadPart", HTTP_PUT, input.Bucket, input.Key, input, output) 137 } 138 if err != nil { 139 output = nil 140 } else { 141 ParseUploadPartOutput(output) 142 output.PartNumber = input.PartNumber 143 } 144 return 145 } 146 147 // CompleteMultipartUpload combines the uploaded parts in a specified bucket by using the multipart upload ID. 148 func (obsClient ObsClient) CompleteMultipartUpload(input *CompleteMultipartUploadInput) (output *CompleteMultipartUploadOutput, err error) { 149 if input == nil { 150 return nil, errors.New("CompleteMultipartUploadInput is nil") 151 } 152 153 if input.UploadId == "" { 154 return nil, errors.New("UploadId is empty") 155 } 156 157 var parts partSlice = input.Parts 158 sort.Sort(parts) 159 160 output = &CompleteMultipartUploadOutput{} 161 err = obsClient.doActionWithBucketAndKey("CompleteMultipartUpload", HTTP_POST, input.Bucket, input.Key, input, output) 162 if err != nil { 163 output = nil 164 } else { 165 ParseCompleteMultipartUploadOutput(output) 166 } 167 return 168 } 169 170 // ListParts lists the uploaded parts in a bucket by using the multipart upload ID. 171 func (obsClient ObsClient) ListParts(input *ListPartsInput) (output *ListPartsOutput, err error) { 172 if input == nil { 173 return nil, errors.New("ListPartsInput is nil") 174 } 175 if input.UploadId == "" { 176 return nil, errors.New("UploadId is empty") 177 } 178 output = &ListPartsOutput{} 179 err = obsClient.doActionWithBucketAndKey("ListParts", HTTP_GET, input.Bucket, input.Key, input, output) 180 if err != nil { 181 output = nil 182 } 183 return 184 } 185 186 // CopyPart copy a part to a specified bucket by using a specified multipart upload ID. 187 // 188 // 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. 189 func (obsClient ObsClient) CopyPart(input *CopyPartInput) (output *CopyPartOutput, err error) { 190 if input == nil { 191 return nil, errors.New("CopyPartInput is nil") 192 } 193 if input.UploadId == "" { 194 return nil, errors.New("UploadId is empty") 195 } 196 if strings.TrimSpace(input.CopySourceBucket) == "" { 197 return nil, errors.New("Source bucket is empty") 198 } 199 if strings.TrimSpace(input.CopySourceKey) == "" { 200 return nil, errors.New("Source key is empty") 201 } 202 203 output = &CopyPartOutput{} 204 err = obsClient.doActionWithBucketAndKey("CopyPart", HTTP_PUT, input.Bucket, input.Key, input, output) 205 if err != nil { 206 output = nil 207 } else { 208 ParseCopyPartOutput(output) 209 output.PartNumber = input.PartNumber 210 } 211 return 212 }