Merge pull request #127 from KirillovDenis/bugfix/121-listObjects_prefix_as_key

[#121] Fixed directory listing
remotes/KirillovDenis/bugfix/681-fix_acl_parsing
Roman Khimov 2021-07-01 23:36:23 +03:00 committed by GitHub
commit abcbe8d690
3 changed files with 24 additions and 2 deletions

View File

@ -126,6 +126,7 @@ func (h *handler) listObjects(w http.ResponseWriter, r *http.Request) (*listObje
MaxKeys: arg.MaxKeys,
Delimiter: arg.Delimiter,
Marker: marker,
Version: arg.APIVersion,
})
if err != nil {
h.log.Error("something went wrong",

View File

@ -32,6 +32,7 @@ type (
Delimiter string
MaxKeys int
Marker string
Version int
}
)

View File

@ -8,6 +8,7 @@ import (
"io"
"net/url"
"sort"
"strings"
"time"
"github.com/nspcc-dev/neofs-api-go/pkg/client"
@ -116,6 +117,9 @@ var (
ErrObjectNotExists = errors.New("object not exists")
)
// ETag (hex encoded md5sum) of empty string.
const emptyETag = "d41d8cd98f00b204e9800998ecf8427e"
// NewLayer creates instance of layer. It checks credentials
// and establishes gRPC connection with node.
func NewLayer(log *zap.Logger, conns pool.Pool) Client {
@ -216,6 +220,8 @@ func (n *layer) ListObjects(ctx context.Context, p *ListObjectsParams) (*ListObj
ln = p.MaxKeys
}
mostRecentModified := time.Time{}
needDirectoryAsKey := p.Version == 2 && len(p.Prefix) > 0 && len(p.Delimiter) > 0 && strings.HasSuffix(p.Prefix, p.Delimiter)
result.Objects = make([]*ObjectInfo, 0, ln)
for _, id := range ids {
@ -251,6 +257,9 @@ func (n *layer) ListObjects(ctx context.Context, p *ListObjectsParams) (*ListObj
// sub-entities, then it is a file, else directory.
if oi := objectInfoFromMeta(bkt, meta, p.Prefix, p.Delimiter); oi != nil {
if needDirectoryAsKey && oi.Created.After(mostRecentModified) {
mostRecentModified = oi.Created
}
// use only unique dir names
if _, ok := uniqNames[oi.Name]; ok {
continue
@ -275,12 +284,23 @@ func (n *layer) ListObjects(ctx context.Context, p *ListObjectsParams) (*ListObj
result.NextMarker = result.Objects[len(result.Objects)-1].Name
}
for i, oi := range result.Objects {
index := 0
for _, oi := range result.Objects {
if isDir := uniqNames[oi.Name]; isDir {
result.Objects = append(result.Objects[:i], result.Objects[i+1:]...)
result.Objects = append(result.Objects[:index], result.Objects[index+1:]...)
result.Prefixes = append(result.Prefixes, oi.Name)
} else {
index++
}
}
if needDirectoryAsKey {
res := []*ObjectInfo{{
Name: p.Prefix,
Created: mostRecentModified,
HashSum: emptyETag,
}}
result.Objects = append(res, result.Objects...)
}
return &result, nil
}