diff options
| author | Andrey Triumfov <triumfov@yahoo.com> | 2022-08-15 18:19:28 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-15 08:19:28 -0700 |
| commit | 31faa6d43d3d518398d9ff587bab62f642d28426 (patch) | |
| tree | 50c6aa6235375148dc15fb88442434cb56d511af | |
| parent | cb476a53ffe8861565f4b8e40e985ce7bac81fe9 (diff) | |
| download | seaweedfs-31faa6d43d3d518398d9ff587bab62f642d28426.tar.xz seaweedfs-31faa6d43d3d518398d9ff587bab62f642d28426.zip | |
Remove duplicate slashes in object path to prevent 500 errors (#3442)
| -rw-r--r-- | weed/s3api/s3api_object_handlers.go | 23 | ||||
| -rw-r--r-- | weed/s3api/s3api_object_handlers_test.go | 48 |
2 files changed, 70 insertions, 1 deletions
diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 75abd0e4d..f3b34fa4d 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -130,9 +130,30 @@ func urlPathEscape(object string) string { return strings.Join(escapedParts, "/") } +func removeDuplicateSlashes(object string) string { + result := strings.Builder{} + result.Grow(len(object)) + + isLastSlash := false + for _, r := range object { + switch r { + case '/': + if !isLastSlash { + result.WriteRune(r) + } + isLastSlash = true + default: + result.WriteRune(r) + isLastSlash = false + } + } + return result.String() +} + func (s3a *S3ApiServer) toFilerUrl(bucket, object string) string { + object = urlPathEscape(removeDuplicateSlashes(object)) destUrl := fmt.Sprintf("http://%s%s/%s%s", - s3a.option.Filer.ToHttpAddress(), s3a.option.BucketsPath, bucket, urlPathEscape(object)) + s3a.option.Filer.ToHttpAddress(), s3a.option.BucketsPath, bucket, object) return destUrl } diff --git a/weed/s3api/s3api_object_handlers_test.go b/weed/s3api/s3api_object_handlers_test.go new file mode 100644 index 000000000..d1043451d --- /dev/null +++ b/weed/s3api/s3api_object_handlers_test.go @@ -0,0 +1,48 @@ +package s3api + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRemoveDuplicateSlashes(t *testing.T) { + tests := []struct { + name string + path string + expectedResult string + }{ + { + name: "empty", + path: "", + expectedResult: "", + }, + { + name: "slash", + path: "/", + expectedResult: "/", + }, + { + name: "object", + path: "object", + expectedResult: "object", + }, + { + name: "correct path", + path: "/path/to/object", + expectedResult: "/path/to/object", + }, + { + name: "path with duplicates", + path: "///path//to/object//", + expectedResult: "/path/to/object/", + }, + } + + for _, tst := range tests { + t.Run(tst.name, func(t *testing.T) { + obj := removeDuplicateSlashes(tst.path) + assert.Equal(t, tst.expectedResult, obj) + }) + } +} |
