如何使用Go

时间:2016-08-06 22:35:49

标签: amazon-web-services go amazon-s3

我有一个从S3下载文件的功能。它工作但无法识别IfModifiedSince选项。下面的函数在本地查找相同的命名文件,如果存在,则将time.Time对象设置为修改日期和时间。然后在S3的请求中使用它,如果从那时起修改了文件,则只下载该文件。

func DownloadS3Media(filename string, mediaDirectory string, bucket string, c *configuration.Configuration) (dest string, bytes int64, err error) {
    os.Setenv("AWS_ACCESS_KEY_ID", c.AWS_ACCESS_KEY_ID)
    os.Setenv("AWS_SECRET_ACCESS_KEY", c.AWS_SECRET_ACCESS_KEY)

    // Create the directories in the path
    finalFilePath := filepath.Join(mediaDirectory, filename)
    if err1 := os.MkdirAll(filepath.Dir(finalFilePath), 0775); err1 != nil {
        return "", 0, err1
    }

    //Create the blank file to push the data into
    var t *time.Time
    if fi, err2 := os.Stat(finalFilePath); err2 == nil {
        t1 := fi.ModTime()
        t = &t1
    }
    tempFilePath := filepath.Join(mediaDirectory, filename + ".tmp")
    tempFile, err3 := os.Create(tempFilePath)
    if err3 != nil {
        log.Println("Failed to create file", err3)
        return finalFilePath, 0, err3
    }
    defer tempFile.Close()

    logLevel := aws.LogDebug
    downloader := s3manager.NewDownloader(session.New(&aws.Config{Region: aws.String("us-east-1"), LogLevel:&logLevel}))
    params := &s3.GetObjectInput{Bucket: aws.String(bucket),
        Key:    aws.String(filename),
        IfModifiedSince: t}
    numBytes, err4 := downloader.Download(tempFile, params)
    if err4 != nil {
        log.Println("Failed to download file", err4)
        return finalFilePath, 0, err4
    }

    //if downloader pulled down the file, rename the tmp file to original.
    if _, err5 := os.Stat(tempFilePath); err5 == nil {
        os.Rename(tempFilePath, finalFilePath)
        log.Println("Renamed ", tempFilePath, "to", finalFilePath)
    }

    log.Println("Downloaded file", filename, "to", finalFilePath, numBytes, "bytes")
    return finalFilePath, numBytes, nil
}

调试时,我看到& t的正确值,类似于sec: 63606119179。 AWS发送请求时,标头存在但设置为1/1/0001。

---[ REQUEST POST-SIGN ]-----------------------------
GET http://*****.s3.amazonaws.com/domenic-test.png HTTP/1.1
Host: *****.s3.amazonaws.com
User-Agent: aws-sdk-go/1.3.1 (go1.6.3; darwin; amd64) S3Manager
Authorization: AWS4-HMAC-SHA256 Credential= *****/20160806/us-east-1/s3/aws4_request, SignedHeaders=host;if-modified-since;range;x-amz-content-sha256;x-amz-date, Signature= *****
If-Modified-Since: Mon, 1 Jan 0001 00:00:00 GMT
Range: bytes=0-5242879
X-Amz-Content-Sha256: *****
X-Amz-Date: 20160806T223302Z

1 个答案:

答案 0 :(得分:0)

尝试这种简化:

var t time.Time
if fi, err2 := os.Stat(finalFilePath); err2 == nil {
    t := fi.ModTime()
}

以后:

params := &s3.GetObjectInput{Bucket: aws.String(bucket),
    Key:    aws.String(filename),
    IfModifiedSince: aws.Time(t)}

...如示例代码中所示:https://github.com/aws/aws-sdk-go/blob/f1e26250235022af782521266389e4b2ae2945e4/service/s3/examples_test.go#L975

起初我认为这是一个擦除问题,但经过测试,我发现time.Time指向的t值逃脱了阻塞(这让我感到很惊讶)。也许在两者之间发生了一些其他的错误,但我认为,因为他们的测试正在通过,这应该可行。