获取S3存储桶上的资源URI。

huangapple go评论75阅读模式
英文:

Get resource URI on s3 bucket

问题

目前,我使用字符串插值手动构建URI:

fmt.Sprintf("https://%s.%s.amazonaws.com/%s/%s", serviceId, region, namespace, filename)

在我看来,这种方法不好,因为我通过参数从环境变量中传递它们。我可以访问正确初始化的aws.Session对象,该对象与我们的s3存储桶相关联。

是否有一种语义上正确的方式(可能使用aws sdk API)来生成与我通过“dummy”字符串构建器生成的相同资源URI?

英文:

Currently, I construct URI by hand with string interpolation:

fmt.Sprintf("https://%s.%s.amazonaws.com/%s/%s", serviceId, region, namespace, filename)

which IMHO is bad as I pass them via parameters from env variables. I have access to aws.Session object which is correctly initialized with our s3 bucket.

Is there are a semantically correct way(probably with aws sdk API) to generate the same resource URI I do by dummy string builder?

答案1

得分: 1

从一个示例中...

虽然aws-sdk-gosvc.GetObjectRequest返回的结构体中暴露了*http.Request,但它返回的URL实际上更像是一个“URL格式”,直到你在请求上运行SignPresign等方法。

可以在此页面找到一些Presign的示例。Get示例提供了以下输出:

2017/08/03 09:47:43 URL为https://get-resource-uri-test.s3-us-west-2.amazonaws.com/myKey?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIFJBK7YB3H7CTZIA%2F20170803%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20170803T144743Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=3c279aece1eda3c33b0711bb0e5a86e330e378f9052f1e73cdb0b9ca19de6209

请注意,我使用的是“get-resource-uri-test”作为我的存储桶名称,因为示例中的存储桶已经在使用中


调整后的示例

由于这不是您要寻找的输出类型,我调整了示例以使用Sign,这样可以使事情更简洁,因为身份验证信息被放入头部等而不是URL中:

svc := s3.New(session.New(&aws.Config{Region: aws.String("us-west-2")}))
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
	Bucket: aws.String("get-resource-uri-test"),
	Key:    aws.String("myKey"),
})

// 不使用提供的Presign示例
if err := req.Sign(); err != nil {
	log.Println("Failed to sign request", err)
}

log.Println("URL为", req.HTTPRequest.URL)

2017/08/03 09:53:22 URL为https://get-resource-uri-test.s3-us-west-2.amazonaws.com/myKey


考虑事项

虽然这个建议确实避免了对S3进行任何调用,但我对此有些矛盾的感觉。在某些方面,aws-sdk-go似乎旨在在一定程度上消除对URL操作的需求,并且生成URL(主要是在内部)是你尝试实现的结果。

那么,在Go中,我们是否真的需要创建一个完整的S3客户端才能从Amazon获取一个正确的URL呢?这似乎有点过度,但这是我迄今为止找到的唯一一种从aws-sdk-go接收格式化URL的方法。如果其他人能够提出更合理的替代方案,我鼓励他/她也发布自己的解决方案。

我可能不需要说这个,但如果您计划在规模上使用此示例,我建议创建一个单独的S3客户端(在提供的示例中命名为svc),并重用其GetObjectRequest方法,以避免每次需要确定URL时都创建一个新的客户端。

英文:

From an example...

While aws-sdk-go does expose the *http.Request in a struct returned by svc.GetObjectRequest, the URL it returns is really more of a 'url format' until you run a method on the request like Sign or Presign.

A few Presign examples can be found On This Page. The Get example provides the following output:

> 2017/08/03 09:47:43 The URL is https://get-resource-uri-test.s3-us-west-2.amazonaws.com/myKey?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIFJBK7YB3H7CTZIA%2F20170803%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20170803T144743Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=3c279aece1eda3c33b0711bb0e5a86e330e378f9052f1e73cdb0b9ca19de6209

Note that I'm using 'get-resource-uri-test' as my bucket name since the one in the example was already in use


Adjusted example

Since this isn't the kind of output you're looking for, I've adjusted the example to use Sign, which keeps things more clean since the auth info is put into headers/etc. instead of in the URL:

svc := s3.New(session.New(&aws.Config{Region: aws.String("us-west-2")}))
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
	Bucket: aws.String("get-resource-uri-test"),
	Key:    aws.String("myKey"),
})

// Instead of using Presign, which was provided in example
if err := req.Sign(); err != nil {
	log.Println("Failed to sign request", err)
}

log.Println("The URL is", req.HTTPRequest.URL)

> 2017/08/03 09:53:22 The URL is https://get-resource-uri-test.s3-us-west-2.amazonaws.com/myKey


Considerations

While this suggestion does avoid actually making any calls to S3, I do have mixed feelings about it. In some respects, aws-sdk-go seems designed to somewhat eliminate the need for URL manipulation and instead generates it (mostly internally) as a consequence of what you're trying to accomplish.

So is it really necessary for us to create a whole S3 client to get a properly 'sanctioned/blessed' url from Amazon in Go? It seems a little overboard, but this is the only way I've found so far to receive a formatted URL from aws-sdk-go. If anyone else is able to come up with a more reasonable alternative, I'd encourage that person to post his/her solution as well.

I probably don't need to say this, but if this example is something you're planning to use at scale, I'd recommend creating a single s3 client (named svc in the example provided) and reusing its GetObjectRequest method to avoid creating a new client every time you need to determine a URL.

huangapple
  • 本文由 发表于 2017年8月3日 19:27:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/45482885.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定