Skip to content

Commit

Permalink
Fix s3x URL generation to not mangle slashes
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Jul 26, 2024
1 parent 9cf3cd0 commit 55ab629
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
10 changes: 5 additions & 5 deletions s3x/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ func TestService(t *testing.T) {
err = svc.Test(ctx, "gocommon-tests")
assert.NoError(t, err)

url, err := svc.PutObject(ctx, "gocommon-tests", "hello world.txt", "text/plain", []byte("hello world"), s3.BucketCannedACLPublicRead)
url, err := svc.PutObject(ctx, "gocommon-tests", "1/hello world.txt", "text/plain", []byte("hello world"), s3.BucketCannedACLPublicRead)
assert.NoError(t, err)
assert.Equal(t, "http://localhost:9000/gocommon-tests/hello%20world.txt", url)
assert.Equal(t, "http://localhost:9000/gocommon-tests/1/hello+world.txt", url)

contentType, body, err := svc.GetObject(ctx, "gocommon-tests", "hello world.txt")
contentType, body, err := svc.GetObject(ctx, "gocommon-tests", "1/hello world.txt")
assert.NoError(t, err)
assert.Equal(t, "text/plain", contentType)
assert.Equal(t, []byte("hello world"), body)

_, err = svc.Client.DeleteObject(&s3.DeleteObjectInput{Bucket: aws.String("gocommon-tests"), Key: aws.String("hello world.txt")})
_, err = svc.Client.DeleteObject(&s3.DeleteObjectInput{Bucket: aws.String("gocommon-tests"), Key: aws.String("1/hello world.txt")})
assert.NoError(t, err)

_, err = svc.Client.DeleteBucket(&s3.DeleteBucketInput{Bucket: aws.String("gocommon-tests")})
Expand All @@ -45,5 +45,5 @@ func TestService(t *testing.T) {

aws, err := s3x.NewService("AA1234", "2345263", "us-east-1", "https://s3.amazonaws.com", false)
assert.NoError(t, err)
assert.Equal(t, "https://gocommon-tests.s3.us-east-1.amazonaws.com/hello%20world.txt", aws.ObjectURL("gocommon-tests", "hello world.txt"))
assert.Equal(t, "https://gocommon-tests.s3.us-east-1.amazonaws.com/1/hello+world.txt", aws.ObjectURL("gocommon-tests", "1/hello world.txt"))
}
11 changes: 8 additions & 3 deletions s3x/urls.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@ package s3x

import (
"fmt"
"net/url"
"strings"
)

// ObjectURLer is a function that takes a key and returns the publicly accessible URL for that object
type ObjectURLer func(string, string) string

func AWSURLer(region string) ObjectURLer {
return func(bucket, key string) string {
return fmt.Sprintf("https://%s.s3.%s.amazonaws.com/%s", bucket, region, url.PathEscape(key))
return fmt.Sprintf("https://%s.s3.%s.amazonaws.com/%s", bucket, region, escape(key))
}
}

func MinioURLer(endpoint string) ObjectURLer {
return func(bucket, key string) string {
return fmt.Sprintf("%s/%s/%s", endpoint, bucket, url.PathEscape(key))
return fmt.Sprintf("%s/%s/%s", endpoint, bucket, escape(key))
}
}

// can't URL escape keys because need to preserve slashes
func escape(key string) string {
return strings.ReplaceAll(key, " ", "+")
}
4 changes: 2 additions & 2 deletions s3x/urls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

func TestURLers(t *testing.T) {
urler := s3x.AWSURLer("us-east-1")
assert.Equal(t, "https://mybucket.s3.us-east-1.amazonaws.com/hello%20world.txt", urler("mybucket", "hello world.txt"))
assert.Equal(t, "https://mybucket.s3.us-east-1.amazonaws.com/1/hello+world.txt", urler("mybucket", "1/hello world.txt"))

urler = s3x.MinioURLer("http://localhost:9000")
assert.Equal(t, "http://localhost:9000/mybucket/hello%20world.txt", urler("mybucket", "hello world.txt"))
assert.Equal(t, "http://localhost:9000/mybucket/1/hello+world.txt", urler("mybucket", "1/hello world.txt"))
}

0 comments on commit 55ab629

Please sign in to comment.