I\'d like to upload a file to AWS S3 via the POST interface, but I fail to do so.
I\'ve already made it work with PUT and getSignedUrl, but unfortunatel
Finally it works. Here's the code in case anyone has the same problem.
A few things to note:
acl latel, it will fail.signatureVersion to V4 even in the S3 constructor.I'm not proud of the code quality, but at last it works.
const aws = require('aws-sdk');
const fs = require('fs');
const request = require('request');
const config = require('./config');
let s3;
const init = () => {
aws.config.update({
signatureVersion: 'v4',
region: 'eu-central-1',
accessKeyId: config.aws.keyId,
secretAccessKey: config.aws.keySecret
});
s3 = new aws.S3({signatureVersion: 'v4'});
};
const signFile = (filePath) => {
return new Promise((resolve, reject) => {
const params = {
Bucket: config.aws.bucket,
Fields: {
key: filePath
},
Expires: config.aws.expire,
Conditions: [
['content-length-range', 0, 10000000], // 10 Mb
{'acl': 'public-read'}
]
};
s3.createPresignedPost(params, (err, data) => {
resolve(data);
});
});
};
const sendFile = (filePath, payload) => {
const fetch = require('node-fetch');
const FormData = require('form-data');
const form = new FormData();
form.append('acl', 'public-read');
for(const field in payload.fields) {
form.append(field, payload.fields[field]);
}
form.append('file', fs.createReadStream(__dirname + `/${filePath}`));
form.getLength((err, length) => {
console.log(`Length: ${length}`);
fetch(payload.url, {
method: 'POST',
body: form,
headers: {
'Content-Type': false,
'Content-Length': length
}
})
.then((response) => {
console.log(response.ok);
console.log(response.status);
console.log(response.statusText);
return response.text();
})
.then((payload) => {
console.log(payload);
console.log(form.getHeaders());
})
.catch((err) => console.log(`Error: ${err}`));
});
};
init();
const file = 'test.pdf';
const filePath = `files/new/${file}`;
signFile(filePath)
.then((payload) => { sendFile(file, payload); });