|
|
@ -738,25 +738,20 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re |
|
|
|
// No need to compress for remote etcd calls
|
|
|
|
// No need to compress for remote etcd calls
|
|
|
|
// Pass the decompressed stream to such calls.
|
|
|
|
// Pass the decompressed stream to such calls.
|
|
|
|
if srcInfo.IsCompressed() && !isRemoteCallRequired(ctx, srcBucket, dstBucket, objectAPI) { |
|
|
|
if srcInfo.IsCompressed() && !isRemoteCallRequired(ctx, srcBucket, dstBucket, objectAPI) { |
|
|
|
var sreader io.Reader |
|
|
|
|
|
|
|
var swriter io.Writer |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Open a pipe for compression.
|
|
|
|
// Open a pipe for compression.
|
|
|
|
// Where snappyWriter is piped to srcInfo.Reader.
|
|
|
|
// Where pipeWriter is piped to srcInfo.Reader.
|
|
|
|
// gr writes to snappyWriter.
|
|
|
|
// gr writes to pipeWriter.
|
|
|
|
snappyReader, snappyWriter := io.Pipe() |
|
|
|
pipeReader, pipeWriter := io.Pipe() |
|
|
|
reader = snappyReader |
|
|
|
reader = pipeReader |
|
|
|
length = -1 |
|
|
|
length = -1 |
|
|
|
|
|
|
|
|
|
|
|
swriter = snappy.NewWriter(snappyWriter) |
|
|
|
snappyWriter := snappy.NewWriter(pipeWriter) |
|
|
|
sreader = gr |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
defer snappyWriter.Close() |
|
|
|
|
|
|
|
// Compress the decompressed source object.
|
|
|
|
// Compress the decompressed source object.
|
|
|
|
if _, err = io.Copy(swriter, sreader); err != nil { |
|
|
|
_, cerr := io.Copy(snappyWriter, gr) |
|
|
|
return |
|
|
|
snappyWriter.Close() |
|
|
|
} |
|
|
|
pipeWriter.CloseWithError(cerr) |
|
|
|
}() |
|
|
|
}() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Remove the metadata for remote calls.
|
|
|
|
// Remove the metadata for remote calls.
|
|
|
@ -1102,7 +1097,6 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var hashError error |
|
|
|
|
|
|
|
actualSize := size |
|
|
|
actualSize := size |
|
|
|
|
|
|
|
|
|
|
|
if objectAPI.IsCompressionSupported() && isCompressible(r.Header, object) && size > 0 { |
|
|
|
if objectAPI.IsCompressionSupported() && isCompressible(r.Header, object) && size > 0 { |
|
|
@ -1113,21 +1107,21 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req |
|
|
|
pipeReader, pipeWriter := io.Pipe() |
|
|
|
pipeReader, pipeWriter := io.Pipe() |
|
|
|
snappyWriter := snappy.NewWriter(pipeWriter) |
|
|
|
snappyWriter := snappy.NewWriter(pipeWriter) |
|
|
|
|
|
|
|
|
|
|
|
actualReader, err := hash.NewReader(reader, size, md5hex, sha256hex, actualSize) |
|
|
|
var actualReader *hash.Reader |
|
|
|
|
|
|
|
actualReader, err = hash.NewReader(reader, size, md5hex, sha256hex, actualSize) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL) |
|
|
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
defer pipeWriter.Close() |
|
|
|
|
|
|
|
defer snappyWriter.Close() |
|
|
|
|
|
|
|
// Writing to the compressed writer.
|
|
|
|
// Writing to the compressed writer.
|
|
|
|
_, err = io.CopyN(snappyWriter, actualReader, actualSize) |
|
|
|
_, cerr := io.CopyN(snappyWriter, actualReader, actualSize) |
|
|
|
if err != nil { |
|
|
|
snappyWriter.Close() |
|
|
|
hashError = err |
|
|
|
pipeWriter.CloseWithError(cerr) |
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
// Set compression metrics.
|
|
|
|
// Set compression metrics.
|
|
|
|
size = -1 // Since compressed size is un-predictable.
|
|
|
|
size = -1 // Since compressed size is un-predictable.
|
|
|
|
md5hex = "" // Do not try to verify the content.
|
|
|
|
md5hex = "" // Do not try to verify the content.
|
|
|
@ -1197,15 +1191,6 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if hashError != nil { |
|
|
|
|
|
|
|
if hashError == io.ErrUnexpectedEOF { |
|
|
|
|
|
|
|
writeErrorResponse(w, ErrIncompleteBody, r.URL) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
writeErrorResponse(w, toAPIErrorCode(hashError), r.URL) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writeSuccessResponseHeadersOnly(w) |
|
|
|
writeSuccessResponseHeadersOnly(w) |
|
|
|
|
|
|
|
|
|
|
|
// Get host and port from Request.RemoteAddr.
|
|
|
|
// Get host and port from Request.RemoteAddr.
|
|
|
@ -1458,25 +1443,20 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt |
|
|
|
|
|
|
|
|
|
|
|
// Need to decompress only for range-enabled copy parts.
|
|
|
|
// Need to decompress only for range-enabled copy parts.
|
|
|
|
if srcInfo.IsCompressed() && rangeHeader != "" { |
|
|
|
if srcInfo.IsCompressed() && rangeHeader != "" { |
|
|
|
var sreader io.Reader |
|
|
|
|
|
|
|
var swriter io.Writer |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Open a pipe for compression.
|
|
|
|
// Open a pipe for compression.
|
|
|
|
// Where snappyWriter is piped to srcInfo.Reader.
|
|
|
|
// Where pipeWriter is piped to srcInfo.Reader.
|
|
|
|
// gr writes to snappyWriter.
|
|
|
|
// gr writes to pipeWriter.
|
|
|
|
snappyReader, snappyWriter := io.Pipe() |
|
|
|
pipeReader, pipeWriter := io.Pipe() |
|
|
|
reader = snappyReader |
|
|
|
reader = pipeReader |
|
|
|
length = -1 |
|
|
|
length = -1 |
|
|
|
|
|
|
|
|
|
|
|
swriter = snappy.NewWriter(snappyWriter) |
|
|
|
snappyWriter := snappy.NewWriter(pipeWriter) |
|
|
|
sreader = gr |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
defer snappyWriter.Close() |
|
|
|
|
|
|
|
// Compress the decompressed source object.
|
|
|
|
// Compress the decompressed source object.
|
|
|
|
if _, err = io.Copy(swriter, sreader); err != nil { |
|
|
|
_, cerr := io.Copy(snappyWriter, gr) |
|
|
|
return |
|
|
|
snappyWriter.Close() |
|
|
|
} |
|
|
|
pipeWriter.CloseWithError(cerr) |
|
|
|
}() |
|
|
|
}() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
reader = gr |
|
|
|
reader = gr |
|
|
@ -1692,21 +1672,21 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http |
|
|
|
if objectAPI.IsCompressionSupported() && compressPart { |
|
|
|
if objectAPI.IsCompressionSupported() && compressPart { |
|
|
|
pipeReader, pipeWriter = io.Pipe() |
|
|
|
pipeReader, pipeWriter = io.Pipe() |
|
|
|
snappyWriter := snappy.NewWriter(pipeWriter) |
|
|
|
snappyWriter := snappy.NewWriter(pipeWriter) |
|
|
|
actualReader, err := hash.NewReader(reader, size, md5hex, sha256hex, actualSize) |
|
|
|
|
|
|
|
|
|
|
|
var actualReader *hash.Reader |
|
|
|
|
|
|
|
actualReader, err = hash.NewReader(reader, size, md5hex, sha256hex, actualSize) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL) |
|
|
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
defer pipeWriter.Close() |
|
|
|
|
|
|
|
defer snappyWriter.Close() |
|
|
|
|
|
|
|
// Writing to the compressed writer.
|
|
|
|
// Writing to the compressed writer.
|
|
|
|
_, err = io.CopyN(snappyWriter, actualReader, actualSize) |
|
|
|
_, cerr := io.CopyN(snappyWriter, actualReader, actualSize) |
|
|
|
if err != nil { |
|
|
|
snappyWriter.Close() |
|
|
|
// The ErrorResponse is already written in putObjectPart Handle.
|
|
|
|
pipeWriter.CloseWithError(cerr) |
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
// Set compression metrics.
|
|
|
|
// Set compression metrics.
|
|
|
|
size = -1 // Since compressed size is un-predictable.
|
|
|
|
size = -1 // Since compressed size is un-predictable.
|
|
|
|
md5hex = "" // Do not try to verify the content.
|
|
|
|
md5hex = "" // Do not try to verify the content.
|
|
|
|