You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:38:12