1/* 2 * Minio Go Library for Amazon S3 Compatible Cloud Storage 3 * Copyright 2017, 2018 Minio, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package minio 19 20import ( 21 "context" 22 "io" 23 "io/ioutil" 24 "net/http" 25 26 "github.com/minio/minio-go/pkg/encrypt" 27) 28 29// CopyObject - copy a source object into a new object 30func (c Client) CopyObject(dst DestinationInfo, src SourceInfo) error { 31 return c.CopyObjectWithProgress(dst, src, nil) 32} 33 34// CopyObjectWithProgress - copy a source object into a new object, optionally takes 35// progress bar input to notify current progress. 36func (c Client) CopyObjectWithProgress(dst DestinationInfo, src SourceInfo, progress io.Reader) error { 37 header := make(http.Header) 38 for k, v := range src.Headers { 39 header[k] = v 40 } 41 42 var err error 43 var size int64 44 // If progress bar is specified, size should be requested as well initiate a StatObject request. 45 if progress != nil { 46 size, _, _, err = src.getProps(c) 47 if err != nil { 48 return err 49 } 50 } 51 52 if src.encryption != nil { 53 encrypt.SSECopy(src.encryption).Marshal(header) 54 } 55 56 if dst.encryption != nil { 57 dst.encryption.Marshal(header) 58 } 59 for k, v := range dst.getUserMetaHeadersMap(true) { 60 header.Set(k, v) 61 } 62 63 resp, err := c.executeMethod(context.Background(), "PUT", requestMetadata{ 64 bucketName: dst.bucket, 65 objectName: dst.object, 66 customHeader: header, 67 }) 68 if err != nil { 69 return err 70 } 71 defer closeResponse(resp) 72 73 if resp.StatusCode != http.StatusOK { 74 return httpRespToErrorResponse(resp, dst.bucket, dst.object) 75 } 76 77 // Update the progress properly after successful copy. 78 if progress != nil { 79 io.CopyN(ioutil.Discard, progress, size) 80 } 81 82 return nil 83} 84