CopyObject - copy a source object into a new object
(ctx context.Context, dst CopyDestOptions, src CopySrcOptions)
| 25 | |
| 26 | // CopyObject - copy a source object into a new object |
| 27 | func (c *Client) CopyObject(ctx context.Context, dst CopyDestOptions, src CopySrcOptions) (UploadInfo, error) { |
| 28 | if err := src.validate(); err != nil { |
| 29 | return UploadInfo{}, err |
| 30 | } |
| 31 | |
| 32 | if err := dst.validate(); err != nil { |
| 33 | return UploadInfo{}, err |
| 34 | } |
| 35 | |
| 36 | header := make(http.Header) |
| 37 | dst.Marshal(header) |
| 38 | src.Marshal(header) |
| 39 | |
| 40 | resp, err := c.executeMethod(ctx, http.MethodPut, requestMetadata{ |
| 41 | bucketName: dst.Bucket, |
| 42 | objectName: dst.Object, |
| 43 | customHeader: header, |
| 44 | }) |
| 45 | if err != nil { |
| 46 | return UploadInfo{}, err |
| 47 | } |
| 48 | defer closeResponse(resp) |
| 49 | |
| 50 | if resp.StatusCode != http.StatusOK { |
| 51 | return UploadInfo{}, httpRespToErrorResponse(resp, dst.Bucket, dst.Object) |
| 52 | } |
| 53 | |
| 54 | // Update the progress properly after successful copy. |
| 55 | if dst.Progress != nil { |
| 56 | io.Copy(io.Discard, io.LimitReader(dst.Progress, dst.Size)) |
| 57 | } |
| 58 | |
| 59 | cpObjRes := copyObjectResult{} |
| 60 | if err = xmlDecoder(resp.Body, &cpObjRes); err != nil { |
| 61 | return UploadInfo{}, err |
| 62 | } |
| 63 | |
| 64 | // extract lifecycle expiry date and rule ID |
| 65 | expTime, ruleID := amzExpirationToExpiryDateRuleID(resp.Header.Get(amzExpiration)) |
| 66 | |
| 67 | return UploadInfo{ |
| 68 | Bucket: dst.Bucket, |
| 69 | Key: dst.Object, |
| 70 | LastModified: cpObjRes.LastModified, |
| 71 | ETag: trimEtag(cpObjRes.ETag), |
| 72 | VersionID: resp.Header.Get(amzVersionID), |
| 73 | Expiration: expTime, |
| 74 | ExpirationRuleID: ruleID, |
| 75 | }, nil |
| 76 | } |
no test coverage detected