Reputation: 75
I try get the pre-signed URL to an Amazon S3 object using the Aws\S3\S3Client::createPresignedRequest() method:
$s3 = new S3Client($config);
$command = $s3->getCommand('GetObject', array(
'Bucket' => $bucket,
'Key' => $key,
'ResponseContentDisposition'=>'attachment; filename="' . $fileName . '"',
));
$request = $s3->createPresignedRequest($command, $time);
// Get the actual presigned-url
$this->signedUrl = (string)$request->getUri();
I get presigned-url like this:
https://s3.amazonaws.com/img/1c9a149e-57bc-11e5-9347-58743fdfa18a?X-Amz-Content-Sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=13JZVPMFV04D8A3AQPG2%2F20150910%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20150910T181455Z&X-Amz-SignedHeaders=Host&X-Amz-Expires=1200&X-Amz-Signature=0d99ae98ea13e2974322575f95f5a19e94e13dc859b2509cecc21cd41c01c65d
and this url returned error:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
....
Upvotes: 2
Views: 4279
Reputation: 1084
Above error indicates the Key doesn't exist or file you are trying to generating presignedUrl doesn't exist. You can generate presignedURL even if object or key is not present.
I have faced multiple issues, similar like one above but i solved it by using await function in my code to wait until the s3 key is uploaded.
In my scenario, I was using Lambda to upload the file in S3 and generate presignedUrl and send to the client
Lambda Code:
const AWS = require('aws-sdk');
function uploadAndGeneratePreSignedUrlHandler () {
const s3 = new AWS.S3();
const basicS3ParamList = {
Bucket: "Bucket_NAME",
Key: "FILE_NAME", // PATH or FileName
};
const uploadS3ParamList = {
...basicS3ParamList,
Body: "DATA" // Buffer data or file
}
try {
await s3.upload(uploadS3ParamList).promise();
const presignedURL = s3.getSignedUrl('getObject', basicS3ParamList);
return presignedURL;
} catch (error) {
console.log('error')
}
}
Client side : I created pop-up for download
// React
const popUpEventForDownload = (testParams) => {
try {
const fetchResponse = await axios({ method: 'GET', url: 'GATEWAY_URL', data: testParams });
const { presignedURL } = fetchResponse.data;
downloadCSVFile(presignedURL, 'test')
} catch(error) {
console.log('error');
}
}
downloadCSVFile = (sUrl, fileName) => {
//If in Chrome or Safari or Firefox - download via virtual link click
//Creating new link node.
var link = document.createElement('a');
link.href = sUrl;
if (link.download !== undefined) {
//Set HTML5 download attribute. This will prevent file from opening if supported.
link.download = `${fileName}.CSV`;
}
//Dispatching click event.
if (document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent('click', true, true);
link.dispatchEvent(e);
return true;
}
// Force file download (whether supported by server).
var query = '?download';
window.open(sUrl + query);
}
Upvotes: 0
Reputation: 178956
Generating a pre-signed URL is done entirely on the client side with no interaction with the S3 service APIs. As such, there is no validation that the object actually exists, at the time a pre-signed URL is created. (A pre-signed URL can technically even be created before the object is uploaded).
The NoSuchKey
error means exactly that -- there is no such object with the specified key in the bucket, where key, in S3 parlance, refers to the path+filename (the URI) of the object. (It's referred to as a key as in the term key/value store -- which S3 is -- the path to the object is the "key," and the object body/payload is the "value.")
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html
Upvotes: 4