Trying to add metadata to my presigned url. The url generates and has the metadata included in the query string, but I am not able to submit my file with the metadata as it fails with 403 forbidden. It should be noted that the url works fine if I remove the metadata from the setup. I have tried signing headers, unhoisting headers and nothing works. I know this is possible with presigned POST, but I need it to work for PUT.
Lambda code to generate URL:
const params={
Bucket: bucket,
Key: key,
Metadata:{
"filesize": filesInfo.fileSize,
"origfilename": encodeURIComponent(filesInfo.origFilename),
"filetype": filesInfo.fileType,
},
};
console.log("params=", params);
const headersToSign= new Set([
// "ContentLength",
"x-amz-meta-fileSize",
"x-amz-meta-fileType",
"x-amz-meta-origFilename",
]);
const unhoistableHeaders=new Set ([
"x-amz-meta-fileSize", "x-amz-meta-fileType", "x-amz-meta-origFilename"
]);
const command=new PutObjectCommand(params);
const url = await getSignedUrl(s3Client, command, {
expiresIn: expiry,
signedHeaders: headersToSign,
unhoistableHeaders: unhoistableHeaders
});
Client fetch:
const encodedFileName = encodeURIComponent(fileToSubmit.name);//did this to ensure filenames work--need to decode when showing file
const myHeaders = new Headers({
"x-amz-meta-filesize": fileToSubmit.size,
"x-amz-meta-filetype": fileToSubmit.type,
"x-amz-meta-origfilename": encodedFileName,
});
const myRequest = new Request(url, {
method: 'PUT',
mode: 'cors',
cache: 'default',
body: fileToSubmit,
headers: myHeaders
});
fetch(myRequest)
.then(response => {
})
.then(data => {
})
Well that was silly. It works now. I just hadn't ensured that my metadata values were all strings. The filesize metadata was a number and once I converted it to a string in the lambda and added that value to the metadata all was well.