使用AWS SDK for Go使用完整URI从S3下载文件

时间:2018-03-27 22:37:21

标签: go amazon-s3 aws-sdk

我见过的使用AWS SDK for Go从S3下载文件的示例如下:

downloader := s3manager.NewDownloader(session, /* other args */)

s3object := &s3.GetObjectInput{
    Bucket: aws.String(myBucket),
    Key: aws.String(myKey),
}

bytesDownloaded, err := downloader.Download(myFile, s3object)

即,使用存储桶和密钥指定文件。但是如果我已经在S3上拥有该文件的完整URI呢? E.g:

https://s3.us-west-2.amazonaws.com/myBucket/myKey

有没有办法使用SDK直接使用URL指定要下载的文件?

不,存储桶公开。在SDK中,我还设置了访问密钥和密钥(从示例代码中省略)。

最后,如果根本无法通过SDK执行我所要求的操作,那么这是一个可接受的(虽然不是理想的)答案。

4 个答案:

答案 0 :(得分:3)

没有办法做你想做的事。获取私有对象的唯一方法是:

  1. 使用存储桶和密钥下载文件
  2. 生成预先签名的网址,并在该网址上执行hhtp.Get(以生成您需要存储桶和密钥的预签名网址)
  3. 如果你真的想使用我建议你创建一个s3.GetObjectInput的包装器,它接受URL作为参数,解析它然后创建s3.GetObjectInput对象。

    另外,我不知道你是否可以这样做取决于你的使用案例,但是如果你在某处存放URL并且这就是你想要使用它们的原因,那么你可以考虑使用long来存储预先签名的URL到期时间,然后当您想要获取对象时,您可以使用该URL。

答案 1 :(得分:1)

您可以解析URL以获取存储桶和密钥:

package main

import (
    "fmt"
    "log"
    "net/url"
    "strings"
)

func main() {
    u, err := url.Parse("https://s3.us-west-2.amazonaws.com/myBucket/myKey/morekey")
    if err != nil {
        log.Fatal(err)
    }

    path := strings.SplitN(u.Path, "/", 3)
    bucket := path[1]
    key := path[2]
    fmt.Println(bucket)
    fmt.Println(key)
}

Runnable:https://play.golang.org/p/G3Mxmm4f4qM

答案 2 :(得分:1)

为此创建了新的S3URLtoURI解析器。

func S3URLtoURI(s3Url string) (map[string]string, error) {
    m := make(map[string]string)
    u, err := url.Parse(s3Url)
    if err != nil {
        return m, err
    }

    if u.Scheme == "s3" {
        //s3: //bucket/key
        m["bucket"] = u.Host
        m["key"] = strings.TrimLeft(u.Path, "/")
    } else if u.Scheme == "https" {
        host := strings.SplitN(u.Host, ".", 2)
        if host[0] == "s3" {
            // No bucket name in the host;
            path := strings.SplitN(u.Path, "/", 3)
            m["bucket"] = path[1]
            m["key"] = path[2]
        } else { //bucket name in host
            m["bucket"] = host[0]
            m["key"] = strings.TrimLeft(u.Path, "/")
        }

    }
    return m, err
}

可运行:https://play.golang.org/p/vkPJ7E4Fyno

答案 3 :(得分:0)

首先,您需要在尝试从S3下载的对象上启用公共访问。您可以通过以下任一方法实现此目的。

  • 使对象公开可读。但请记住,无论谁有权访问 资源网址可以从S3下载您的对象。
  • 通过存储桶策略授予对S3存储桶的匿名访问权限。 Refer here通过政策样本了解这种方法。记得验证 你走这条路的时候会露出什么。
  • 使用允许在时间限制内下载对象的PreSignedUrl 方式。这就是我所希望的上述方法。

现在最后一步是使用go http client来调用预先签名的网址并下载所需的对象。