diff --git a/cmd/object-api-common.go b/cmd/object-api-common.go index 46c47ae52..edb1ce542 100644 --- a/cmd/object-api-common.go +++ b/cmd/object-api-common.go @@ -247,6 +247,21 @@ func listObjects(ctx context.Context, obj ObjectLayer, bucket, prefix, marker, d return loi, nil } + if len(prefix) > 0 && maxKeys == 1 && delimiter == "" && marker == "" { + // Optimization for certain applications like + // - Cohesity + // - Actifio, Splunk etc. + // which send ListObjects requests where the actual object + // itself is the prefix and max-keys=1 in such scenarios + // we can simply verify locally if such an object exists + // to avoid the need for ListObjects(). + objInfo, err := obj.GetObjectInfo(ctx, bucket, prefix, ObjectOptions{NoLock: true}) + if err == nil { + loi.Objects = append(loi.Objects, objInfo) + return loi, nil + } + } + // For delimiter and prefix as '/' we do not list anything at all // since according to s3 spec we stop at the 'delimiter' // along // with the prefix. On a flat namespace with 'prefix' @@ -290,6 +305,13 @@ func listObjects(ctx context.Context, obj ObjectLayer, bucket, prefix, marker, d i := i walkResult, ok := <-walkResultCh if !ok { + if HasSuffix(prefix, SlashSeparator) { + objInfo, err := obj.GetObjectInfo(ctx, bucket, prefix, ObjectOptions{NoLock: true}) + if err == nil { + loi.Objects = append(loi.Objects, objInfo) + return loi, nil + } + } // Closed channel. eof = true break