From 47d74a5a77d5fa89955f2345c3b417c72aee1791 Mon Sep 17 00:00:00 2001 From: Roman Loginov Date: Tue, 4 Feb 2025 13:21:57 +0300 Subject: [PATCH 1/2] [#174] Add slash clipping for FileName attribute According to the FrostFS API specification, the FileName attribute cannot contain a slash at the beginning. Signed-off-by: Roman Loginov --- CHANGELOG.md | 1 + internal/handler/handler.go | 14 +++++++++++++- internal/handler/handler_test.go | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30fcf7a..51080bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This document outlines major changes between releases. ### Added - Add handling quota limit reached error (#187) +- Add slash clipping for FileName attribute (#174) ## [0.32.2] - 2025-02-03 diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 69aecbf..532cdc4 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -253,6 +253,10 @@ func (h *Handler) byAttribute(c *fasthttp.RequestCtx, handler func(context.Conte return } + if key == attrFileName { + val = prepareFileName(val) + } + log = log.With(zap.String("cid", cidParam), zap.String("attr_key", key), zap.String("attr_val", val)) bktInfo, err := h.getBucketInfo(ctx, cidParam, log) @@ -294,7 +298,7 @@ func (h *Handler) findObjectByAttribute(ctx context.Context, log *zap.Logger, cn switch { case errors.Is(err, io.EOF) && h.needSearchByFileName(attrKey, attrVal): log.Debug(logs.ObjectNotFoundByFilePathTrySearchByFileName, logs.TagField(logs.TagExternalStorage)) - return h.findObjectByAttribute(ctx, log, cnrID, attrFileName, attrVal) + return h.findObjectByAttribute(ctx, log, cnrID, attrFileName, prepareFileName(attrVal)) case errors.Is(err, io.EOF): log.Error(logs.ObjectNotFound, zap.Error(err), logs.TagField(logs.TagExternalStorage)) return oid.ID{}, fmt.Errorf("object not found: %w", err) @@ -315,6 +319,14 @@ func (h *Handler) needSearchByFileName(key, val string) bool { return strings.HasPrefix(val, "/") && strings.Count(val, "/") == 1 || !strings.Contains(val, "/") } +func prepareFileName(fileName string) string { + if strings.HasPrefix(fileName, "/") { + return fileName[1:] + } + + return fileName +} + // resolveContainer decode container id, if it's not a valid container id // then trey to resolve name using provided resolver. func (h *Handler) resolveContainer(ctx context.Context, containerID string) (*cid.ID, error) { diff --git a/internal/handler/handler_test.go b/internal/handler/handler_test.go index 53c9739..1638f9f 100644 --- a/internal/handler/handler_test.go +++ b/internal/handler/handler_test.go @@ -239,6 +239,10 @@ func TestBasic(t *testing.T) { r = prepareGetByAttributeRequest(ctx, bktName, keyAttr, valAttr) hc.Handler().DownloadByAttribute(r) require.Equal(t, content, string(r.Response.Body())) + + r = prepareGetByAttributeRequest(ctx, bktName, attrFileName, "/"+objFileName) + hc.Handler().DownloadByAttribute(r) + require.Equal(t, content, string(r.Response.Body())) }) t.Run("head by attribute", func(t *testing.T) { @@ -246,6 +250,11 @@ func TestBasic(t *testing.T) { hc.Handler().HeadByAttribute(r) require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID))) require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID))) + + r = prepareGetByAttributeRequest(ctx, bktName, attrFileName, "/"+objFileName) + hc.Handler().HeadByAttribute(r) + require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID))) + require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID))) }) t.Run("zip", func(t *testing.T) { @@ -293,8 +302,8 @@ func TestFindObjectByAttribute(t *testing.T) { err = json.Unmarshal(r.Response.Body(), &putRes) require.NoError(t, err) - testAttrVal1 := "test-attr-val1" - testAttrVal2 := "test-attr-val2" + testAttrVal1 := "/folder/cat.jpg" + testAttrVal2 := "cat.jpg" testAttrVal3 := "test-attr-val3" for _, tc := range []struct { @@ -340,6 +349,14 @@ func TestFindObjectByAttribute(t *testing.T) { err: "not found", additionalSearch: true, }, + { + name: "success search by FilePath with leading slash (with additional search)", + firstAttr: prepareObjectAttributes(attrFilePath, testAttrVal1), + secondAttr: prepareObjectAttributes(attrFileName, testAttrVal2), + reqAttrKey: attrFilePath, + reqAttrValue: "/cat.jpg", + additionalSearch: true, + }, } { t.Run(tc.name, func(t *testing.T) { obj := hc.frostfs.objects[putRes.ContainerID+"/"+putRes.ObjectID] @@ -422,6 +439,17 @@ func TestNeedSearchByFileName(t *testing.T) { } } +func TestPrepareFileName(t *testing.T) { + fileName := "/cat.jpg" + expected := "cat.jpg" + actual := prepareFileName(fileName) + require.Equal(t, expected, actual) + + fileName = "cat.jpg" + actual = prepareFileName(fileName) + require.Equal(t, expected, actual) +} + func prepareUploadRequest(ctx context.Context, bucket, content string) (*fasthttp.RequestCtx, error) { r := new(fasthttp.RequestCtx) utils.SetContextToRequest(ctx, r) -- 2.45.3 From 466f3a9531002cf8d93e8d0690133c4a7f07a639 Mon Sep 17 00:00:00 2001 From: Roman Loginov Date: Wed, 5 Feb 2025 14:40:31 +0300 Subject: [PATCH 2/2] [#174] Port release v0.32.3 changelog Signed-off-by: Roman Loginov --- CHANGELOG.md | 8 +++++++- VERSION | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51080bb..2025b6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ This document outlines major changes between releases. - Add handling quota limit reached error (#187) - Add slash clipping for FileName attribute (#174) +## [0.32.3] - 2025-02-05 + +### Added +- Add slash clipping for FileName attribute (#174) + ## [0.32.2] - 2025-02-03 ### Fixed @@ -200,4 +205,5 @@ To see CHANGELOG for older versions, refer to https://github.com/nspcc-dev/neofs [0.32.0]: https://git.frostfs.info/TrueCloudLab/frostfs-http-gw/compare/v0.31.0...v0.32.0 [0.32.1]: https://git.frostfs.info/TrueCloudLab/frostfs-http-gw/compare/v0.32.0...v0.32.1 [0.32.2]: https://git.frostfs.info/TrueCloudLab/frostfs-http-gw/compare/v0.32.1...v0.32.2 -[Unreleased]: https://git.frostfs.info/TrueCloudLab/frostfs-http-gw/compare/v0.32.2...master \ No newline at end of file +[0.32.3]: https://git.frostfs.info/TrueCloudLab/frostfs-http-gw/compare/v0.32.2...v0.32.3 +[Unreleased]: https://git.frostfs.info/TrueCloudLab/frostfs-http-gw/compare/v0.32.3...master \ No newline at end of file diff --git a/VERSION b/VERSION index c6a2605..2c768c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.32.2 +v0.32.3 -- 2.45.3