From 52481375b07aaa1d9b1ac6a2c76f49cb177eb252 Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Tue, 6 May 2025 11:37:28 +0300 Subject: [PATCH] [#240] Fix native index page Signed-off-by: Denis Kirillov --- internal/handler/browse.go | 16 ++++---- internal/handler/handler_test.go | 68 ++++++++++++++++++++++++++++++-- internal/templates/index.gotmpl | 22 ++--------- 3 files changed, 76 insertions(+), 30 deletions(-) diff --git a/internal/handler/browse.go b/internal/handler/browse.go index 1dc23a3..5296bab 100644 --- a/internal/handler/browse.go +++ b/internal/handler/browse.go @@ -76,13 +76,13 @@ func newListObjectsResponseNative(attrs map[string]string) ResponseObject { } } -func getNextDir(filepath, prefix string) string { +func getNextDir(filepath, prefix string) *string { restPath := strings.Replace(filepath, prefix, "", 1) index := strings.Index(restPath, "/") if index == -1 { - return "" + return nil } - return restPath[:index] + return ptr(restPath[:index]) } func lastPathElement(path string) string { @@ -143,7 +143,7 @@ func getParent(encPrefix string) string { if slashIndex == -1 { return "" } - return prefix[:slashIndex] + return prefix[:slashIndex+1] } func urlencode(path string) string { @@ -259,7 +259,7 @@ func (h *Handler) getDirObjectsNative(ctx context.Context, bucketInfo *data.Buck if _, ok := dirs[objExt.Object.FileName]; ok { continue } - objExt.Object.GetURL = "/get/" + bucketInfo.CID.EncodeToString() + urlencode(objExt.Object.FilePath) + objExt.Object.GetURL = "/get/" + bucketInfo.CID.EncodeToString() + "/" + urlencode(objExt.Object.FilePath) dirs[objExt.Object.FileName] = struct{}{} } else { objExt.Object.GetURL = "/get/" + bucketInfo.CID.EncodeToString() + "/" + objExt.Object.OID @@ -331,13 +331,13 @@ func (h *Handler) headDirObject(ctx context.Context, cnrID cid.ID, objID oid.ID, } dirname := getNextDir(attrs[object.AttributeFilePath], basePath) - if dirname == "" { + if dirname == nil { return newListObjectsResponseNative(attrs), nil } return ResponseObject{ - FileName: dirname, - FilePath: basePath + dirname, + FileName: *dirname, + FilePath: basePath + *dirname, IsDir: true, }, nil } diff --git a/internal/handler/handler_test.go b/internal/handler/handler_test.go index 6c715fe..eddb7c6 100644 --- a/internal/handler/handler_test.go +++ b/internal/handler/handler_test.go @@ -520,15 +520,23 @@ func TestIndex(t *testing.T) { obj1.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "prefix/obj1")) hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1 + obj2ID := oidtest.ID() + obj2 := object.New() + obj2.SetID(obj2ID) + obj2.SetPayload([]byte("obj2")) + obj2.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "/dir/..")) + hc.frostfs.objects[cnrID.String()+"/"+obj2ID.String()] = obj2 + hc.tree.containers[cnrID.String()] = containerInfo{ trees: map[string]map[string]nodeResponse{ "system": {"bucket-settings": nodeResponse{nodeID: 1}}, "version": { - "": nodeResponse{}, //root + "": nodeResponse{}, //root "prefix": nodeResponse{ nodeID: 1, - meta: []nodeMeta{{key: tree.FileNameKey, value: []byte("prefix")}}}, - "obj1": nodeResponse{ + meta: []nodeMeta{{key: tree.FileNameKey, value: []byte("prefix")}}, + }, + "prefix/obj1": nodeResponse{ parentID: 1, nodeID: 2, meta: []nodeMeta{ @@ -536,6 +544,23 @@ func TestIndex(t *testing.T) { {key: "OID", value: []byte(obj1ID.String())}, }, }, + "": nodeResponse{ + nodeID: 3, + meta: []nodeMeta{{key: tree.FileNameKey, value: []byte("")}}, + }, + "/dir": nodeResponse{ + parentID: 3, + nodeID: 4, + meta: []nodeMeta{{key: tree.FileNameKey, value: []byte("dir")}}, + }, + "/dir/..": nodeResponse{ + parentID: 4, + nodeID: 5, + meta: []nodeMeta{ + {key: tree.FileNameKey, value: []byte("..")}, + {key: "OID", value: []byte(obj2ID.String())}, + }, + }, }, }, } @@ -563,6 +588,21 @@ func TestIndex(t *testing.T) { r = prepareGetRequest(ctx, "bucket", "dummy") hc.Handler().DownloadByAddressOrBucketName(r) require.Contains(t, string(r.Response.Body()), "Index of s3://bucket/dummy") + + r = prepareGetRequest(ctx, "bucket", "") + hc.Handler().DownloadByAddressOrBucketName(r) + require.Contains(t, string(r.Response.Body()), `..`) + require.Contains(t, string(r.Response.Body()), `/`) + + r = prepareGetRequest(ctx, "bucket", "/") + hc.Handler().DownloadByAddressOrBucketName(r) + require.Contains(t, string(r.Response.Body()), `..`) + require.Contains(t, string(r.Response.Body()), `dir/`) + + r = prepareGetRequest(ctx, "bucket", "/dir/") + hc.Handler().DownloadByAddressOrBucketName(r) + require.Contains(t, string(r.Response.Body()), `..`) + require.Contains(t, string(r.Response.Body()), `..`) }) t.Run("native", func(t *testing.T) { @@ -575,6 +615,13 @@ func TestIndex(t *testing.T) { obj1.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "prefix/obj1")) hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1 + obj2ID := oidtest.ID() + obj2 := object.New() + obj2.SetID(obj2ID) + obj2.SetPayload([]byte("obj2")) + obj2.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "/dir/..")) + hc.frostfs.objects[cnrID.String()+"/"+obj2ID.String()] = obj2 + r := prepareGetRequest(ctx, cnrID.EncodeToString(), "prefix/") hc.Handler().DownloadByAddressOrBucketName(r) require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode()) @@ -598,6 +645,21 @@ func TestIndex(t *testing.T) { r = prepareGetRequest(ctx, cnrID.EncodeToString(), "dummy") hc.Handler().DownloadByAddressOrBucketName(r) require.Contains(t, string(r.Response.Body()), "Index of frostfs://"+cnrID.String()+"/dummy") + + r = prepareGetRequest(ctx, cnrID.EncodeToString(), "") + hc.Handler().DownloadByAddressOrBucketName(r) + require.Contains(t, string(r.Response.Body()), `..`) + require.Contains(t, string(r.Response.Body()), `/`) + + r = prepareGetRequest(ctx, cnrID.EncodeToString(), "/") + hc.Handler().DownloadByAddressOrBucketName(r) + require.Contains(t, string(r.Response.Body()), `..`) + require.Contains(t, string(r.Response.Body()), `dir/`) + + r = prepareGetRequest(ctx, cnrID.EncodeToString(), "/dir/") + hc.Handler().DownloadByAddressOrBucketName(r) + require.Contains(t, string(r.Response.Body()), `..`) + require.Contains(t, string(r.Response.Body()), `..`) }) } diff --git a/internal/templates/index.gotmpl b/internal/templates/index.gotmpl index 4c03404..9ce0f5b 100644 --- a/internal/templates/index.gotmpl +++ b/internal/templates/index.gotmpl @@ -56,40 +56,24 @@ {{ $parentPrefix := getParent .Prefix }} - {{if $parentPrefix }} - ⮐.. + ⮐.. - {{else}} - - - ⮐.. - - - - - - - {{end}} {{range .Objects}} {{if .IsDir}} 🗀 - - {{.FileName}}/ - + {{.FileName}}/ {{else}} 🗎 - - {{.FileName}} - + {{.FileName}} {{end}} {{.OID}}