How to send a downloaded file to client in NodeJS Express?

Viewed 634

I have an ftp server that hosts files, I want my clients to be able to download files on the ftp server by clicking a button on my front-end website . The ftp server is password protected but I as the admin know the password, the user can not know the password, so I use puppeteer, but the problem is that when the user clicks the button, it downloads in the server/back-end instead of sending it to the client. How can I pipe that to my client/user? Is puppeteer really necessary in this case?

Here is my code:

async downloadFile(req: Request, res: Response, next: NextFunction) {
        //const file_id = req.params.file_id;
        async function run() {
            const browser = await puppeteer.launch({headless: false});
            const page = await browser.newPage();
            await page.authenticate({username:"user", password:"password"});
            await page.goto('http://ftpserver/remote.php/webdav/filename.rar');
            browser.close()
            return page
        }
        res.setHeader('Content-type', 'application/x-rar-compressed');
        res.send(run());
    }

Thanks

2 Answers

I think you can catch response event of page, and get file buffer from response result object, then send the buffer to client as a file.

async downloadFile(req: Request, res: Response, next: NextFunction) {
  //const file_id = req.params.file_id;
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.authenticate({ username: "user", password: "password" });
  await page.goto('http://ftpserver/remote.php/webdav/filename.rar');

  page.on('response', async (response) => {
    if (response.url().indexOf('.rar') != -1) { // is resource what you want
      const buffer = await response.buffer(); // get response buff - file buffer
      res.setHeader('Content-Disposition', 'attachment; filename=filename.rar'); // set filename for client download process
      res.setHeader('Content-Transfer-Encoding', 'binary');
      res.setHeader('Content-Type', 'application/octet-stream');
      res.send(Buffer.from(buffer, 'binary'));
    }
    browser.close();
  });
}
import { PassThrough } from "stream";
import { ServerResponse } from "http";

function responseStream(serverResponse: ServerResponse, data)
{
    let readStream = new PassThrough();
    readStream.end(data);
    return readStream.pipe(serverResponse);
}

...
responseStream(res, await run());
...
Related