aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Triumfov <triumfov@yahoo.com>2022-08-15 18:19:28 +0300
committerGitHub <noreply@github.com>2022-08-15 08:19:28 -0700
commit31faa6d43d3d518398d9ff587bab62f642d28426 (patch)
tree50c6aa6235375148dc15fb88442434cb56d511af
parentcb476a53ffe8861565f4b8e40e985ce7bac81fe9 (diff)
downloadseaweedfs-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.go23
-rw-r--r--weed/s3api/s3api_object_handlers_test.go48
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)
+ })
+ }
+}