Last active
May 4, 2017 22:40
-
-
Save askldjd/ca98b949729fce5d9cc251b3d91a7d8e to your computer and use it in GitHub Desktop.
Node.js S3 Streamer for Efolder Express
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
// This Express server is designed to support Efolder-Express Rails server to | |
// allow streaming data from S3 without first saving a local copy on disk. | |
const express = require('express') | |
const app = express() | |
const AWS = require('aws-sdk'); | |
AWS | |
.config | |
.update({region: 'us-gov-west-1'}); | |
const s3 = new AWS.S3(); | |
app.use(require('cookie-parser')()); | |
const sessionDecoder = require('rails-session-decoder'); | |
// Use the shared SECRET_KEY_BASE from the env file to setup the Rails session | |
// decoder. | |
const decoder = sessionDecoder(process.env.SECRET_KEY_BASE); | |
const sessionCookieName = '_caseflow_session'; | |
// Setup a middleware to decode the Rails session cookie. Whenever "_caseflow_session" | |
// is present, it will be decoded. | |
app.use(function (req, res, next) { | |
if (req.cookies && req.cookies[sessionCookieName]) { | |
decoder | |
.decodeCookie(req.cookies[sessionCookieName], function (err, sessionData) { | |
req.cookies[sessionCookieName] = JSON.parse(sessionData); | |
next(err); | |
}); | |
} else { | |
next(); | |
} | |
}); | |
// stream-download re-check user's authority from its session, and pipe | |
// the request directly to S3 if the user is authorized for this download. | |
app.get('/stream-download/:filename', function (req, res) { | |
const session = req.cookies[sessionCookieName]; | |
if (!session || !session.user || !session.user.roles || session.user.roles.indexOf('Download efolder') != -1) { | |
return res | |
.status(403) | |
.send('not authorized'); | |
} | |
s3 | |
.getObject({Bucket: process.env.AWS_BUCKET_NAME, Key: req.params.filename }) | |
.on('httpHeaders', function (statusCode, headers) { | |
res.set('Content-Length', headers['content-length']); | |
res.set('Content-Type', headers['content-type']); | |
this | |
.response | |
.httpResponse | |
.createUnbufferedStream() | |
.pipe(res); | |
}) | |
.send(); | |
}) | |
// Nginx is expected to proxy /stream-download to port 3002. | |
app.listen(3002, function () { | |
console.log('listening on 3002') | |
}) |
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
# Nginx config changes to re-route /stream-download/ path to Node.js | |
# streaming server | |
# streamer is on 3002, but this is arbitrary | |
upstream streamer_app { | |
server 127.0.0.1:3002; | |
} | |
# Any URL with /assets should be served by Nginx. | |
location ^~ /stream-download/ { | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
proxy_set_header Host $http_host; | |
proxy_redirect off; | |
# Disable disk cache to allow large files to be downloaded. | |
# See https://serverfault.com/questions/820597/nginx-does-not-serve-large-files | |
proxy_max_temp_file_size 0; | |
proxy_pass http://streamer_app; | |
} |
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
{ | |
"name": "node-proxy-s3", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"aws-sdk": "^2.48.0", | |
"cookie-parser": "^1.4.3", | |
"express": "^4.15.2", | |
"rails-cookie-parser": "0.0.3", | |
"rails-session-decoder": "^1.0.4" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment