Closed Senui closed 1 year ago
Hi @Senui ,
Thanks for reaching out.
This is not an issue with encoding. S3's API specifies that a /
character cannot be used to describe a bucket name:
This causes the SDK to encode the invalid character to conform to S3's API requirements.
The issue at hand is that the formatting the SDK uses by default to serialize requests to S3 is of a virtual-hosted URL that conforms to: bucket.s3.region.amazonaws.com
whereas your local test server expects a path-style url like myswift.domain.com/bucket
.
You can force path style by passing it as a functional options to your api call:
func main() {
bucketName := "mybucket"
endpoint := "https://myswift.domain.com"
region := "NL"
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: endpoint,
SigningRegion: region,
}, nil
})
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion(region),
config.WithEndpointResolverWithOptions(customResolver),
config.WithClientLogMode(aws.LogRetries|aws.LogRequest|aws.LogRequestWithBody),
)
if err != nil {
fmt.Println("Failed to load AWS configuration:", err)
return
}
client := s3.NewFromConfig(cfg)
resp, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{
Bucket: aws.String(bucketName),
}, func(options *s3.Options) {
options.UsePathStyle = true
})
// more code...
Will result in the expected serialized request:
SDK 2023/07/14 13:56:01 DEBUG Request
GET /mybucket?list-type=2 HTTP/1.1
Host: myswift.domain.com
Let me know if this helps.
Thanks, Ran~
Dear @RanVaknin,
Thank you so much for your quick reply. You are exactly right - setting the HostnameImmutable to true
resolves my issue. I didn't know about the virtual-hosted URLs vs path-style URLs! It now makes complete sense as to why the bucket name was automatically prepended to the hostname without a prepending forward slash in the bucket's name.
Really great to see that this was taken into account in the SDK and that such a convenient flag is all it takes to switch between these two styles.
I hereby close the ticket. Thanks again for taking your time to look into this.
Ahmad
Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.
Describe the bug
I'm trying to perform an action (e.g. list all objects) on an S3 bucket using a custom S3-compatible endpoint that serves a Openstack SWIFT object store. Using the aws-sdk-go-v2 module I am unable to do so because the HTTP request (retrieved from logs) is not correctly generated from my configuration (an encoded forward slash is prepending to the GET request).
The same configuration is used in the
boto3
python package, which works fine.Expected Behavior
Current Behavior
Reproduction Steps
Here is the reproducing code. Note that if I were to remove the forward slash in front of the bucket name, the bucket name would be prepended to the host and would mess up the request completely:
Possible Solution
Perhaps there are
options
that I can set in myendpointResolver
to fix the encoding issue, but there is no documentation on that AFAIKAdditional Information/Context
No response
AWS Go SDK V2 Module Versions Used
v1.19.0
Compiler and Version used
go version go1.20.6 linux/amd64
Operating System and version
Debian GNU/Linux 12 (bookworm)