1

Here is my code, It will stream properly but when try to download it return error of Requires Range header.

app.get('/download-file', (req, res) => {
  const filePath = req.query.file;

  if (!filePath) {
    res.status(400).send('File path is required');
    return;
  }
  const fullPath = path.resolve(filePath);
  fs.stat(fullPath, (err, stats) => {
    if (err) {
      res.status(404).send('File not found');
      return;
    }
    const fileSize = stats.size;
    const rangeHeader = req.headers.range;
    console.log(rangeHeader)

    if (!rangeHeader) {
      res.status(400).send('Requires Range header');
      return;
    }
    const ranges = rangeParser(fileSize, rangeHeader);
    if (ranges === -1) {
      res.status(416).send('Range not satisfiable');
      return;
    }
    if (ranges === -2 || !ranges.length) {
      res.status(400).send('Malformed Range header');
      return;
    }
    const range = ranges[0];
    const { start, end } = range;
    res.status(206);
    res.setHeader('Content-Range', `bytes ${start}-${end}/${fileSize}`);
    res.setHeader('Accept-Ranges', 'bytes');
    res.setHeader('Content-Length', end - start + 1);
    res.setHeader('Content-Type', 'application/octet-stream');
    res.setHeader('Content-Disposition', `attachment; filename="${path.basename(filePath)}"`);
    const stream = fs.createReadStream(fullPath, { start, end });
    stream.pipe(res);
    req.on('close', () => {
      stream.destroy();
      console.log('Request canceled by the client');
    });
  });
});

I Try do download file http://192.168.1.3:3000/download-file?file=downloads/1716537967084_out.mkv Like this But it stream properply on vlc but not download when try to download it returns error of Requires Range header.

2 Answers 2

0

The client is not required to send a range header. VLC and other streaming clients are more likely to use it for buffering purposes and to speedup playback from mid points, but other clients - such as browsers - don't send it by default (it usually is used only to resume a previously paused download). You should not expect the range header in your request; if isn't available, you have to send the whole file from first to last byte without returning any error code.

0

You can replace the check for the range header with this

   if (!rangeHeader) {
      return res.download(fullPath); // Handles the download automatically
  }

Not the answer you're looking for? Browse other questions tagged or ask your own question.