我如何安全地检查文件是否存在于S3桶中使用go in lambda?

rsaldnfx  于 2022-12-07  发布在  Go
关注(0)|答案(4)|浏览(143)

我正在为我的项目开发一个服务,用于同步AWS中的Lambda作品。我的想法是编写一个TrackerFile模块,它将存储S3上的结构。每次使用跟踪器时,我都会检查是否有一个文件的名称分配给了被调用的跟踪器。
我不知道如何安全地检查S3上是否存在具有给定名称的文件。您能否显示一段示例代码,如果文件存在,该代码将能够返回(bool,err),其中bool为True?

5kgi1eie

5kgi1eie1#

请确保您具有以下权限:“s3:获取对象”、“s3:列表存储桶”、
关于安全性,AWS刚刚引入了S3的强一致性

s3svc = s3.New(sess)
     
func keyExists(bucket string, key string) (bool, error) {
        _, err := s3svc.HeadObject(&s3.HeadObjectInput{
            Bucket: aws.String(bucket),
            Key:    aws.String(key),
        })
        if err != nil {
            if aerr, ok := err.(awserr.Error); ok {
                switch aerr.Code() {            
                case "NotFound": // s3.ErrCodeNoSuchKey does not work, aws is missing this error code so we hardwire a string
                    return false, nil
                default:
                    return false, err
                }
            }
            return false, err
        }
        return true, nil
    }
sulc1iza

sulc1iza2#

如果您使用AWS SDK for Go V2:

import (
    ...
    awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
    ...
)

func uploaded(ctx context.Context, client *s3.Client, bucket string, key string) (bool, error) {
    _, err := client.HeadObject(ctx, &s3.HeadObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(key),
    })
    if err != nil {
        var responseError *awshttp.ResponseError
        if errors.As(err, &responseError) && responseError.ResponseError.HTTPStatusCode() == http.StatusNotFound {
            return false, nil
        }
        return false, err
    }
    return true, nil
}

Handling Errors in the AWS SDK for Go V2

0tdrvxhp

0tdrvxhp3#

您可以尝试以下代码来获取对象元数据:

sess, err := session.NewSession(&aws.Config{
    Region: aws.String("your-region"),
})

if err != nil {
    //handle error here
}

svc := s3.New(session.Must(sess, err))
output, err := svc.HeadObject(&s3.HeadObjectInput{
    Bucket: aws.String("bucket_name"),
    Key:    aws.String("object_key"),
})

if err != nil {
    //handle error here
}

fmt.Println(output.LastModified) //do something with metadata
ddhy6vgd

ddhy6vgd4#

只需参考AWS API S3 HeadObject方法:AWS API documentation。在缺少对象的情况下,它将返回状态代码404
HEAD请求与对象上的GET操作具有相同的选项。响应与GET响应相同,只是没有响应主体。因此,如果HEAD请求生成错误,它将返回通用的404 Not Found或403 Forbidden代码。

import (
  "context"
  "github.com/aws/aws-sdk-go-v2/aws"
  "github.com/aws/aws-sdk-go-v2/service/s3"
  "log"
)

func IsObjectExistsInS3Bucket(bucketName string, objectKey string) bool{
  _, err := executeHeadObjectMethodOnS3Api(bucketName, objectKey)
  return ! handleErrorOnS3HeadObjectAction(bucketName, objectKey, err)
}

func executeHeadObjectMethodOnS3Api(bucketName string, objectKey string) (output *s3.HeadObjectOutput, err error){
  s3Client := getS3Client()
  return s3Client.HeadObject(context.TODO(), &s3.HeadObjectInput{
    Bucket:               aws.String(bucketName),
    Key:                  aws.String(objectKey),
  })
}

func handleErrorOnS3HeadObjectAction(bucketName, objectKey string, err error) (hit bool){
  logUnableToHeadObjectFromS3Bucket(bucketName, objectKey, err)
  return err != nil
}

func logUnableToHeadObjectFromS3Bucket(bucketName string, objectKey string, err error) {
  if err != nil {
    log.Printf("Unable to head object {%s} from S3 bucket {%s}: { %v }", objectKey, bucketName, err)
  }
}

相关问题