Почему мой сервер Hapi не будет обслуживать статические файлы с динамическими именами файлов?

#javascript #node.js #hapijs

Вопрос:

В настоящее время я добавляю новые функции в довольно большой проект, который работает уже пару лет. В проекте используется база данных Couch DB, Hapijs в бэкэнде и React во внешнем интерфейсе.

Моя цель-добавить кнопку загрузки, которая позволит пользователю (администратору) загружать все файлы .pdf из базы данных, отсортированных по годам и упакованных в zip-архив . На сервере уже есть маршрут для аналогичных задач, поэтому я расширяю функциональность этого маршрута вместо того, чтобы создавать новый с нуля.

/generate/{query} Маршрут обрабатывает весь экспорт файлов в зависимости от параметров в строке запроса. Параметры запроса всегда будут содержать год. Маршрут начинается так:

  server.route({
    method: 'GET',
    path: '/generate/{query*}',

    handler: async function(request, h) {
      ...
      }
     }) 

Этот маршрут запускает длинную серию асинхронных процессов и в конце успешно сохраняет все файлы .pdf в папке tmp, отсортированной по годам и упакованной в zip-файлы . Единственное, что осталось сделать, это отправить zip-файл в качестве ответа обратно на интерфейс, где запускается загрузка.

Вот тут-то у меня и возникают проблемы:

Я использую пакет inert для добавления файлов в свой ответ с помощью этого file() метода. Если я передам путь в виде жестко закодированной строки (например file('/tmp/2019.zip') ), данные отправляются на интерфейс правильно, и загрузка начинается так, как должна. Однако, если я попытаюсь динамически создать одну и ту же строку, я получу поврежденный zip — файл размером всего 1 МБ-3 МБ (исходный файл 250 МБ) (когда-то он составлял 80 МБ, один раз 150 МБ, но оба файла были повреждены и не могли быть распакованы). Я попробовал несколько разных подходов, чтобы получить динамический путь к файлу (шаблонные литералы и т. Д.), Но все они дали один и тот же результат. Это то, с чем я сейчас застрял:

             const response = h.file(Path.join(__dirname   '/tmp/'   request.query.year   '.zip'), {
              mode: 'attachment',
          })
             return response 

Затем я создал следующий тестовый маршрут:

   server.route({
    method: 'GET',
    path: '/test/{query*}',
      handler: function(req, res) {
        return res.file(Path.join(__dirname   '/tmp/'   req.query.year   '.zip'), {
          mode: 'attachment'
      })
      }
  }) 

…и это работает как заклинание, независимо от того, какой год я передаю в качестве параметра запроса.

Это затрудняет точное определение части моего кода, которая вызывает проблемы: в моем тестовом маршруте нет проблем с динамически генерируемыми путями к файлам, так что это не может быть так. Код в фактическом маршруте также выполняется правильно, но только в том случае, если путь к файлу жестко закодирован, поэтому он, очевидно, не полностью нарушен. В целях тестирования в настоящее время я не удаляю файлы из папки tmp, поэтому это не может быть проблемой с моими асинхронными функциями (поврежденные zip-файлы разного размера заставили меня задуматься, может ли это иметь какое-то отношение к моей проблеме). Но… что еще это могло быть? Почему я не могу передавать динамические имена файлов по основному маршруту?

Has anybody here ever encountered anything like this? Let me know if you need more details. Any help is appreciated, even the slightest hunch could be of help!