1
0
mirror of https://github.com/minio/mc.git synced 2025-07-30 07:23:03 +03:00

Allow copying file onto itself (#2617)

This allows encrypting an unencrypted file
using server side CopyObject API.
This commit is contained in:
Harshavardhana
2018-12-06 10:18:16 -08:00
committed by kannappanr
parent f3eaa54a32
commit 2073642656
4 changed files with 8 additions and 58 deletions

View File

@ -365,58 +365,19 @@ func readFile(fpath string) (io.ReadCloser, error) {
return fileData, nil
}
// createFile creates an empty file at the provided filepath
// if one does not exist already.
func createFile(fpath string) (io.WriteCloser, error) {
if e := os.MkdirAll(filepath.Dir(fpath), 0777); e != nil {
return nil, e
}
file, e := os.Create(fpath)
if e != nil {
return nil, e
}
return file, nil
}
// Copy - copy data from source to destination
func (f *fsClient) Copy(source string, size int64, progress io.Reader, srcSSEKey, tgtSSEKey string) *probe.Error {
// Don't use f.Get() f.Put() directly. Instead use readFile and createFile
destination := f.PathURL.Path
if destination == source { // Cannot copy file into itself
return probe.NewError(SameFile{
Source: source,
Destination: destination,
})
}
rc, e := readFile(source)
if e != nil {
err := f.toClientError(e, destination)
return err.Trace(destination)
}
defer rc.Close()
wc, e := createFile(destination)
if e != nil {
err := f.toClientError(e, destination)
return err.Trace(destination)
}
defer wc.Close()
reader := hookreader.NewHook(rc, progress)
// Perform copy
n, _ := io.CopyN(wc, reader, size) // e == nil only if n != size
// Only check size related errors if size is positive
if size > 0 {
if n < size { // Unexpected early EOF
return probe.NewError(UnexpectedEOF{
TotalSize: size,
TotalWritten: n,
})
}
if n > size { // Unexpected ExcessRead
return probe.NewError(UnexpectedExcessRead{
TotalSize: size,
TotalWritten: n,
})
}
_, err := f.put(rc, size, map[string][]string{}, progress)
if err != nil {
return err.Trace(destination, source)
}
return nil
}

View File

@ -594,7 +594,7 @@ func (c *s3Client) Get(sseKey string) (io.ReadCloser, *probe.Error) {
Bucket: bucket,
})
}
if errResponse.Code == "NoSuchKey" || errResponse.Code == "InvalidArgument" {
if errResponse.Code == "NoSuchKey" {
return nil, probe.NewError(ObjectMissing{})
}
return nil, probe.NewError(e)
@ -646,7 +646,7 @@ func (c *s3Client) Copy(source string, size int64, progress io.Reader, srcSSEKey
Bucket: dstBucket,
})
}
if errResponse.Code == "NoSuchKey" || errResponse.Code == "InvalidArgument" {
if errResponse.Code == "NoSuchKey" {
return probe.NewError(ObjectMissing{})
}
return probe.NewError(e)
@ -742,7 +742,7 @@ func (c *s3Client) Put(ctx context.Context, reader io.Reader, size int64, metada
Bucket: bucket,
})
}
if errResponse.Code == "NoSuchKey" || errResponse.Code == "InvalidArgument" {
if errResponse.Code == "NoSuchKey" {
return n, probe.NewError(ObjectMissing{})
}
return n, probe.NewError(e)
@ -1116,7 +1116,7 @@ func (c *s3Client) getObjectStat(bucket, object string, opts minio.StatObjectOpt
Bucket: bucket,
})
}
if errResponse.Code == "NoSuchKey" || errResponse.Code == "InvalidArgument" {
if errResponse.Code == "NoSuchKey" {
return nil, probe.NewError(ObjectMissing{})
}
return nil, probe.NewError(e)

View File

@ -97,10 +97,6 @@ func prepareCopyURLsTypeA(sourceURL string, targetURL string, encKeyDB map[strin
// Source is not a regular file
return URLs{Error: errInvalidSource(sourceURL).Trace(sourceURL)}
}
if sourceContent.URL.String() == targetURL {
// source and target can not be same
return URLs{Error: errSourceTargetSame(sourceURL).Trace(sourceURL)}
}
// All OK.. We can proceed. Type A
return makeCopyContentTypeA(sourceAlias, sourceContent, targetAlias, targetURL, encKeyDB)

View File

@ -111,10 +111,3 @@ var errSourceIsDir = func(URL string) *probe.Error {
msg := "Source `" + URL + "` is a folder."
return probe.NewError(sourceIsDirErr(errors.New(msg))).Untrace()
}
type sourceTargetSameErr error
var errSourceTargetSame = func(URL string) *probe.Error {
msg := "Source and target URL can not be same : " + URL
return probe.NewError(sourceTargetSameErr(errors.New(msg))).Untrace()
}