Read from Dropbox stream into Buffer

Viewed 115

I need to download a file from Dropbox into buffer on my server. Due to a security issues I can't download a file directly to a client. Therefore I send request to my server, then fetch the file from Dropbox and then forward it to the client. I managed to implement this writing Dropbox stream to a file on my server and then sending it to a client.

I need to implement this mechanism without writing Dropbox stream into file on my server. I need to create a buffer and write into it and then forward the buffer to a client.

export const downloadFileFromDropbox = async function downloadFileFromDropbox(fileName,
                                                                              folderNameOnDropbox) {

    let isSucceeded;
    const message = [];
    let downloadResult;
    let fileBuffered = "";

    // authentication
    const dropbox = dropboxV2Api.authenticate({
        token: process.env.DEV_DROPBOX_SECRET_KEY
    });

    // configuring parameters
    const params = Object.freeze({
        resource: "files/download",
        parameters: {
            path: `/${folderNameOnDropbox}/${fileName}`
        }
    });


      let dropboxPromise = new Promise(function (resolve, reject) {
            dropbox(params, function (err, result) {
                if (err) {
                    reject(err);
                } else {
                    resolve(result);
                }
        }).pipe(fs.createWriteStream(/* need to implement buffer here */));
     });

     await dropboxPromise.then(async function (resultObj) {
            isSucceeded = true;
            message.push("fileDownload_OK");
        }).catch(async function (err) {
            isSucceeded = false;
            message.push(err.message);
     });

    downloadResult = {
        isSucceeded,
        message,
        /* Buffer */
    };

    return downloadResult;

};
1 Answers

There is no way to convert a file into buffer without writing it in some location What worked for me is:

  1. write the file in a temporary folder
  2. Read it and convert into buffer
  3. send the buffer back to the client
  4. delete the file from the temporary location

here's my code :

   dropbox = dropboxV2Api.authenticate({ token: credentials.access_token });
dropbox(
  {
    resource: 'files/download',
    parameters: {
      path: `${req.query.folder}` + `/${req.query.filename}`,
    },
  },
  (err, result, response) => {
    //download completed
    if (err) {
      return res.status(500).send(err);
    } else {
      console.log('download completed');
    }
  }
).pipe(
  fs
    .createWriteStream(`./app/tmp/` + `${req.query.filename}`)
    .on('finish', () => {
      fs.readFile(
        `./app/tmp/` + `${req.query.filename}`,
        function (err, buffer) {
          if (err) {
            res.status(500).send(err);
          } else {
            fs.unlink(`./app/tmp/` + `${req.query.filename}`, (err) => {
              if (err) {
                console.error(err);
                return;
              }
              //file removed
              res.status(200).send(buffer);
            });
          }
        }
      );
    })
);

I hope this will help you even though it's a little bit late

Related