草庐IT

amazon-web-services - 如何使用 Go 在 AWS S3 中设置 If-Modified-Since header

coder 2024-07-10 原文

我有一个从 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 发送请求时, header 已存在但设置为 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

最佳答案

试试这个简化:

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

一开始以为是删除问题,后来测试发现t指向的time.Time值逃逸了 block (老实说让我吃了一惊)。也许在两者之间发生了一些其他错误,但我认为既然他们的测试通过了,这应该可行。

关于amazon-web-services - 如何使用 Go 在 AWS S3 中设置 If-Modified-Since header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38809347/

有关amazon-web-services - 如何使用 Go 在 AWS S3 中设置 If-Modified-Since header的更多相关文章

  1. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  2. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  3. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

  4. ruby-on-rails - 如何将大于 5GB 的文件上传到 Amazon S3? - 2

    我目前正在使用带有Carrierwavegem的Rails3.2将文件上传到AmazonS3。现在我需要能够处理用户提交的大于5GB的文件,同时仍然使用Carrierwavegem。Carrierwave或Fog是否有任何其他gem或分支可以处理5GB以上的文件上传到S3?编辑:我不想重写一个完整的Rails上传解决方案,所以像这样的链接没有帮助:https://gist.github.com/908875. 最佳答案 我想出了如何做到这一点,并且现在可以正常工作了。在正确的config/environment文件中,添加以下内容以

  5. ruby-on-rails - 将 Amazon Simple Notification service SNS 与 ruby​​ 结合使用 - 2

    很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visitthehelpcenter.关闭9年前。我需要从基于ruby​​的应用程序使用AmazonSimpleNotificationService,但不知道从哪里开始。您对从哪里开始有什么建议吗?

  6. ruby-on-rails - 尝试设置 Amazon 的 S3 存储桶 : 403 Forbidden error & setting permissions - 2

    我正在关注Hartl的railstutorial.org并已到达11.4.4:Imageuploadinproduction.我做了什么:注册亚马逊网络服务在AmazonIdentityandAccessManagement中,我创建了一个用户。用户创建成功。在AmazonS3中,我创建了一个新存储桶。设置新存储桶的权限:权限:本教程指示“授予上一步创建的用户读写权限”。但是,在存储桶的“权限”下,未提及新用户名。我只能在每个人、经过身份验证的用户、日志传送、我和亚马逊似乎根据我的名字+数字创建的用户名之间进行选择。我已经通过选择经过身份验证的用户并选中了上传/删除和查看权限的框(而不

  7. python - 用于 Python 或 Ruby 的 Amazon Book API? - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:AmazonAPIlibraryforPython?我正在寻找一个AmazonAPI,它可以让我:按书名或作者查找书籍显示书籍封面获取有关每本书的信息(价格、评级、评论数、格式、页数等)Python或Ruby库都可以(我只想要最容易使用的库)。有什么建议么?我知道在SO上还有其他一些关于此的帖子,但这些API似乎很快就过时了。[几个月前我尝试了几个建议的Ruby库,但无法让它们中的任何一个工作。]

  8. ruby-on-rails - 如何在回形针 ruby​​ on rails 中设置默认图像 - 2

    最近我安装了Paperclipgem,我正在努力让默认图像在我的系统上工作,我将图像文件放在assets/images/pic.png中。这是我的模型User中的代码:has_attached_file:pic,:styles=>{:medium=>"300x300>",:thumb=>"100x100>"},:default_url=>'missing_:avatar.png'#:default_url=>'assets/images/avatar.png'has_attached_file:attach这是我的AddPicPaperClip迁移中的代码:defself.upadd_

  9. ruby - 使用 Ruby 开发工具包将文件上传到 Amazon S3 - 2

    我正在尝试上传文件。一个简单的hello.txt。我正在关注文档,但无法将其上传到我的存储桶。#STARTAWSCLIENTs3=Aws::S3::Resource.newbucket=s3.bucket(BUCKET_NAME)begins3.buckets[BUCKET_NAME].objects[KEY].write(:file=>FILE_NAME)puts"Uploadingfile#{FILE_NAME}tobucket#{BUCKET_NAME}."bucket.objects.eachdo|obj|puts"#{obj.key}=>#{obj.etag}"endresc

  10. ruby-on-rails - Rails 中的类实例变量应该在互斥体中设置吗? - 2

    假设我的Rails项目中有一个设置实例变量的Ruby类。classSomethingdefself.objects@objects||=begin#somelogicthatbuildsanarray,whichisultimatelystoredin@objectsendendend是否可以多次设置@objects?是否有可能在一个请求期间,在上面的begin/end之间执行代码时,可以在第二个请求期间调用此方法?我想这实际上归结为Rails服务器实例如何fork的问题。我应该改用Mutex还是线程同步?例如:classSomethingdefself.objectsreturn@o

随机推荐