var http = require('http'),
fs = require('fs'),
path = require('path'),
bee = require('beeline'),
qs = require('querystring'),
hl = require(__dirname + '/highlight'),
tmpl = require(__dirname + '/templates'),
pasteInit = require(__dirname + '/paste');
var config = {
port: 8080,
database: __dirname + '/../db/pastes.kch'
};
var paste;
function _200(res, contentType, data) {
res.writeHead(200, {'Content-Type': contentType});
res.write(data);
res.end('\n');
}
function _302(res, url) {
res.writeHead(302, {'Location': url});
res.end();
}
function _404(res) {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('404: Not found.\n');
}
function _500(res, err) {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.write('500: Internal Server Error');
if (err) {
res.write(':\n');
res.write(JSON.stringify(err));
}
res.end('\n');
}
function parsePost(req, callback) {
var content = '';
req.on('data', function(chunk) {
content += chunk;
});
req.on('end', function() {
var post = qs.parse(content);
callback(post);
});
}
function getContentType(ext) {
contentType = {
'.css': 'text/css',
'.js': 'text/javascript',
'.png': 'image/png'
};
if (contentType[ext]) {
return contentType[ext];
}
else {
return 'unknown';
}
}
function checkPath(file, base) {
var normFile = path.normalize(file);
var normBase = path.normalize(base);
if (normFile.indexOf(normBase) === 0) {
return true;
}
else {
return false;
}
}
function serveStaticFiles(res, filepath) {
var base = path.join(__dirname, '..', 'static');
var file = path.join(base, filepath);
if (checkPath(file, base)) {
fs.lstat(file, function(err, stat) {
if (stat.isFile()) {
var ext = path.extname(file);
var contentType = getContentType(ext);
fs.readFile(file, function (err, data) {
if (err) {
_500(res, err);
}
else {
_200(res, contentType, data);
}
});
}
else {
_404(res);
}
});
}
else {
_404(res);
}
}
var router = bee.route({
"/": function(req, res) {
tmpl.renderHtml('submit-form.tmpl', {}, res);
},
"r`^/plain/([^/]+)$`": function(req, res, id) {
paste.get(id[0], function(data) {
if (data) {
_200(res, 'text/plain', data.content);
}
else {
_404(res);
}
});
},
"r`^/get/([^/]+)$`": function(req, res, id) {
paste.get(id[0], function(data) {
if (data) {
data.styles = [{name: '/static/highlight/github.css'}];
data.content = hl.highlight(data.content, data.language);
tmpl.renderHtml('paste.tmpl', data, res);
}
else {
_404(res);
}
});
},
"r`^/static/(.+)$`": function(req, res, filepath) {
serveStaticFiles(res, filepath[0]);
},
"/add": {
POST: function(req, res) {
parsePost(req, function(post) {
paste.add(post, function(err, id) {
if (err) {
_500(res, err);
}
else {
console.log('new paste: %s', id);
_302(res, '/get/' + id);
}
});
});
},
GET: function(req, res) {
_404(res);
}
},
"`404`": function(req, res) {
_404(res);
},
"`503`": function(req, res, err) {
_500(res, err);
}
});
var server = function(port) {
port = port || config.port;
pasteInit.init(config, function(func) {
paste = func;
http.createServer(router).listen(port);
console.log('Listening on port %d...', port);
});
};
if (typeof module == "object" && typeof require == "function") {
exports.server = server;
exports.config = config;
}
if (module === require.main) {
server();
}