Загрузка потокового файла на s3 через экспресс-сервер

У меня есть экспресс-конечная точка, где я в настоящее время обрабатываю загрузку файлов. Большие файлы занимают много памяти, потому что я использовал bodyParser, который буферизует весь файл в памяти перед вызовом моей функции обработчика.

Я удалил промежуточное ПО bodyParser из этой конечной точки и пытаюсь правильно использовать потоки, чтобы в основном передавать загрузку файла -> экспресс -> s3.

Это документы по методу s3, и он принимает буфер или поток.

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property

маршрут

router.put('/files/:filename', putHandler({ s3Client: s3Client }))

Я попробовал это, которое передает файл в мой метод обработчика, но, похоже, он не передает его в метод s3.upload (на самом деле неудивительно)

function put ({ s3Client }) {
  return (req, res) => {
        ...
        let whenFileUploaded = new Promise((resolve, reject) => {
          // const { Readable } = require('stream')
          // const inStream = new Readable({
            // read() {}
          // })

          let data = ''
          req.on('data', function (chunk) {
            req.log.debug('in chunk')
            data += chunk
            // inStream.push(chunk)
          })
          req.on('end', function () {
            req.log.debug('in end')
          })

          s3Client.upload(
            {
              Key: filepath,
              Body: data,
              SSECustomerAlgorithm: 'AES256',
              SSECustomerKey: sseKey.id.split('-').join('')
            },
            {
              partSize: 16 * 1024 * 1024, // 16mb
              queuSize: 1
            },
            (err, data) => err ? reject(err) : resolve(data)
          )
        })

Я предполагаю, что мне нужно создать поток и подключить req.on('data... к моему потоку, а затем установить Body: inStream, что, как вы можете видеть, я пытался сделать с закомментированным материалом, но это тоже не сработало.

Помощь?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
1 219
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оказывается, ответ на самом деле очень прост. Все, что мне нужно было сделать, это передать объект req.

function put ({ s3Client }) {
  return (req, res) => {
        ...
        let whenFileUploaded = new Promise((resolve, reject) => {
          s3Client.upload(
            {
              Key: filepath,
              Body: req, // <-- NOTE THIS LINE
              SSECustomerAlgorithm: 'AES256',
              SSECustomerKey: sseKey.id.split('-').join('')
            },
            {
              partSize: 16 * 1024 * 1024, // 16mb
              queuSize: 1
            },
            (err, data) => err ? reject(err) : resolve(data)
          )
        })

Я выяснил это следующим образом: я посмотрел исходный код экспресса, что такое объект req, и увидел, что это объект http.IncomingMessage - https://github.com/expressjs/express/blob/master/lib/request.js#L31

Затем я посмотрел документы Node и увидел, что http.IncomingMessage реализует интерфейс Readable Stream.

It implements the Readable Stream interface, as well as the following additional events, methods, and properties.

https://nodejs.org/docs/latest-v9.x/api/http.html#http_class_http_incomingmessage

Другие вопросы по теме