mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
fix: zip error races in WebDownload (#12086)
When an error is reported it is ignored and zipping continues with the next object. However, if there is an error it will write a response to `writeWebErrorResponse(w, err)`, but responses are still being built. Fixes #12082 Bonus: Exclude common compressed image types.
This commit is contained in:
parent
49b7923309
commit
3d685b7fff
@ -29,7 +29,7 @@ import (
|
||||
"github.com/minio/minio/pkg/handlers"
|
||||
"github.com/minio/minio/pkg/kms"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/minio/minio/cmd/config/cache"
|
||||
"github.com/minio/minio/cmd/config/compress"
|
||||
"github.com/minio/minio/cmd/config/dns"
|
||||
@ -258,7 +258,7 @@ var (
|
||||
globalCompressConfig compress.Config
|
||||
|
||||
// Some standard object extensions which we strictly dis-allow for compression.
|
||||
standardExcludeCompressExtensions = []string{".gz", ".bz2", ".rar", ".zip", ".7z", ".xz", ".mp4", ".mkv", ".mov"}
|
||||
standardExcludeCompressExtensions = []string{".gz", ".bz2", ".rar", ".zip", ".7z", ".xz", ".mp4", ".mkv", ".mov", ".jpg", ".png", ".gif"}
|
||||
|
||||
// Some standard content-types which we strictly dis-allow for compression.
|
||||
standardExcludeCompressContentTypes = []string{"video/*", "audio/*", "application/zip", "application/x-gzip", "application/x-zip-compressed", " application/x-compress", "application/x-spoon"}
|
||||
|
@ -1688,6 +1688,9 @@ func (web *webAPIHandlers) DownloadZip(w http.ResponseWriter, r *http.Request) {
|
||||
respElements := extractRespElements(w)
|
||||
|
||||
for i, object := range args.Objects {
|
||||
if contextCanceled(ctx) {
|
||||
return
|
||||
}
|
||||
// Writes compressed object file to the response.
|
||||
zipit := func(objectName string) error {
|
||||
var opts ObjectOptions
|
||||
@ -1706,38 +1709,26 @@ func (web *webAPIHandlers) DownloadZip(w http.ResponseWriter, r *http.Request) {
|
||||
return err
|
||||
}
|
||||
header := &zip.FileHeader{
|
||||
Name: strings.TrimPrefix(objectName, args.Prefix),
|
||||
Method: zip.Deflate,
|
||||
Flags: 1 << 11,
|
||||
Modified: info.ModTime,
|
||||
Name: strings.TrimPrefix(objectName, args.Prefix),
|
||||
Method: zip.Deflate,
|
||||
Flags: 1 << 11,
|
||||
Modified: info.ModTime,
|
||||
UncompressedSize64: uint64(info.Size),
|
||||
}
|
||||
if hasStringSuffixInSlice(info.Name, standardExcludeCompressExtensions) || hasPattern(standardExcludeCompressContentTypes, info.ContentType) {
|
||||
if info.Size < 20 || hasStringSuffixInSlice(info.Name, standardExcludeCompressExtensions) || hasPattern(standardExcludeCompressContentTypes, info.ContentType) {
|
||||
// We strictly disable compression for standard extensions/content-types.
|
||||
header.Method = zip.Store
|
||||
}
|
||||
writer, err := archive.CreateHeader(header)
|
||||
if err != nil {
|
||||
writeWebErrorResponse(w, errUnexpected)
|
||||
return err
|
||||
}
|
||||
httpWriter := ioutil.WriteOnClose(writer)
|
||||
|
||||
// Write object content to response body
|
||||
if _, err = io.Copy(httpWriter, gr); err != nil {
|
||||
httpWriter.Close()
|
||||
if !httpWriter.HasWritten() { // write error response only if no data or headers has been written to client yet
|
||||
writeWebErrorResponse(w, err)
|
||||
}
|
||||
if _, err = io.Copy(writer, gr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = httpWriter.Close(); err != nil {
|
||||
if !httpWriter.HasWritten() { // write error response only if no data has been written to client yet
|
||||
writeWebErrorResponse(w, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Notify object accessed via a GET request.
|
||||
sendEvent(eventArgs{
|
||||
EventName: event.ObjectAccessedGet,
|
||||
|
Loading…
Reference in New Issue
Block a user