[#XX] Fix s3 index page
Some checks failed
/ DCO (pull_request) Failing after 32s
/ Vulncheck (pull_request) Successful in 55s
/ Builds (pull_request) Successful in 1m11s
/ OCI image (pull_request) Successful in 1m51s
/ Lint (pull_request) Successful in 2m39s
/ Tests (pull_request) Successful in 57s
/ Integration tests (pull_request) Successful in 6m7s

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
Denis Kirillov 2025-05-05 18:03:12 +03:00
parent 96a22d98f2
commit d189455c92
4 changed files with 35 additions and 15 deletions

View file

@ -150,8 +150,11 @@ func urlencode(path string) string {
var res strings.Builder var res strings.Builder
prefixParts := strings.Split(path, "/") prefixParts := strings.Split(path, "/")
for _, prefixPart := range prefixParts { for i, prefixPart := range prefixParts {
prefixPart = "/" + url.PathEscape(prefixPart) prefixPart = url.PathEscape(prefixPart)
if i != 0 {
prefixPart = "/" + prefixPart
}
if prefixPart == "/." || prefixPart == "/.." { if prefixPart == "/." || prefixPart == "/.." {
prefixPart = url.PathEscape(prefixPart) prefixPart = url.PathEscape(prefixPart)
} }
@ -168,11 +171,16 @@ type GetObjectsResponse struct {
} }
func (h *Handler) getDirObjectsS3(ctx context.Context, bucketInfo *data.BucketInfo, prefix string) (*GetObjectsResponse, error) { func (h *Handler) getDirObjectsS3(ctx context.Context, bucketInfo *data.BucketInfo, prefix string) (*GetObjectsResponse, error) {
if prefix != "" && prefix[len(prefix)-1] == '/' { var treePrefix *string
prefix = prefix[:len(prefix)-1] if prefix != "" {
if prefix[len(prefix)-1] == '/' {
treePrefix = ptr(prefix[:len(prefix)-1])
} else {
treePrefix = &prefix
}
} }
nodes, err := h.tree.GetSubTreeByPrefix(ctx, bucketInfo, prefix, true) nodes, err := h.tree.GetSubTreeByPrefix(ctx, bucketInfo, treePrefix, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -193,14 +201,18 @@ func (h *Handler) getDirObjectsS3(ctx context.Context, bucketInfo *data.BucketIn
if obj.IsDeleteMarker { if obj.IsDeleteMarker {
continue continue
} }
obj.FilePath = prefix + "/" + obj.FileName obj.FilePath = prefix + obj.FileName
obj.GetURL = "/get/" + bucketInfo.Name + urlencode(obj.FilePath) obj.GetURL = "/get/" + bucketInfo.Name + "/" + urlencode(obj.FilePath)
result.objects = append(result.objects, obj) result.objects = append(result.objects, obj)
} }
return result, nil return result, nil
} }
func ptr(s string) *string {
return &s
}
func (h *Handler) getDirObjectsNative(ctx context.Context, bucketInfo *data.BucketInfo, prefix string) (*GetObjectsResponse, error) { func (h *Handler) getDirObjectsNative(ctx context.Context, bucketInfo *data.BucketInfo, prefix string) (*GetObjectsResponse, error) {
basePath := prefix basePath := prefix
if basePath != "" && basePath[len(basePath)-1] != '/' { if basePath != "" && basePath[len(basePath)-1] != '/' {

View file

@ -325,11 +325,12 @@ func (h *Handler) browseIndexMiddleware(fn ListFunc) MiddlewareFunc {
ctx, span := tracing.StartSpanFromContext(prm.Context, "handler.browseIndex") ctx, span := tracing.StartSpanFromContext(prm.Context, "handler.browseIndex")
defer span.End() defer span.End()
ctx = utils.SetReqLog(ctx, h.reqLogger(ctx).With( h.reqLogger(ctx).Info(logs.BrowseIndex,
zap.String("bucket", prm.BktInfo.Name), zap.String("bucket", prm.BktInfo.Name),
zap.String("container", prm.BktInfo.CID.EncodeToString()), zap.String("container", prm.BktInfo.CID.EncodeToString()),
zap.String("prefix", prm.Path), zap.String("prefix", prm.Path),
)) logs.TagField(logs.TagDatapath),
)
objects, err := fn(ctx, prm.BktInfo, prm.Path) objects, err := fn(ctx, prm.BktInfo, prm.Path)
if err != nil { if err != nil {

View file

@ -127,6 +127,7 @@ const (
EmptyAccessControlRequestMethodHeader = "empty Access-Control-Request-Method request header" EmptyAccessControlRequestMethodHeader = "empty Access-Control-Request-Method request header"
CORSRuleWasNotMatched = "cors rule was not matched" CORSRuleWasNotMatched = "cors rule was not matched"
CouldntCacheCors = "couldn't cache cors" CouldntCacheCors = "couldn't cache cors"
BrowseIndex = "browse index"
) )
// Log messages with the "external_storage" tag. // Log messages with the "external_storage" tag.

View file

@ -323,17 +323,23 @@ func pathFromName(objectName string) []string {
return strings.Split(objectName, separator) return strings.Split(objectName, separator)
} }
func (c *Tree) GetSubTreeByPrefix(ctx context.Context, bktInfo *data.BucketInfo, prefix string, latestOnly bool) ([]data.NodeInfo, error) { func (c *Tree) GetSubTreeByPrefix(ctx context.Context, bktInfo *data.BucketInfo, prefix *string, latestOnly bool) ([]data.NodeInfo, error) {
ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetSubTreeByPrefix") ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetSubTreeByPrefix")
defer span.End() defer span.End()
rootID, err := c.getPrefixNodeID(ctx, bktInfo, versionTree, strings.Split(prefix, separator)) rootID := []uint64{0}
var err error
if prefix != nil {
rootID, err = c.getPrefixNodeID(ctx, bktInfo, versionTree, strings.Split(*prefix, separator))
if err != nil { if err != nil {
if errors.Is(err, ErrNodeNotFound) { if errors.Is(err, ErrNodeNotFound) {
return nil, nil return nil, nil
} }
return nil, err return nil, err
} }
}
subTree, err := c.service.GetSubTree(ctx, bktInfo, versionTree, rootID, 2, false) subTree, err := c.service.GetSubTree(ctx, bktInfo, versionTree, rootID, 2, false)
if err != nil { if err != nil {
if errors.Is(err, ErrNodeNotFound) { if errors.Is(err, ErrNodeNotFound) {