Transferring from Windows to Linux in node js with smbget

1.1k views Asked by At

How do you retrieve a file if your node express web service is on a linux server (ubuntu) and you need to download files from a windows server?

2 Valid Options:

How can you do this from the operating system directly instead of relying on third-party node packages?

1

There are 1 answers

0
astanley86 On

You can use smbget (linux utility included with https://linux.die.net/man/1/smbget ) and then just use node child_process spawn to call the function.

Just replace [workgroup], [username], [password], [serveraddress], and [path] with your own information here.

 function getFile(file) {
  return new Promise(function(resolve, reject) {
    var tempFilePath = `/tmp/${file}`; // the linux machine
    var remoteFile = require('child_process').spawn('smbget', ['--outputfile', tempFilePath, '--workgroup=[workgroup]', '-u', '[username]', '-p', '[password]', `smb://[serveraddress]/c$/[path]/[path]/${file}`]);
     remoteFile.stdout.on('data', function(chunk) {
    //     //handle chunk of data
     });
    remoteFile.on('exit', function() {
      //file loaded completely, continue doing stuff

      // TODO: make sure the file exists on local drive before resolving.. an error should be returned if the file does not exist on WINDOWS machine 
       resolve(tempFilePath);
    });
    remoteFile.on('error', function(err) {
      reject(err);
    })
  })
}

The code snippet above returns a promise. So in node you could send the response to a route like this:

 var express = require('express'),
 router = express.Router(),
 retrieveFile = require('../[filename-where-above-function-is]');

router.route('/download/:file').get(function(req, res) {
    retrieveFile.getFile(req.params.file).then(
        file => {
          res.status(200);
          res.download(file, function(err) {
            if (err) {
              // handle error, but keep in mind the response may be partially sent
              // so check res.headersSent
            } else {
              // remove the temp file from this server
              fs.unlinkSync(file); // this delete the file!
            }
          });
        })
      .catch(err => {
        console.log(err);
        res.status(500).json(err);
      })
  }

The response will be the actual binary for the file to download. Since this file was retrieved from a remote server, we also need to make sure we delete the local file using fs.unlinkSync().

Use res.download to send the proper headers with the response so that most modern web browsers will know to prompt the user to download the file.