Rails скачать zip из потока двоичных данных - PullRequest
0 голосов
/ 03 мая 2018

У меня есть data-API для получения данных из файловой системы. Data-API - это сервер nodeJS. Наш веб-сервер является сервером Rails. С веб-сервера я отправляю в API параметры, какие файлы я хочу скачать. Затем API данных архивирует файлы запроса и отправляет архив обратно в виде двоичных данных.

Пока все отлично работает. Теперь перейдите к той части, где я застрял. Я хочу представить двоичные данные для загрузки в браузере. Я могу либо преобразовать двоичные данные в zip-файл и отправить их в браузер, либо найти другое умное решение, которое представит двоичные данные в виде загрузки.

Вот что у меня есть

Сторона веб-сервера Rails:

app/controllers/simulation_controller.rb

def download_multiple
  files = JSON.parse(params[:files])
  file_list = @simulation.sweep_points.find(params[:sweep_point_id]).file_list
  send_data file_list.zip(files: files), filename: 'archive.zip', type: 'application/zip', disposition: 'attachment'
end

app/models/file_list.rb

def zip
  uuid = SecureRandom.uuid
  simulation = sweep_point.simulation
  files = files[:files].join(" ")
  url = URI.parse("http://localhost:3003/files/zip/#{simulation.name}/#{uuid}");
  req = Net::HTTP::Get.new(url.to_s)
  req.add_field("files", files)
  res = Net::HTTP.start(url.host, url.port) { |http| http.request(req) }
  content = res.body
  content.force_encoding("ASCII-8BIT")
end

сторона API-интерфейса dataJS:

exports.zip_simulation_files = (req, res) => {
  const { headers, method, url } = req;
  var simulation = req.params.simulation;
  var uuid = req.params.uuid;
  var files, command;

  req.on("error", (err) => {
    console.error(err);
  });

  files = req.headers.files;
  command = "cd postprocess/bumblebee-zip " +  "run" + simulation + " " + uuid + " " + "'" + files + "'";

  execute(command, (data) => {
    res.on("error", (err) => {
      console.error(err);
    });

    const zipFilePath = "/home/samuel/test_bumblebee/.zips/run" + simulation + "-files-" + uuid + ".zip"

    var zipFile = fs.readFileSync(zipFilePath);
    var stats = fs.statSync(zipFilePath);
    res.writeHead(200, {
      'Content-Type': 'application/zip',
      'Content-Disposition': 'attachment; filename="archive.zip"',
      'Content-Length': stats.size,
      'Content-Transfer-Encoding': 'binary'
    });
    res.end(zipFile, 'binary');
  });
}

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

"PK \ x03 \ x04 \ x14 \ x00 \ x00 \ x00 \ Ь \ x00 \ xA8 \ x89 \ xDBJ \ XB1 \ XB8 \ xÀ1 \ xBF2 \ x03 \ x00 \ x00 \ xB7F \ x00 \ x006 \ x00 \ x1C \ x00runZhangD3FINAL / 13,0 В / annihilation_abs_profile_001.outUT \ t \ x00 \ x0 ....... x06 \ x00 \ x00 \ x00 \ x00 \ x05 \ x00 \ x05 \ x00l \ x02 \ x00 \ x00) \ x10 \ x00 \ x00 \ x00 \ x00"

Я искал различные решения, пытаясь превратить строку двоичных данных в zip-файл или представлять поток непосредственно браузеру, но ничего не получалось. Либо почтовый индекс не создан, либо двоичный файл не рассматривается как правильные данные.

Что было бы хорошим решением?

...