Copy object API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html .
(w http.ResponseWriter, r *http.Request)
| 717 | // Copy object |
| 718 | // API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html . |
| 719 | func (o *ObjectNode) copyObjectHandler(w http.ResponseWriter, r *http.Request) { |
| 720 | var ( |
| 721 | err error |
| 722 | errorCode *ErrorCode |
| 723 | ) |
| 724 | |
| 725 | span := trace.SpanFromContextSafe(r.Context()) |
| 726 | defer func() { |
| 727 | o.errorResponse(w, r, err, errorCode) |
| 728 | }() |
| 729 | |
| 730 | param := ParseRequestParam(r) |
| 731 | if param.Bucket() == "" { |
| 732 | errorCode = InvalidBucketName |
| 733 | return |
| 734 | } |
| 735 | if param.Object() == "" { |
| 736 | errorCode = InvalidKey |
| 737 | return |
| 738 | } |
| 739 | if len(param.Object()) > MaxKeyLength { |
| 740 | errorCode = KeyTooLong |
| 741 | return |
| 742 | } |
| 743 | var vol *Volume |
| 744 | if vol, err = o.getVol(param.Bucket()); err != nil { |
| 745 | log.LogErrorf("copyObjectHandler: load volume fail: requestID(%v) volume(%v) err(%v)", |
| 746 | GetRequestID(r), param.Bucket(), err) |
| 747 | return |
| 748 | } |
| 749 | |
| 750 | // QPS and Concurrency Limit |
| 751 | rateLimit := o.AcquireRateLimiter() |
| 752 | if err = rateLimit.AcquireLimitResource(vol.owner, param.apiName); err != nil { |
| 753 | return |
| 754 | } |
| 755 | defer rateLimit.ReleaseLimitResource(vol.owner, param.apiName) |
| 756 | |
| 757 | // client can reset these system metadata: Content-Type, Content-Disposition |
| 758 | contentType := r.Header.Get(ContentType) |
| 759 | contentDisposition := r.Header.Get(ContentDisposition) |
| 760 | cacheControl := r.Header.Get(CacheControl) |
| 761 | if len(cacheControl) > 0 && !ValidateCacheControl(cacheControl) { |
| 762 | errorCode = InvalidCacheArgument |
| 763 | return |
| 764 | } |
| 765 | expires := r.Header.Get(Expires) |
| 766 | if len(expires) > 0 && !ValidateCacheExpires(expires) { |
| 767 | errorCode = InvalidCacheArgument |
| 768 | return |
| 769 | } |
| 770 | |
| 771 | // metadata directive, direct object node use source file metadata or recreate metadata for target file |
| 772 | metadataDirective := r.Header.Get(XAmzMetadataDirective) |
| 773 | // metadata directive default value is COPY |
| 774 | if len(metadataDirective) == 0 { |
| 775 | metadataDirective = MetadataDirectiveCopy |
| 776 | } |
nothing calls this directly
no test coverage detected