summaryrefslogblamecommitdiffstats
path: root/lib/main.js
blob: 461f47b5d19e8528ab10536f922b1383ffd8007f (plain) (tree)
1
2
3
4
5
6
7
8
9
                           


                         
                            
                                       

                                          
 



                                             
 







                                                      




                                          


























                                                       


       































                                                    

                                            










                                                        

                  
                          
             




                  

 


























                                                                         
           
      
 


                                                       
 



                                                   
                              
                                       


                                                         
                                                


                     
          
 



                                 
 


                                 
 


                                      

   

















                                                                
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();
}