Created
July 15, 2015 00:03
-
-
Save kirsle/b3f8f28e1606cda7077c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# Problem: sending a binary download in ExpressJS. | |
# | |
# I was trying to proxy download a binary file from S3 and serve it to the user with a different name. | |
# Using the `request` module didn't work; text files came back fine but binary files would be corrupted | |
# in strange ways (see attached diff). | |
# | |
# I ended up using the built-in `https` module and doing it the hard way. | |
# | |
# My theory: the request module expects to only work with text and was performing some UTF-8 coercion | |
# of the binary data. | |
## | |
https = require('https') | |
urllib = require('url') | |
download = (req, res) -> | |
s3url = "https://something-s3.amazonaws.com/file/sdsdf09sd7f90s8d7f.gif" | |
origName = "filename.gif" | |
# Proxy the download to the user, but give it the new name. | |
https.get urllib.parse(s3url), (response) -> | |
# The response is given to us one chunk at a time, in Buffer objects. | |
data = [] | |
response.on("data", (chunk) -> | |
data.push chunk | |
).on("end", -> | |
# data is an array of Buffers, so we take each octet of each buffer | |
# and combine them into one big octet array to pass to a new Buffer | |
# instance for sending to the browser. | |
# See: http://chad.pantherdev.com/node-js-binary-http-streams/ | |
buffer = new Buffer(data.reduce (prev, current) -> | |
return prev.concat(Array.prototype.slice.call(current)) | |
, []) | |
res.setHeader "Content-Disposition", "attachment; filename=#{origName}" | |
res.setHeader "Content-Type", "application/octet-stream" | |
res.end buffer, 'binary' | |
) | |
## | |
# The following DID NOT WORK. It would corrupt the binary files, see | |
# the attached diff. Un-commented out for syntax highlighting. | |
## | |
# Proxy the download to the user, but give it the new name. | |
request s3url, (error, response, body) -> | |
if !error and response.statusCode is 200 | |
res.setHeader "Content-Disposition", "attachment; filename=#{origName}" | |
res.setHeader "Content-Type", response.headers["content-type"] | |
#res.send(new Buffer(body, 'binary')) # this does the same as res.end below | |
res.end body, 'binary' | |
else | |
res.send 500, message: "Failed to download file." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-00000000 47 49 46 38 39 61 10 00 10 00 c2 00 00 00 00 00 |GIF89a..........| | |
+00000000 47 49 46 38 39 61 10 00 10 00 fd 00 00 00 00 00 |GIF89a..........| | |
-00000010 00 98 fd 88 88 88 ff ff ff 00 ba 00 44 44 44 22 |............DDD"| | |
+00000010 00 fd fd fd fd fd fd fd fd 00 fd 00 44 44 44 22 |............DDD"| | |
-00000020 22 22 00 00 00 21 f9 04 01 00 00 03 00 2c 00 00 |""...!.......,..| | |
+00000020 22 22 00 00 00 21 fd 04 01 00 00 03 00 2c 00 00 |""...!.......,..| | |
-00000030 00 00 10 00 10 00 00 03 35 38 ba dc fe 70 80 39 |........58...p.9| | |
+00000030 00 00 10 00 10 00 00 03 35 38 fd fd fd 70 fd 39 |........58...p.9| | |
-00000040 a3 34 25 1b e0 a8 ff 9c 02 08 64 69 0a a1 64 52 |.4%.......di..dR| | |
+00000040 fd 34 25 1b fd fd fd fd 02 08 64 69 0a fd 64 52 |.4%.......di..dR| | |
-00000050 eb 32 92 5c 10 bc a8 5b 02 f2 7c db 30 e1 d3 29 |.2.\...[..|.0..)| | |
+00000050 fd 32 fd 5c 10 fd fd 5b 02 fd 7c fd 30 fd fd 29 |.2.\...[..|.0..)| | |
-00000060 1a 6a d2 12 9d 8e 41 10 c8 c2 6c 3a 19 09 00 3b |.j....A...l:...;| | |
+00000060 1a 6a fd 12 fd fd 41 10 fd fd 6c 3a 19 09 00 3b |.j....A...l:...;| |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment