AWS signed url if the object exists using promises

2019-08-13 07:35发布

问题:

I have a code snippet for generating a signed url. The below return statement always returns empty url. Rest of the data is correctly resolved. When I debug I see that the return callback gets executed first then the resolve part of the function validSignedURL gets called.

awsHelper
        .s3vldSignedURL(s3Link)
        .then(function(signedURL) {
            data[1].url = signedURL;
            return callback(null, successResponse.getResponse(context, 'OK', data));
        });

The s3vldSignedURL maps to the function below. Here s3.headobject is promise based, used to check if a file exists in s3. I want this function to be generic, so that I can use it to generate a signed url, for any s3object.

function validSignedURL(bucket, path) {
console.log("Generating Presigned Link ... ");
const s3 = new aws.S3();

let params = {
    Bucket: bucket,
    Key: path
};

let checkObj = s3.getObject(params);
return new Promise(function(resolve, reject){
    s3.headObject(params).promise()
        .then(function (data) {
            console.log('s3 File exists' + data);
            resolve(getSignedURL(bucket, path));
        }).catch(function (err) {
        console.log('Generating Presigned Link ... Failed' + err);
        resolve('');
    });
});
}

The below function getSignedURL always returns a signed url irrespective of the object exists or not.

function getSignedURL(bucket, path) {
    console.log("Generating Presigned Link ... ");
    const s3 = new aws.S3();

    let params = {
        Bucket: bucket,
        Key: path
    };

return s3.getSignedUrl('getObject', params);
}

Also, how can I convert the function call s3.headObject(params) to a synchronous call which returns true or false?

回答1:

This is the complete function definition and calling for AWS signed url if the object exists using promises. If you are using AWS Lambda you need to add s3 permissions.

  • If there is no need to validate if the url exists then getSignedURL is the function to be used
  • If there is a need to check if the object exists then use validSignedURL it will return an empty url if not found.

Here is how I implemented it:

function getSignedURL(bucket, path) {
    console.log("Generating Presigned Link ... ");

    let params = {
        Bucket: bucket,
        Key: path
    };

    //expires in default 15 mins.
    return s3.getSignedUrl('getObject', params);
}

function validSignedURL(bucket, path) {
    console.log("Generating Presigned Link ... ");
    let params = {
        Bucket: bucket,
        Key: path
    };

    return new Promise(function(resolve, reject){
        s3.headObject(params).promise()
            .then(function (data) {
                console.log('s3 File exists' + data);
                resolve(getSignedURL(bucket, path));
            }).catch(function (err) {
            console.log('Generating Presigned Link ... Failed' + err);
            resolve('');
        });
    });
}

Calling the function and resolving the promise. I have some other fields populated before in data which is returned along with the signed url.

    validSignedURL(bucketName, s3Link + fileName).then(function(signedURL) {
        data.url = signedURL;
        return callback(null, successResponse.getResponse(context, 'OK', data));
        });