如何在AWS smithy-go端点中配置PartitionID与SigningRegion?
问题
之前使用的AWS自定义端点解析器如下:
func loadAWSConfig() aws.Config { endpoint := os.Getenv("MOCK_AWS_ENDPOINT") if endpoint != "" { fmt.Println("Running AWS with custom endpoint resolver: ", endpoint) cfg, err := config.LoadDefaultConfig(context.Background(), config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...any) (aws.Endpoint, error) { return aws.Endpoint{ PartitionID: "aws", URL: endpoint, SigningRegion: region, }, nil }))) if err != nil { panic("unable to load SDK config, " + err.Error()) } return cfg } cfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { panic("unable to load SDK config, " + err.Error()) } return cfg }
由于AWS已弃用config.WithEndpointResolverWithOptions、aws.EndpointResolverWithOptionsFunc和aws.Endpoint,改用EndpointResolverV2后,尝试了以下实现:
import transport "github.com/aws/smithy-go/endpoints" type resolverS3 struct { } func (r resolverS3) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (transport.Endpoint, error) { if endpoint := os.Getenv("MOCK_AWS_ENDPOINT"); endpoint != "" { u, err := url.Parse(endpoint) if err != nil { return transport.Endpoint{}, err } return transport.Endpoint{URI: *u}, nil } // delegate back to the default v2 resolver otherwise return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params) } func GetS3Instance() *s3.Client { return s3.NewFromConfig(loadAWSConfig(), s3.WithEndpointResolverV2(resolverS3{})) }
但运行时出现“未找到指定存储桶”错误,推测是自定义解析器中未设置PartitionID和SigningRegion,请问如何在transport.Endpoint中配置这两个参数?
解决方案
在transport.Endpoint中,PartitionID可直接赋值,SigningRegion需要通过Properties字段结合endpoints.SigningRegionKey键来设置。另外,Mock服务通常使用路径样式的桶寻址,需禁用S3默认的虚拟主机样式,这也是导致“未找到指定存储桶”的常见原因。
修正后的解析器代码如下:
import ( "context" "net/url" "os" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/s3" transport "github.com/aws/smithy-go/endpoints" ) type resolverS3 struct { } func (r resolverS3) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (transport.Endpoint, error) { if endpoint := os.Getenv("MOCK_AWS_ENDPOINT"); endpoint != "" { u, err := url.Parse(endpoint) if err != nil { return transport.Endpoint{}, err } // 初始化属性并设置签名区域 props := make(map[string]any) props[endpoints.SigningRegionKey] = params.Region return transport.Endpoint{ URI: *u, PartitionID: "aws", // 直接设置PartitionID Properties: props, SigningName: "s3", // 指定S3的签名名称 }, nil } // 回退到默认端点解析器 return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params) } func GetS3Instance() *s3.Client { cfg := loadAWSConfig() // 启用路径样式寻址,适配Mock服务的桶路径格式 return s3.NewFromConfig(cfg, s3.WithEndpointResolverV2(resolverS3{}), s3.WithUsePathStyle(true), ) }
关键说明
- PartitionID:直接在
transport.Endpoint结构体中赋值,对应旧版aws.Endpoint的同名字段。 - SigningRegion:通过
Properties字段的endpoints.SigningRegionKey键设置,值取自参数中的params.Region,确保签名区域与配置一致。 - s3.WithUsePathStyle(true):S3默认使用虚拟主机样式寻址(
http://bucket.endpoint),而Mock服务通常采用路径样式(http://endpoint/bucket),开启该选项可避免桶名解析错误。
内容的提问来源于stack exchange,提问作者Lakshan Dissanayake
相关产品推荐
相关产品推荐

