Skip to content

Instantly share code, notes, and snippets.

@programble programble/package.json
Last active Jul 24, 2016

Embed
What would you like to do?
Simple Upload Service
{
"name": "sus",
"version": "0.0.0",
"description": "Simple Upload Service",
"license": "ISC",
"repository": "git@gist.github.com:89cb6f5c409fd9429e0a.git",
"dependencies": {
"basic-auth": "^1.0.3",
"compression": "^1.6.0",
"express": "^4.13.3",
"hiredis": "^0.4.1",
"morgan": "^1.6.1",
"multer": "^1.1.0",
"redis": "^2.3.0"
}
}
'use strict';
let crypto = require('crypto');
let url = require('url');
let express = require('express');
let multer = require('multer');
let compression = require('compression');
let morgan = require('morgan');
let mime = require('mime');
let basic = require('basic-auth');
let redis = require('redis');
let config = {
host: process.env.HOST || '127.0.0.1',
port: process.env.PORT || 3000,
redisURL: process.env.REDIS_URL || 'redis://localhost:6379',
ttl: process.env.TTL || 604800,
username: process.env.USERNAME || 'username',
password: process.env.PASSWORD || 'password',
};
function basicAuth() {
return (req, res, next) => {
let creds = basic(req);
if (!creds || creds.name !== config.username || creds.pass !== config.password) {
res.status(401);
res.set('WWW-Authenticate', 'Basic');
res.send('Not Authorized');
} else {
next();
}
};
}
let r = redis.createClient(config.redisURL, { return_buffers: true });
let app = express();
let upload = multer();
app.use(morgan('dev'));
app.use(compression());
app.get('/', basicAuth(), (req, res) => {
let html = `
<!DOCTYPE html>
<title>Simple Upload Service</title>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file">
</form>
<script>
document.getElementsByTagName('input')[0].onchange = function() {
document.getElementsByTagName('form')[0].submit();
};
</script>
<ol>
`;
r.lrange('recent', 0, -1, (err, recent) => {
if (err) return next(err);
recent.forEach(path => html += `<li><a href="${ path }">${ path }</a></li>`);
html += '</ol>';
res.send(html);
});
});
app.post('/', basicAuth(), upload.single('file'), (req, res, next) => {
if (!req.file) return res.status(400).send('Bad Request');
let hash = crypto.createHash('sha1');
hash.update(req.file.buffer);
let sha = hash.digest('hex').slice(0, 7);
let path = `/${ sha }.${ mime.extension(req.file.mimetype) }`;
let uri = url.format({
protocol: req.protocol,
host: req.headers.host,
pathname: path,
});
let multi = r.multi()
.setex(`type:${ sha }`, config.ttl, req.file.mimetype)
.setex(`data:${ sha }`, config.ttl, req.file.buffer)
.lpush('recent', path)
.ltrim('recent', 0, 4);
multi.exec(err => {
if (err) return next(err);
res.redirect(uri);
});
});
app.get('/:sha.:ext?/:any?', (req, res, next) => {
r.mget([`type:${ req.params.sha }`, `data:${ req.params.sha }`], (err, replies) => {
if (err) return next(err);
if (!replies[0]) return res.status(404).send('Not Found');
res
.type(replies[0].toString())
.set('Cache-Control', `max-age=${ config.ttl }`)
.send(replies[1]);
});
});
let server = app.listen(config.port, config.host, () =>
console.log('server started on port', server.address().port)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.