How to serve a file using iron router or meteor itself?

iron-router, meteor

Solution

On the server:

var fs = Npm.require('fs');

var fail = function(response) {
  response.statusCode = 404;
  response.end();
};

var dataFile = function() {
  // TODO write a function to translate the id into a file path
  var file = fileFromId(this.params.id);

  // Attempt to read the file size
  var stat = null;
  try {
    stat = fs.statSync(file);
  } catch (_error) {
    return fail(this.response);
  }

  // The hard-coded attachment filename
  var attachmentFilename = 'filename-for-user.zip';

  // Set the headers
  this.response.writeHead(200, {
    'Content-Type': 'application/zip',
    'Content-Disposition': 'attachment; filename=' + attachmentFilename
    'Content-Length': stat.size
  });

  // Pipe the file contents to the response
  fs.createReadStream(file).pipe(this.response);
};

Router.route('/data/:id', dataFile, {where: 'server'});

On the client:

<a href='/data/123'>download zip</a>

The nice part about this is that it will download the file as an attachment, and you can customize the filename that the user sees. The trick is writing the `fileFromId` function. I find it's easiest to store all of my dynamically generated files under `/tmp`.

This answer assumes that the files are being generated dynamically. If you want to serve static content, you can just put your files under the `public` directory. See this question for more details.

Problem

I'm trying to serve a zip file on my Meteor app but I'm stuck. After a lot of Googling it seems the best way to go is with Iron Router but I don't know how: ``` Router.map -> @route "data", where: 'server' path: '/data/:id' action: -> data = getBase64ZipData(this.params.id) this.response.writeHead 200, { 'Content-Type': 'application/zip;base64' } ??? ```

Original source

Related problems