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

R.S*_*aby 0 file amazon-s3 go aws-lambda

我正在为我的项目开发一项服务,该服务用于在 AWS 中同步 Lambdas 工作。这个想法是编写一个 TrackerFile 模块,将在 S3 上存储结构。每次我使用跟踪器时,我都会检查是否有分配给被调用跟踪器名称的文件。

我不知道如何安全地检查 S3 上是否存在具有给定名称的文件。如果文件存在,你能展示一段能够返回 (bool, err) 的示例代码,其中 bool 为 True 吗?

Elv*_*vis 13

如果您使用适用于 Go V2 的 AWS 开发工具包:

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
}
Run Code Online (Sandbox Code Playgroud)

处理适用于 Go V2 的 AWS 开发工具包中的错误


Ioa*_*kos 5

确保您拥有以下权限:“s3:GetObject”、“s3:ListBucket”、

关于安全,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
    }
Run Code Online (Sandbox Code Playgroud)


小智 1

为了确保 AWS SDK v3 和 AWS SDK v2 之间的兼容性,我建议同时使用 404 和“NotFound”代码。

export async function fileExistsInS3(bucket, key) {
    try {
        await s3.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
        return { fileExists: true };
    } catch (error) {
        if (error.code === 'NotFound' || (error['$fault'] === 'client' && error['$metadata']?.httpStatusCode === 404)) {
            return { fileExists: false };
        }
        throw error; 
    }
}
Run Code Online (Sandbox Code Playgroud)