Skip to content

Instantly share code, notes, and snippets.

@sebastianhoitz
Last active December 26, 2022 07:06
Show Gist options
  • Save sebastianhoitz/4554903 to your computer and use it in GitHub Desktop.
Save sebastianhoitz/4554903 to your computer and use it in GitHub Desktop.
node.JS streaming zip file
streamingResponse = require "streamingResponse"
async = require "async"
handler = (req, res) ->
files = [
{ source: "/opt/app/foo.jpg", destination: "folderA/foo.jpg" }
{ source: "/opt/app/bar.jpg", destination: "folderB/bar.jpg" }
]
streaming = new streamingResponse
filename: "my_download.zip"
files: files
streaming.pipe res, (err) =>
console.err err if err
console.log "Finished!"
res.end()
zipstream = require "zipstream"
fs = require "fs"
async = require "async"
class StreamingResponse
filename: ""
files: []
streaming: true
###
Takes an options parameter like this:
options =
filename: "download.zip"
files: [
{
source: "/var/www/file.jpg"
destination: "/event/file.jpg"
}
]
###
constructor: (options) ->
@filename = options.filename || "download.zip"
@files = options.files
# Sets the headers for the response
setHeaders: (stream) ->
stream.contentType "zip"
stream.setHeader "Content-Disposition", "attachment; filename=#{@filename}"
# Adds a file to the zip file
# Private.
_addFile: (file, cb) =>
# Check if the response stream ended
unless @streaming
console.log "Stopped streaming"
@zip.destroy()
return cb "Stopped streaming"
readStream = fs.createReadStream file.source
@zip.addFile readStream, {name: file.destination}, cb
addFilesToZip: (files, callback) =>
async.forEachSeries files, @_addFile, (err) =>
if err
console.error err
return callback err
unless err
@zip.finalize callback
pipe: (stream, callback) ->
@setHeaders stream
stream.on "close", =>
@streaming = false
@zip = zipstream.createZip level: 0
@zip.pipe stream
@addFilesToZip @files, callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment