Вот пример того, как передать файл с URL-адреса HTTP в S3. Он использует обещания / async / await, а не обратные вызовы, и он обходится без пакета Jimp, о котором я мало знаю, в пользу более традиционного fetch
API:
Примечание: если вы явно не предоставляетеcontent-type при загрузке на S3, тогда он будет установлен на application/octet-stream
, что будет проблематично, когда клиенты загружают объект. Поэтому этот код сначала определяет тип содержимого файла и устанавливает его при потоковой передаче на S3.
const AWS = require('aws-sdk');
const fetch = require('node-fetch');
const stream = require('stream');
const s3 = new AWS.S3();
const uploadStream = ({ Bucket, Key, ContentType }) => {
const pass = new stream.PassThrough();
return {
writeStream: pass,
promise: s3.upload({ Bucket, Key, ContentType, Body: pass }).promise(),
};
}
const uploadFetch = async ({ url, Bucket, Key, ContentType }) => {
const response = await fetch(url);
const { writeStream, promise } = uploadStream({Bucket, Key, ContentType});
response.body.pipe(writeStream);
return promise;
}
exports.handler = async (_event, _context) => {
const source_jpeg = {
Key: 'audi.jpeg',
Bucket: 'mybucket',
url: 'https://upload.wikimedia.org/wikipedia/commons/0/08/Audi_A3_2015.jpeg',
};
// HEAD the source image to get content type
const rc_head = await fetch(source_jpeg.url, {method: 'HEAD'});
const content_type = rc_head.headers.get('content-type');
console.log('head:', rc_head.status, rc_head.statusText, content_type);
try {
// GET the source image and stream it to S3
const parms = {...source_jpeg, ContentType: content_type};
const rc_upload = await uploadFetch(parms);
console.log('get/upload jpeg:', rc_upload);
} catch(e) {
console.log(e);
}
};
Кроме того, убедитесь, что ваша функция Lambda настроена с разумным тайм-аутом (тайм-аут по умолчанию равен 3 секундам). ).