go - S3 存储桶命名策略问题并尝试将 SDK 生成的请求发送到实现 S3 API 的 API

标签 go amazon-s3

如果标题措辞没有正确描述问题,我深表歉意,我不确定如何措辞。
我正在开发一个 API,它可以像处理 S3 API 一样处理请求,因此应该使用 Go S3 SDK 我在尝试将存储桶名称传递给 Go S3 SDK 函数时特别遇到问题。
例如:

result, err := svc.CreateBucket(&s3.CreateBucketInput{
    Bucket:aws.String(bucketName),
})
当存储桶名称设置为我认为被解析为两个单独标签的字符串时,例如 testBucketmyBucket SDK 似乎生成了一个将主机地址设置为端点地址的请求,即 http://localhost:8000/s3/后跟存储桶名称,我的 API 可以适本地接受、处理和响应。
但是,当存储桶名称包含被解析为单个标签的字符串时,例如 testbuckettestbucket SDK 生成一个主机地址,其存储桶名称位于主机之前,即 http://test.localhost:8000/s3/这会导致错误,因为我编写的 API 不支持此主机地址。
理想情况下,我需要以某种方式支持使用单标签存储桶名称,或者通过扩展 API 处理请求的方式,或者通过制定一种方法来强制 SDK 停止更改主机 URL 格式。
如果有人能够帮助解决问题或提供建议,我将不胜感激。

最佳答案

所以我已经通过 AWS SDK V2 和函数 moveBucketNameToHost(req.URL, bucket) 是导致异常主机的原因。我要提到这一点,这取决于 AWS 是否是错误。不过有办法解决这个问题!
您需要将 EndpointResolver 属性 HostnameImmutable 设置为 true 。这将阻止它被这个函数改变。
例子:
制作自定义解析器时

// for custom localstack endpoint
    customResolver := aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
        if service == s3.ServiceID {
            return aws.Endpoint{
                PartitionID:   "aws",
                URL:           "http://localhost:4566",
                SigningRegion: "eu-west-1",
                HostnameImmutable: true, // This must be set to true to disable the host changing
            }, nil
        }
        // returning EndpointNotFoundError will allow the service to fallback to it's default resolution
        return aws.Endpoint{}, &aws.EndpointNotFoundError{}
    })

    config, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("eu-west-1"), config.WithEndpointResolver(customResolver))
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(config)
更新
默认情况下,S3 使用虚拟主机路径样式来寻址存储桶。这就是主机名变为 {bucketname}.localhost:4566 的原因。
S3 对有效存储桶名称的要求很少。因此,根据要求,camelCase 是一个无效的存储桶名称,因此 SDK 回退到路径样式的 url。因此主机名不会发生变化,您会看到 localhost:4566/camelCase。
来到您的解决方法,如果 HostnameImmutable 属性设置为 true,SDK API 客户端将不会修改 URL 的主机名。如果 API 要求客户端使用特定于操作的主机名值,这可能会导致 API 客户端无法正常运行。
在您的情况下,更好的解决方案是直接在 S3 选项上启用 UsePathStyle 选项
result, err :=  client.CreateBucket(ctx, &input, func(o *s3.Options) {
        o.UsePathStyle = true
})

关于go - S3 存储桶命名策略问题并尝试将 SDK 生成的请求发送到实现 S3 API 的 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65953564/

相关文章:

go - 如何设计一个在另一个对等点上调用相同的链代码?

go - 使用 Gorm 将值从一列映射到单独表中的另一列

sockets - 在 Go 中加速系统调用

java - 使用 IAM 角色从 Java 访问 AWS S3

amazon-web-services - Amazon S3 安全存储桶

go - 将 GoLang 连接到 GitHub

go - 匿名函数中的该例程如何工作?

CSS 文件对 Vue 产品构建没有影响

amazon-web-services - 使用 Python 向 AWS S3 发出批量复制请求

php - 是否可以获取对 Amazon s3 对象发出的请求的数量(计数)?