Поток, похоже, имеет только 1 фрагмент при использовании parse: false в Hapi multipart / form-data

#node.js #parsing #stream #multipartform-data #hapi

#node.js #синтаксический анализ #поток #multipartform-данные #hapi

Вопрос:

У меня есть конечная точка, которая получает поток:

     server.route({
    method: 'PUT',
    path: `${FILES_PREFIX}`,
    handler: Handlers.createFile,
    options: {
        description: 'Create file.',
        tags: ['api', 'file'],
        payload: {
            timeout: false,
            maxBytes: 10 * GB,
            output: 'stream',
            multipart: true,
            parse: false,
            allow: 'multipart/form-data',
        }
    }
});
 

Если я установлю parse: true, я получу свой буфер, как и ожидалось, и смогу прочитать его в payload.data. Однако, поскольку мои файлы слишком большие, мне нужно проанализировать их самостоятельно (в противном случае я получаю: RangeError [ERR_OUT_OF_RANGE]: значение «длина» находится вне диапазона. Оно должно быть>= 0 amp;amp; <= 2147483647. Получено 2877227008)

Итак, решение, которое я пытаюсь, — установить parse: false и самостоятельно проанализировать поток. Однако, когда я смотрю на свою полезную нагрузку, я вижу, что у меня есть readableBuffer(), который возвращает мне список буферов… но список буферов содержит только 1 элемент размером 64 КБ. Значение first element .next равно null . Я просто остался там, спрашивая, где остальные мои данные.

Я также попытался просмотреть request.raw.req, поскольку синтаксический анализ false, у меня все равно не должно быть всех данных в буфере… но в основном это одна и та же информация в request.raw.req и request.payload. У меня также есть readableBuffer размером 64 КБ по запросу.raw.req().readableBuffer()

Ответ №1:

Анализатор по умолчанию определенно не подходит для передач такого размера, поскольку он буферизует все входящие данные в память.

Вы на правильном пути, но вы не используете stream API по назначению. readableBuffer() Метод возвращает только то, что в данный момент буферизовано. Чтобы получить больше данных и правильно их использовать, вам нужно будет использовать соответствующий stream API:

  1. Использование 'data amp; 'end' событий.
  2. Использование stream.read() с 'readable' событием.
  3. Просто stream.pipe() в другой поток.

Для всего этого вам нужно будет зарегистрироваться и 'error' соответствующим образом обработать событие.

Наиболее современным подходом является использование помощника Stream.pipeline().

Наконец, поток может быть не лучшим решением. Hapi также поддерживает 'file' режим вывода, который будет передавать входные данные непосредственно в файл на диске.