1

我在使用 AWS S3 go sdk ( https://github.com/awslabs/aws-sdk-go ) 在 golang 中保存文件时遇到了一些麻烦。

这就是我所拥有的:

import (
        "fmt"
        "bytes"

        "github.com/awslabs/aws-sdk-go/aws"
        "github.com/awslabs/aws-sdk-go/aws/awsutil"
        "github.com/awslabs/aws-sdk-go/service/s3"
)

func main() {    
    cred := aws.DefaultChainCredentials
    cred.Get() // i'm using environment variable credentials and yes, I checked if they were in here
    svc := s3.New(&aws.Config{Region: "us-west-2", Credentials:cred, LogLevel: 1})
    params := &s3.PutObjectInput{
                    Bucket:         aws.String("my-bucket-123"),
                    Key:            aws.String("test/123/"),
                    Body:         bytes.NewReader([]byte("testing!")),
            }
    resp, err := svc.PutObject(params)
    fmt.Printf("response %s", awsutil.StringValue(resp))
}

我不断收到301 Moved Permanently回复。

编辑:我手动创建了存储桶。编辑#2:示例响应:

---[ RESPONSE ]--------------------------------------
HTTP/1.1 301 Moved Permanently
Transfer-Encoding: chunked
Content-Type: application/xml
Date: Tue, 05 May 2015 18:42:03 GMT
Server: AmazonS3

POST 标志也是 http。

4

2 回答 2

3

根据亚马逊

Amazon S3 在所有区域都支持虚拟托管式和路径式访问。但是,路径样式语法要求您在尝试访问存储桶时使用特定于区域的端点。例如,如果您有一个名为 mybucket 的存储桶位于欧盟,您想使用路径样式的语法,并且对象名为 puppy.jpg,则正确的 URI 是http://s3-eu-west-1。 amazonaws.com/mybucket/puppy.jpg。如果您尝试使用以下任一路径样式语法访问美国标准区域以外的存储桶,您将收到“PermanentRedirect”错误、HTTP 响应代码 301 和一条消息,指示您的资源的正确 URI 是什么:

  • http://s3.amazonaws.com

  • 与存储桶所在区域不同的区域的终端节点,例如,http ://s3-eu-west-1.amazonaws.com 表示在美国西部(加利福尼亚北部)区域创建的存储桶

我认为问题在于您试图访问错误区域中的存储桶。您的请求在这里:

https://my-bucket-123.s3-us-west-2.amazonaws.com/test/123

因此,请确保它my-bucket-123实际上在us-west-2. (我用自己的桶试过这个,效果很好)

我还通过包装调用验证了它使用的是 HTTPS:(他们的日志消息是错误的)

type LogReadCloser struct {
    io.ReadCloser
}

func (lr *LogReadCloser) Read(p []byte) (int, error) {
    n, err := lr.ReadCloser.Read(p)
    log.Println(string(p))
    return n, err
}

type LogRoundTripper struct {
    http.RoundTripper
}

func (lrt *LogRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
    log.Println("REQUEST", req)
    res, err := lrt.RoundTripper.RoundTrip(req)
    log.Println("RESPONSE", res, err)
    res.Body = &LogReadCloser{res.Body}
    return res, err
}

接着:

svc := s3.New(&aws.Config{
    Region:      "us-west-2",
    Credentials: cred,
    LogLevel:    0,
    HTTPClient:  &http.Client{Transport: &LogRoundTripper{http.DefaultTransport}},
})
于 2015-05-06T21:58:19.697 回答
0

我认为您最好使用 S3 Uploader。这是我的代码中的一个示例,它是一个 Web 应用程序,我使用 gin 框架,在我的情况下,我从 Web 表单中获取一个文件,将其上传到 s3,然后检索 URL 以在其他 HTML 中显示一个页面:

// Create an S3 Uploader
  uploader := s3manager.NewUploader(sess)

  // Upload 
  result, err := uploader.Upload(&s3manager.UploadInput{
   Bucket: aws.String(bucket),
   Key: aws.String(fileHeader.Filename),
   Body: f,
  })
  if err != nil {
   c.HTML(http.StatusBadRequest, "create-project.html", gin.H{
    "ErrorTitle":   "S3 Upload Failed",
    "ErrorMessage": err.Error()})
  } else {
   // Success, print URL to Console.
   ///"result.Location is the URL of an Image"
   fmt.Println("Successfully uploaded to", result.Location)
  }

你可以在这里找到一个完整的例子,一步一步解释: https ://www.matscloud.com/docs/cloud-sdk/go-and-s3/

于 2020-05-27T07:05:06.223 回答